Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ coverage:
backend:
flags:
- backend
target: 80%
target: 90%
threshold: 1%
base: auto
frontend:
flags:
- frontend
target: 80%
target: 90%
threshold: 1%
base: auto
patch:
Expand Down
60 changes: 49 additions & 11 deletions .github/workflows/run-ci-cd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ jobs:
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f

- name: Build cspell image
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83
uses: docker/build-push-action@601a80b39c9405e50806ae38af30926f9d957c47
with:
cache-from: type=gha,scope=cspell
cache-to: type=gha,scope=cspell,mode=max
Expand Down Expand Up @@ -175,7 +175,7 @@ jobs:
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f

- name: Build backend test image
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83
uses: docker/build-push-action@601a80b39c9405e50806ae38af30926f9d957c47
with:
cache-from: |
type=gha
Expand Down Expand Up @@ -225,7 +225,7 @@ jobs:
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f

- name: Build frontend unit-testing image
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83
uses: docker/build-push-action@601a80b39c9405e50806ae38af30926f9d957c47
with:
cache-from: |
type=gha
Expand Down Expand Up @@ -333,7 +333,7 @@ jobs:
pg_restore -h localhost -U nest_user_e2e -d nest_db_e2e < backend/data/nest.dump

- name: Build frontend end-to-end testing image
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83
uses: docker/build-push-action@601a80b39c9405e50806ae38af30926f9d957c47
with:
cache-from: |
type=gha
Expand Down Expand Up @@ -364,7 +364,7 @@ jobs:
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f

- name: Build frontend a11y-testing image
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83
uses: docker/build-push-action@601a80b39c9405e50806ae38af30926f9d957c47
with:
cache-from: |
type=gha
Expand Down Expand Up @@ -481,7 +481,7 @@ jobs:
uses: aws-actions/amazon-ecr-login@062b18b96a7aff071d4dc91bc00c4c1a7945b076

- name: Build backend image
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83
uses: docker/build-push-action@601a80b39c9405e50806ae38af30926f9d957c47
with:
build-args: |
OWASP_GID=1001
Expand Down Expand Up @@ -538,7 +538,7 @@ jobs:
echo "human_readable=$DISPLAY_SIZE" >> $GITHUB_OUTPUT

- name: Build frontend image
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83
uses: docker/build-push-action@601a80b39c9405e50806ae38af30926f9d957c47
with:
cache-from: |
type=gha
Expand Down Expand Up @@ -579,8 +579,11 @@ jobs:
name: Scan Staging Images
needs:
- build-staging-images
- set-release-version
env:
RELEASE_VERSION: ${{ needs.set-release-version.outputs.release_version }}
permissions:
contents: read
contents: write
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Unnecessary permission escalation: scan-staging-images uses actions/upload-artifact which doesn't require contents: write. Unlike the production scan job (which uses gh release upload), this job should keep contents: read to follow the principle of least privilege.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/run-ci-cd.yaml, line 586:

<comment>Unnecessary permission escalation: `scan-staging-images` uses `actions/upload-artifact` which doesn't require `contents: write`. Unlike the production scan job (which uses `gh release upload`), this job should keep `contents: read` to follow the principle of least privilege.</comment>

<file context>
@@ -579,8 +579,11 @@ jobs:
+      RELEASE_VERSION: ${{ needs.set-release-version.outputs.release_version }}
     permissions:
-      contents: read
+      contents: write
     runs-on: ubuntu-latest
     steps:
</file context>
Suggested change
contents: write
contents: read

runs-on: ubuntu-latest
steps:
- name: Check out repository
Expand All @@ -597,6 +600,22 @@ jobs:
run: |
make security-scan-backend-image BACKEND_IMAGE_NAME=owasp/nest:backend-staging
make security-scan-frontend-image FRONTEND_IMAGE_NAME=owasp/nest:frontend-staging

- name: Generate SBOM for backend image
run: |
make sbom-backend-image BACKEND_IMAGE_NAME=owasp/nest:backend-staging

- name: Generate SBOM for frontend image
run: |
make sbom-frontend-image FRONTEND_IMAGE_NAME=owasp/nest:frontend-staging

- name: Upload SBOMs
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f
with:
name: staging-sbom-${{ env.RELEASE_VERSION }}
path: |
backend-sbom-${{ env.RELEASE_VERSION }}.cdx.json
frontend-sbom-${{ env.RELEASE_VERSION }}.cdx.json
timeout-minutes: 5

plan-staging-nest:
Expand Down Expand Up @@ -966,7 +985,7 @@ jobs:
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Build backend image
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83
uses: docker/build-push-action@601a80b39c9405e50806ae38af30926f9d957c47
with:
build-args: |
OWASP_GID=1002
Expand Down Expand Up @@ -1019,7 +1038,7 @@ jobs:
EOF

- name: Build frontend image
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83
uses: docker/build-push-action@601a80b39c9405e50806ae38af30926f9d957c47
with:
cache-from: |
type=gha
Expand Down Expand Up @@ -1056,8 +1075,11 @@ jobs:
name: Scan Production Images
needs:
- build-production-images
- set-release-version
env:
RELEASE_VERSION: ${{ needs.set-release-version.outputs.release_version }}
permissions:
contents: read
contents: write
runs-on: ubuntu-latest
steps:
- name: Check out repository
Expand All @@ -1074,6 +1096,22 @@ jobs:
run: |
make security-scan-backend-image BACKEND_IMAGE_NAME=owasp/nest:backend-production
make security-scan-frontend-image FRONTEND_IMAGE_NAME=owasp/nest:frontend-production

- name: Generate SBOM for backend image
run: |
make sbom-backend-image BACKEND_IMAGE_NAME=owasp/nest:backend-production

- name: Generate SBOM for frontend image
run: |
make sbom-frontend-image FRONTEND_IMAGE_NAME=owasp/nest:frontend-production

- name: Upload SBOMs
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release upload "${{ github.event.release.tag_name }}" \
backend-sbom-${{ env.RELEASE_VERSION }}.cdx.json \
frontend-sbom-${{ env.RELEASE_VERSION }}.cdx.json
timeout-minutes: 5

deploy-production-nest:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/run-fuzz-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ jobs:
echo "Data loading completed."

- name: Build Fuzz-testing image
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83
uses: docker/build-push-action@601a80b39c9405e50806ae38af30926f9d957c47
with:
cache-from: |
type=gha
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/update-nest-test-images.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Update backend test image
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83
uses: docker/build-push-action@601a80b39c9405e50806ae38af30926f9d957c47
with:
cache-from: |
type=gha
Expand All @@ -46,7 +46,7 @@ jobs:
tags: owasp/nest:test-backend-latest

- name: Update frontend unit test image
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83
uses: docker/build-push-action@601a80b39c9405e50806ae38af30926f9d957c47
with:
cache-from: |
type=gha
Expand All @@ -61,7 +61,7 @@ jobs:
tags: owasp/nest:test-frontend-unit-latest

- name: Update frontend end-to-end test image
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83
uses: docker/build-push-action@601a80b39c9405e50806ae38af30926f9d957c47
with:
cache-from: |
type=gha
Expand All @@ -76,7 +76,7 @@ jobs:
tags: owasp/nest:test-frontend-e2e-latest

- name: Build and push fuzz-test-backend image
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83
uses: docker/build-push-action@601a80b39c9405e50806ae38af30926f9d957c47
with:
cache-from: type=registry,ref=owasp/nest:test-fuzz-backend-cache
cache-to: |
Expand Down
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ backend/fuzzing_results/
*.tfvars
!*.tfvars.example
**/.terraform/
backend-sbom-local.cdx.json
backend/*nest-backend-dev*.tar.gz
backend/*nest-backend-dev*.zip
backend/*nest-backend-staging*.tar.gz
Expand All @@ -46,10 +47,11 @@ backend/generated_videos/
backend/staticfiles
backend/zappa_settings.json
design/
frontend-sbom-local.cdx.json
frontend/.next
frontend/blob-report/
frontend/coverage
frontend/dist
frontend/.next
frontend/npm-debug.log*
frontend/out
frontend/playwright-report/
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,6 @@ repos:
exclude: pnpm-lock.yaml

- repo: https://github.com/tox-dev/pyproject-fmt
rev: v2.14.2
rev: v2.15.3
hooks:
- id: pyproject-fmt
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<div align="center">

[![OWASP](https://img.shields.io/badge/Lab-blue?&label=owasp%20level&style=for-the-badge)](https://owasp.org/www-project-nest/) [![OWASP](https://img.shields.io/badge/Code-blue?label=OWASP%20Type&style=for-the-badge)](https://owasp.org/www-project-nest/) [![project-nest](https://img.shields.io/badge/%23project--nest-blue?label=OWASP%20Slack&logoColor=white&style=for-the-badge)](https://owasp.slack.com/messages/project-nest)
[![OWASP](https://img.shields.io/badge/Lab-blue?&label=owasp%20level&style=for-the-badge)](https://owasp.org/www-project-nest/) [![OWASP](https://img.shields.io/badge/Code-blue?label=OWASP%20Type&style=for-the-badge)](https://owasp.org/www-project-nest/) [![project-nest](https://img.shields.io/badge/%23project--nest-blue?label=OWASP%20Slack&logoColor=white&style=for-the-badge)](https://owasp.slack.com/archives/project-nest)

[![License](https://img.shields.io/github/license/owasp/nest?color=blue&label=License&style=for-the-badge)](https://github.com/OWASP/Nest/blob/main/LICENSE) [![Last Commit](https://img.shields.io/github/last-commit/owasp/nest/main?color=blue&style=for-the-badge&label=Last%20commit)](https://github.com/OWASP/Nest/commits/main/) [![Contributors](https://img.shields.io/github/contributors/owasp/nest?style=for-the-badge&label=Contributors&color=blue)](https://github.com/OWASP/Nest/graphs/contributors)

Expand Down
20 changes: 20 additions & 0 deletions backend/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ else
SHELL := /bin/bash
endif

.PHONY: sbom-backend-image

build-backend-local-image:
@DOCKER_BUILDKIT=1 docker build \
--no-cache \
Expand Down Expand Up @@ -192,6 +194,24 @@ security-scan-backend-image:
$$(grep -E '^FROM aquasec/trivy:' docker/trivy/Dockerfile | sed 's/^FROM //') \
image --config /trivy.yaml $(BACKEND_IMAGE_NAME)

SBOM_VERSION := $(if $(RELEASE_VERSION),$(RELEASE_VERSION),local)

sbom-backend-image:
@if [ "$(BACKEND_IMAGE_NAME)" = "nest-backend-local" ]; then \
$(MAKE) build-backend-local-image; \
fi
@echo "Generating SBOM for image: $(BACKEND_IMAGE_NAME)..."
@docker run \
--rm \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $(CURDIR)/.trivy-cache:/root/.cache/trivy \
-v $(CURDIR):/work \
$$(grep -E '^FROM aquasec/trivy:' docker/trivy/Dockerfile | sed 's/^FROM //') \
image \
--format cyclonedx \
--output /work/backend-sbom-$(SBOM_VERSION).cdx.json \
$(BACKEND_IMAGE_NAME)

shell-backend:
@CMD="/bin/sh" $(MAKE) exec-backend-command-it

Expand Down
4 changes: 0 additions & 4 deletions backend/apps/ai/common/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ def create_chunks_and_embeddings(
ValueError: If context is None or invalid

"""
from apps.ai.models.chunk import Chunk

try:
last_request_time = datetime.now(UTC) - timedelta(
seconds=DEFAULT_LAST_REQUEST_OFFSET_SECONDS
Expand Down Expand Up @@ -94,8 +92,6 @@ def regenerate_chunks_for_context(context: Context):
context (Context): The specific context instance to be updated.

"""
from apps.ai.models.chunk import Chunk

context.chunks.all().delete()
new_chunk_texts = Chunk.split_text(context.content)

Expand Down
2 changes: 2 additions & 0 deletions backend/apps/ai/models/chunk.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ class Chunk(TimestampedModel):
"""AI Chunk model for storing text chunks with embeddings."""

class Meta:
"""Model options."""

db_table = "ai_chunks"
verbose_name = "Chunk"
unique_together = ("context", "text")
Expand Down
2 changes: 2 additions & 0 deletions backend/apps/ai/models/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ class Context(TimestampedModel):
source = models.CharField(max_length=100, blank=True, default="")

class Meta:
"""Model options."""

db_table = "ai_contexts"
verbose_name = "Context"
unique_together = ("entity_type", "entity_id", "source")
Expand Down
2 changes: 2 additions & 0 deletions backend/apps/api/models/api_key.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ class ApiKey(models.Model):
"""API key model."""

class Meta:
"""Model options."""

db_table = "api_keys"
verbose_name_plural = "API keys"
ordering = ["-created_at"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ class Command(BaseCommand):

def handle(self, *_args, **_options) -> None:
"""Update replicas for Algolia indices."""
print("\n Starting replica configuration...")
self.stdout.write("\n Starting replica configuration...\n")
ProjectIndex.configure_replicas()
print("\n Replica have been Successfully created.")
self.stdout.write(self.style.SUCCESS("\n Replicas have been successfully created.\n"))
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ class Command(BaseCommand):

def handle(self, *_args, **_options) -> None:
"""Update synonyms for Algolia indices."""
print("\nThe following models synonyms were reindexed:")
self.stdout.write("\nThe following models synonyms were reindexed:")
for index in (IssueIndex, ProjectIndex):
count = index.update_synonyms()
if count:
print(f"{7 * ' '} * {index.index_name.capitalize()} --> {count}")
self.stdout.write(f"{7 * ' '} * {index.index_name.capitalize()} --> {count}")
2 changes: 1 addition & 1 deletion backend/apps/common/management/commands/dump_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def handle(self, *args, **options):
dump_cmd += [f"--table={table}" for table in tables]
dump_cmd += ["-f", str(output_path)]

run(dump_cmd, check=True, env=env)
run(dump_cmd, check=True, env=env) # noqa: S603
self.stdout.write(self.style.SUCCESS(f"Created dump: {output_path}"))
except CalledProcessError as e:
message = f"Command failed: {e.cmd}"
Expand Down
2 changes: 1 addition & 1 deletion backend/apps/common/management/commands/purge_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ def handle(self, *_args, **options) -> None:
sql.Identifier(model._meta.db_table)
)
)
print(f"Purged {nest_app}.{model.__name__}")
self.stdout.write(f"Purged {nest_app}.{model.__name__}")
2 changes: 2 additions & 0 deletions backend/apps/core/models/prompt.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ class Prompt(TimestampedModel):
"""Prompt model."""

class Meta:
"""Model options."""

db_table = "nest_prompts"
verbose_name_plural = "Prompts"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def handle(self, *args, **options) -> None:
projects = []
for idx, project in enumerate(active_projects[offset:]):
prefix = f"{idx + offset + 1} of {active_projects_count}"
print(f"{prefix:<10} {project.owasp_url}")
self.stdout.write(f"{prefix:<10} {project.owasp_url}\n")

repository_urls = project.related_urls.copy()
for repository_url in repository_urls:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def handle(self, *args, **options) -> None:
update_fields += ["summary"] if (update_summary := options["update_summary"]) else []
for idx, issue in enumerate(open_issues[offset:]):
prefix = f"{idx + offset + 1} of {open_issues_count - offset}"
print(f"{prefix:<10} {issue.title}")
self.stdout.write(f"{prefix:<10} {issue.title}\n")

if update_hint:
issue.generate_hint(open_ai=open_ai)
Expand Down
Loading
Loading