3-tier architecture, security hardening, parser fixes, and upstream backports#64
Closed
xMinhx wants to merge 41 commits into
Closed
3-tier architecture, security hardening, parser fixes, and upstream backports#64xMinhx wants to merge 41 commits into
xMinhx wants to merge 41 commits into
Conversation
Sponsored docker compose preview version. Agentic Coding Fixed to dockerize the frontend container. Startet dokumentation change (not finished yet)
… adding login page
…rated to queries/apiClient)
- Add api/ prefix to all route constants in constants.tsx - Remove /api/ from ApiClientProvider baseURL (routes now carry it) - Add CSRF pre-fetch (GET /api/login) before login POST - Wrap LoginBox in <form> with handleSubmit, make onConfirm async - Remove email-only validation (accept usernames) - Fix eye icon z-index and add alt text - Add @ensure_csrf_cookie to Login view, add GET handler for CSRF cookie - Remove email validation from backend login view - Add JSON 404 handler, make SPA catch-all dev-only in urls.py - Profile.tsx: remove onClick from Menu that broke MenuItem handlers
- CORS_ALLOW_CREDENTIALS for cross-origin cookie auth - Remove STATICFILES_DIRS (Nginx serves frontend assets) - Fix HTTPS detection (startswith instead of substring check) - Add build script to package.json - Output webpack to ./dist with HtmlWebpackPlugin + DefinePlugin - Add REACT_APP_API_URL DefinePlugin for API endpoint config - Uncomment gunicorn CMD with LOG_LEVEL env var - set -e in entrypoint, collectstatic comment, seed_preview_data for dev - Add frontend staticfiles/dist to .gitignore - Fix EOF newlines in UserSettingsContent Co-authored-by: Stefan Schubert <stefan@bluewhale.de>
- docker-compose-preview.yml: preview/development compose config - frontend/Dockerfile: Nginx container serving built SPA - frontend/.dockerignore, frontend/nginx.conf: nginx config - frontend/src/index.html, login.html: standalone HTML templates for HtmlWebpackPlugin - frontend/src/queries/apiClient.ts: axios instance with CSRF config - backend/analyzer/management/: seed_preview_data management command - backend/assets/.gitkeep: ensure assets directory exists Co-authored-by: Stefan Schubert <stefan@bluewhale.de>
…mrc and requirements.lock
- update quick-start API/static expectations for 3-tier preview - document REACT_APP_API_URL same-origin proxy behavior - clarify makemigrations is a manual dev workflow, not container startup - point dev installation guide to docker-compose-preview.yml - ignore generated backend/staticfiles artifacts
- remove invalid frontend image COPY of /staticfiles paths that are outside frontend build context - proxy /static/ via frontend nginx to backend in preview mode - stop running makemigrations at container startup; keep migrate only for deterministic schema - add RUNNER_UID/GID defaults in preview compose to improve first-run reliability - run gunicorn in Dockerfile prod stage with LOG_LEVEL default expansion - switch docker-compose.ci.yml build target to prod so CI validates production-like runtime Reasoning: These changes remove non-deterministic startup behavior and fix a concrete preview build failure, while making CI exercise the same runtime model used for production deployment.
- conftest.py patches requests.get + time.sleep in cve_fetcher module - Skips mock for tests marked @pytest.mark.nvd_integration - Moves test_cve_fetcher.py module-level code into fixtures - pytest.ini excludes nvd_integration by default 66 tests now run in ~1s vs timing out at >120s
- Remove debug console statements that logged passwords (LoginBox.tsx)
- Translate German comments to English (LoginBox.tsx)
- Add GET method with @ensure_csrf_cookie to Login view; remove validate_email from username check
- Restore deleted backend/assets/icons/ and backend/assets/images/ (eye.svg, logos, flags, etc.)
- Add set -e to entrypoint.sh
- Fix FQDN https check to use startswith("https://") instead of substring match
- Switch frontend Dockerfile from yarn to npm ci + npm run build
- Add frontend/.dockerignore
5 tests covering the full upload→parse→DB flow using pre-baked OWASP fixtures (no live NVD calls): - test_large_report_parses_correctly (54 deps, 33 CVEs) - test_small_report_parses_correctly (19 deps, 1 CVE) - test_cve_ids_valid_format (CVE-YYYY-NNNNN pattern) - test_cve_severity_not_null - test_threshold_rejects_when_exceeded (406 on LOW) Marked @pytest.mark.e2e, excluded from default pytest run.
Runs E2E report analysis tests on bare Ubuntu runner with PostgreSQL 16, Python 3.12, and pre-baked fixtures. No Docker-in-Docker needed. Uses pytest -m e2e marker.
The e2e_test job referenced backend/requirements-dev.txt which does not exist. Remove the line since all dependencies (including pytest and pytest-django) are already in backend/requirements.txt.
Use hmac.compare_digest for constant-time string comparison to prevent timing side-channel attacks that could allow an attacker to recover API keys character by character. Fixes C1 from security audit.
Use ldap3.utils.conv.escape_filter_chars to escape special characters in LDAP search filters before interpolation. Prevents authentication bypass and data exfiltration via crafted username values. Fixes C2 from security audit.
Only allow hardcoded dev credentials when IS_DEV=True to prevent accidental exposure in production. Use hmac.compare_digest for constant-time password comparison to prevent timing attacks on credential validation. Fixes C3 from security audit.
Add IsAuthenticated and analyzer.delete_project permission requirements to DeleteProjectAPI to prevent IDOR. Any authenticated user could previously delete any project. Fixes H1 from security audit.
Add regex validation for CVE ID format to prevent SSRF via crafted CVE IDs. Add 30-second timeout to NVD and EPSS API requests to prevent slow-loris DoS attacks. Fixes H2 from security audit.
Add ALLOWED_TEMPLATES frozenset to HtmlView to prevent template injection. Non-whitelisted template names are logged and the login page is rendered instead. This mitigates information disclosure via path traversal. Fixes H5 from security audit.
The api_404_view function was defined twice in urls.py. The second definition silently shadowed the first. Remove the duplicate to ensure consistent behavior. Fixes M4 from security audit.
L1: Use specific UID (1000) for baseuser to avoid permission
issues with volume mounts.
L2: Add HEALTHCHECK instruction using Python urllib to verify
the application is responding.
L3: Make gunicorn workers and threads configurable via
GUNICORN_WORKERS and GUNICORN_THREADS env vars.
Fixes L1, L2, L3 from security audit.
H3: Add AnonRateThrottle and UserRateThrottle. Tighten login
rate to 5/min to prevent brute-force attacks.
H4: Use secrets.token_urlsafe() to generate random dev
credentials when not explicitly set. Log warning.
M2: Replace CORS_ALLOW_ALL_ORIGINS with explicit origins
whitelist (already correct, but add dev origins).
M3: Add HTTPS enforcement settings (HSTS, SSL redirect,
X-Frame-Options, content type nosniff) for production.
Fixes H3, H4, M2, M3 from security audit.
The ParserManager passes request.data as a dict, but cyclonedx_parser called json.loads() directly, which crashes on dict input. Add an isinstance check to handle both string and dict input, matching the trivy parser's behavior.
Trivy reports can list multiple CVEs for the same (pkg, version) pair.
The parser used dependency_name as the dict key, which caused later
entries to overwrite earlier ones for the same dep. Switch the key to
f"{name}:{version}" and skip duplicate CVE IDs so all vulnerabilities
for a dependency are preserved.
Discovered via E2E test: requests@2.32.3 was silently losing CVEs.
Cover the happy path (string + dict input) and the ParserManager dispatch. CycloneDX tests include a regression case for the dict-input crash that was fixed in the previous commit.
Verify the full upload pipeline for both tools: - Trivy: 17 deps, 56 Reports, 55 unique CVEObjects stored - CycloneDX: 14 components stored, 0 CVEs (clean SBOM) These tests also cover the dedup behavior: trivy's 58 raw vulnerability entries collapse to 56 (dep, cve) pairs because 3 CVEs are shared between deps and 2 are duplicated within the same dep.
Generated by scanning this project with trivy 0.71.2 and cyclonedx-bom 7.3.0 to provide realistic test data for the previously untested parsers. - trivy-report-securechecknext.json (312K, 17 deps, 58 vuln entries) - cyclonedx-report-securechecknext.json (12K, 14 components)
…t parsers - README.md: CycloneDX and Trivy are now supported (not 'future features'); add 'Supported Report Formats' section - API.md: toolName now lists owasp, trivy, cyclonedx; add example fixtures - ARCHITECTURE.md: reflect Nginx frontend container, Gunicorn backend, and 3-tier deployment (not Django-serves-SPA) - QUICK_START.md, PROJEKTUEBERSICHT_3TIER.md: docker-compose (v1) -> docker compose (v2) - README-DEV-INSTALLATION.md: docker-compose is bundled with Docker Engine 20.10+, no separate install
Fixes accso#22 The solution was generated using github copilot workspace. --- For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/accso/SecureCheckPlus/issues/22?shareId=XXXX-XXXX-XXXX-XXXX).
…stream accso#22) - Swap adventurer-neutral API URL for local @dicebear/core v9 + bottts-neutral - Add avatar.ts utility wrapping createAvatar() -> toDataUri() - Update UserSettingsContent.tsx and Profile.tsx to use getAvatarDataUri() - Remove dicebear.com URL from constants.tsx - Remove django-csp app, middleware, and all CSP config (no external images left) - Shell -> exec form CMD in Dockerfile for proper signal handling - as -> AS in Dockerfile per convention - Exclude .opencode/ from git tracking Co-authored-by: Niklas Büchel <NikAcc@users.noreply.github.com>
…stream accso#38) Co-authored-by: Nils Kreiner <kreinern@users.noreply.github.com>
The original versions were heavily German with emoji slop
("🚀", "✅", "❌", etc.). Rewrite both files in plain English
following the project's existing style (API.md, ARCHITECTURE.md).
Changes:
- QUICK_START.md: complete rewrite, 268 -> 215 lines, no German
- API_TEST_GUIDE.md: complete rewrite, 88 -> 137 lines, English only
with practical curl examples and URL structure reference
- README.md: fix broken link to renamed README-INSTALLATION.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Rebased fork branch containing 41 commits across several independent concerns, curated from xMinhx/SecureCheckNext.
Changes
3-tier architecture (7 commits)
Separates the Django monolith into a 3-tier stack: React SPA frontend (Webpack 5, served as Django static files) + Django REST API backend + PostgreSQL. Adds Docker Compose preview deployment with frontend nginx container.
Security hardening (9 commits)
Parser fixes + tests (6 commits)
CI improvements (4 commits)
Upstream backports (8 commits)
Incorporates changes originally authored by @NikAcc and @kreinern from open PRs:
Documentation (2 commits)
Notes