diff --git a/.github/workflows/cicd-actions.yml b/.github/workflows/cicd-actions.yml index dffbe4d..59dc4b8 100644 --- a/.github/workflows/cicd-actions.yml +++ b/.github/workflows/cicd-actions.yml @@ -117,6 +117,63 @@ jobs: name: htmlcov path: backend/htmlcov + e2e_test: + runs-on: ubuntu-latest + needs: create_dotenv_file + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Set up Node + uses: actions/setup-node@v4 + with: + node-version: "18" + + - name: Download .env artifact + uses: actions/download-artifact@v4 + with: + name: env_file + path: backend + + - name: Install PostgreSQL + uses: harmon758/postgresql-action@v1 + with: + postgresql version: "16" + postgresql user: securecheckplus + postgresql password: ${{ secrets.TEST_DB_PASSWORD }} + postgresql database: securecheckplus + + - name: Wait for PostgreSQL + run: | + until pg_isready -h localhost -p 5432 -U securecheckplus; do + echo "Waiting for PostgreSQL..." + sleep 2 + done + + - name: Install Python dependencies + run: | + python -m pip install --upgrade pip + pip install -r backend/requirements.txt + + - name: Run E2E tests + working-directory: backend + env: + IS_DEV: "True" + POSTGRES_HOST: localhost + POSTGRES_USER: securecheckplus + POSTGRES_DB: securecheckplus + POSTGRES_PORT: "5432" + POSTGRES_PASSWORD: ${{ secrets.TEST_DB_PASSWORD }} + DJANGO_SECRET_KEY: ${{ secrets.TEST_DJANGO_SECRET_KEY }} + SALT: ${{ secrets.TEST_SALT }} + run: | + python -m pytest analyzer/test/test_e2e.py -m e2e -v --tb=short + cleanup: runs-on: ubuntu-latest needs: testing diff --git a/.gitignore b/.gitignore index 0848898..5e5230f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ ### Custom Files ### backend/assets/bundle.js backend/staticfiles/* +frontend/staticfiles/* +frontend/dist/ node_modules backend/*.env .idea @@ -344,4 +346,3 @@ modules.xml # option (not recommended) you can uncomment the following to ignore the entire idea folder. # End of https://www.toptal.com/developers/gitignore/api/django,python,intellij+all ->>>>>>> .gitignore diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..3c03207 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +18 diff --git a/API.md b/API.md index de5180a..3609c3d 100644 --- a/API.md +++ b/API.md @@ -15,7 +15,7 @@ The Analyzer supports one HTTP POST request at relative URL `api/analyzer`: | header | `content-type` | Must be "text/plain" | | parameter | `projectId` | The ID of the project as configured in the webfrontend. | | parameter | `fileType` | Type of the report format (only "json" for the time being) | -| parameter | `toolName` | Tool used to generate the report (only "owasp" for the time being) | +| parameter | `toolName` | Tool used to generate the report: `owasp`, `trivy`, or `cyclonedx` | The content of the scan report file must be passed as POST payload. @@ -25,13 +25,15 @@ An example URL would be : ### Supported Formats -Currently, only scan reports generated by tool OWASP in JSON format can be processed. See the following examples. +Scan reports generated by the following tools in JSON format can be processed. See the following examples. -| Tool | Format | Example | -|-------|--------|------------------------------------------------------------------------------------------------| -| OWASP | JSON | [Simple Python Example](backend/analyzer/test/data/dependency-check-report-python-small.json) | -| OWASP | JSON | [Complex Python Example](backend/analyzer/test/data/dependency-check-report-python-large.json) | -| OWASP | JSON | [Java Example](backend/analyzer/test/data/dependency-check-report-java.json) | +| Tool | Format | Example | +|------------|--------|--------------------------------------------------------------------------------------------------| +| OWASP | JSON | [Simple Python Example](backend/analyzer/test/data/dependency-check-report-python-small.json) | +| OWASP | JSON | [Complex Python Example](backend/analyzer/test/data/dependency-check-report-python-large.json) | +| OWASP | JSON | [Java Example](backend/analyzer/test/data/dependency-check-report-java.json) | +| Trivy | JSON | [Trivy Example](backend/analyzer/test/data/trivy-report-securechecknext.json) | +| CycloneDX | JSON | [CycloneDX Example](backend/analyzer/test/data/cyclonedx-report-securechecknext.json) | Use the script [scripts/run-adapter-image.bash](scripts/run-adapter-image.bash) to upload one of the test files to the analyzer API. Note that all required environment variables must be set beforehand (see end of file diff --git a/API_TEST_GUIDE.md b/API_TEST_GUIDE.md new file mode 100644 index 0000000..1aa2a16 --- /dev/null +++ b/API_TEST_GUIDE.md @@ -0,0 +1,119 @@ +# API Testing Guide + +How to test the SecureCheckPlus API correctly. + +## Common confusion: why `/api/` returns 404 + +```bash +curl http://localhost:8005/api/ +# Returns: 404 Not Found +``` + +This is correct behavior. `/api/` is only a URL prefix, not an endpoint. The actual endpoints are: + +- `/api/login` (POST) +- `/api/me` (GET) +- `/api/projects` (GET) +- `/api/projectsFlat` (GET) +- `/api/cveObject//update` (PUT) +- etc. + +## Testing real endpoints + +### Health check (no auth required) + +```bash +curl http://localhost:8005/check_health +# Expected: HTTP/1.1 200 OK, "I'm fine!" +``` + +### Login (POST) + +```bash +curl -X POST http://localhost:8005/api/login \ + -H "Content-Type: application/json" \ + -d '{"username":"secure-user@acme.de","password":"secure"}' +``` + +### Authenticated requests + +Authenticated requests use Django sessions. After login, the session cookie is set and subsequent requests with `-b cookies.txt -c cookies.txt` will be authenticated. + +```bash +# Login and save cookie +curl -c cookies.txt -X POST http://localhost:8005/api/login \ + -H "Content-Type: application/json" \ + -d '{"username":"secure-user@acme.de","password":"secure"}' + +# Use the saved cookie +curl -b cookies.txt http://localhost:8005/api/me +curl -b cookies.txt http://localhost:8005/api/projects +``` + +### Analyzer API + +The analyzer endpoint requires an API key in the `API-KEY` header (not the URL body): + +```bash +curl -X POST "http://localhost:8005/analyzer/api?projectId=my-project&fileType=json&toolName=owasp" \ + -H "API-KEY: your-api-key-here" \ + -H "Content-Type: application/json" \ + --data-binary @report.json +``` + +## Expected responses + +### Good: JSON for API requests + +```json +{"detail":"Authentication credentials were not provided."} +``` + +```json +{"username":"secure-user@acme.de","email":"..."} +``` + +### Bad: HTML for API requests + +If you see HTML responses (e.g., Django's default 404 page), the URL routing is misconfigured. Check that: + +- The request path includes the correct prefix (`/api/`, `/analyzer/api/`) +- The endpoint exists in `webserver/urls.py` or `securecheckplus/urls.py` +- The `BASE_URL` setting matches your deployment path + +## URL structure + +``` +/ → static frontend (Nginx in 3-tier mode) +/static/ → static files (proxied to backend) +/analyzer/api → analyzer endpoints +/api/ → webserver API prefix + /api/login → authentication + /api/me → current user + /api/projects → project list + /api/projectsFlat → flat project list + /api/projects/ → project detail + /api/projects//apiKey → API key management + /api/cveObject//update → CVE update + /api/myFavorites → user's favorite projects + /api/deleteProjects → bulk delete + /api/error404 → 404 handler +/check_health → health check (no prefix) +``` + +## Using scripts/run-adapter-image.bash + +A helper script exists for testing with the bundled OWASP report: + +```bash +# Set required environment variables +export API_KEY=your-api-key +export PROJECT_ID=your-project-id +export SERVER_URL=http://localhost:8005 +export REPORT_FILE_NAME=dependency-check-report.json + +# Run the script +scripts/run-adapter-image.bash +``` + +The script sends the report to `/analyzer/api` and prints the response. diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 133e4d0..cb8214d 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -4,11 +4,11 @@ ## Quick Overview for Developers -This Django-based web application serves as a tool to manage and track vulnerabilities in software dependencies. It utilizes a **React single-page frontend** integrated into the Django backend. The core features include report uploads, vulnerability tracking, project management, and notifications. Below is a concise introduction for developers to get started: +This Django-based web application serves as a tool to manage and track vulnerabilities in software dependencies. It uses a **3-tier architecture** in production: a separate React frontend served by Nginx, a Django backend providing the API, and a PostgreSQL database. The core features include report uploads, vulnerability tracking, project management, and notifications. Below is a concise introduction for developers to get started: -- **Frontend**: The single-page application is developed using **React** and served through Django. It provides an interactive interface for uploading reports, managing projects, and viewing vulnerabilities. -- **Backend**: The backend is powered by Django, which handles both API requests from the React frontend and core logic for managing vulnerabilities and user data. -- **Key Technologies**: Django (Backend and API server), React (Frontend), LDAP (Authentication) (optional, if used locally), and PostgreSQL (Database). +- **Frontend**: The single-page application is developed using **React** and built to static assets. In 3-tier (Docker) deployments, the assets are served by an Nginx container. In native dev mode, Django serves the SPA as a fallback. The frontend provides an interactive interface for uploading reports, managing projects, and viewing vulnerabilities. +- **Backend**: The backend is powered by Django (with Gunicorn in production), which exposes a JSON API consumed by the React frontend and handles core logic for managing vulnerabilities and user data. +- **Key Technologies**: Django + Gunicorn (API server), React + Nginx (Frontend), LDAP (Authentication, optional), and PostgreSQL (Database). For more details about each module, continue reading the **Key Modules Overview** and **C4 Model Architecture** sections. @@ -70,9 +70,9 @@ The **Container Diagram** depicts the core system containers of the application ![Architecture Container Diagram](etc/images/diagram-architecture-container.drawio.png "Architecture Container Diagram") -- **React Frontend**: Provides an interactive user interface for uploading reports, managing projects, and viewing vulnerabilities. -- **Web Server (Django)**: Handles HTTP requests from users, serves the React frontend, and provides API endpoints for interaction. -- **Backend (Analyzer)**: Processes the uploaded vulnerability reports and manages core business logic such as parsing, notifications, and project management. +- **React Frontend (Nginx)**: Serves the built React single-page application and proxies `/api/` and `/analyzer/api` requests to the backend. +- **Backend (Django + Gunicorn)**: Handles HTTP API requests from the frontend, processes vulnerability data, and manages user/project/reports resources. In 3-tier mode, the backend is API-only; in native dev mode, Django can also serve the SPA as a fallback. +- **Analyzer**: Processes the uploaded vulnerability reports and manages core business logic such as parsing, notifications, and project management. - **Database**: Stores data related to users, projects, dependencies, and vulnerabilities. For a more in-depth look into the schema of the database look at: [TODO] LINK - **External Systems**: - **LDAP**: Responsible for authentication and authorization of users. diff --git "a/PROJEKT\303\234BERSICHT_3TIER.md" "b/PROJEKT\303\234BERSICHT_3TIER.md" new file mode 100644 index 0000000..6c220e4 --- /dev/null +++ "b/PROJEKT\303\234BERSICHT_3TIER.md" @@ -0,0 +1,204 @@ +# SecureCheckPlus Projekt-Übersicht & 3Tier-Refactoring + +## Projektstruktur + +``` +SecureCheckPlus.git/ +├── backend/ # Django Backend (3Tier) +│ ├── analyzer/ # Sicherheitsanalyse App +│ ├── webserver/ # Web API & User Management +│ ├── securecheckplus/ # Django Settings & URLs +│ ├── utilities/ # Shared Constants & Helpers +│ ├── templates/ # Email Templates +│ └── Dockerfile +│ +├── frontend/ # React TypeScript Frontend +│ └── src/ +│ ├── components/ +│ ├── page/ +│ ├── queries/ # API Client +│ └── style/ +│ +├── adapter/ # Zusätzlicher Adapter Service +│ +└── docker-compose-preview.yml # Testumgebung +``` + +## 3Tier-Architektur + +Die Anwendung folgt einer **3-Tier-Architektur**: + +### Tier 1: Presentation Layer (Frontend) +- **React + TypeScript** +- Container: `securecheckplus_frontend` +- Port: 3000 +- **Komponenten:** + - Login-Seite + - Project Dashboard + - Report Viewer + - CVSS Calculator + +### Tier 2: Application Layer (Backend) +- **Django 5.1.2** + REST Framework +- Container: `securecheckplus_server` +- Port: 8000 (intern) → 8005 (extern) +- **Apps:** + - `analyzer`: CVE-Analyse und Dependency-Management + - `webserver`: REST API, User & Project Management + - `utilities`: Gemeinsame Konstanten und Helper + +### Tier 3: Data Layer (Database) +- **PostgreSQL** +- Container: `securecheckplus_db` +- Port: 5432 + +## Hauptkomponenten + +### Backend: Analyzer App (`analyzer/`) +**Modelle:** +- `Project`: Verwaltete Projekte +- `Dependency`: Dependencies mit Versionierung +- `CVEObject`: CVE Informationen (CVSS, EPSS, etc.) +- `Report`: Verbindung zwischen Dependency und CVE mit Status + +**Eigenschaften:** +- CVE-Daten-Integration (NVD API) +- Risk-Score Berechnung basierend auf EPSS +- Dependency Tracking pro Projekt +- Status-Management (REVIEW, NO_THREAT, THREAT_FIXED, etc.) + +### Backend: Webserver App (`webserver/`) +**Modelle:** +- `User`: Authentifizierung & Benachrichtigungen +- `UserWatchProject`: Many-to-Many Beziehung User ↔ Project + +**Funktionalitäten:** +- REST API für Frontend +- User Management (Favoriten, Verlauf) +- LDAP Integration (optional) + +## Docker Compose Services + +### Development Setup (docker-compose-preview.yml) + +1. **securecheckplus_frontend** + - Build: `./frontend` (Dev-Modus) + - Environment: `REACT_APP_API_URL=""` (Same-Origin via Nginx Proxy) + - Exposes: Port 3000 + +2. **securecheckplus_server** + - Build: `./backend` (target: dev) + - Environment: Django Config (SECRET_KEY, DB-Credentials, etc.) + - Volumes: `./backend:/backend` (Hot-Reload) + - Exposes: Port 8005 → 8000 (intern) + - Dependencies: PostgreSQL, SMTP Mailserver + +3. **securecheckplus_db** + - Image: postgres (latest) + - Environment: DB Credentials + - Exposes: Port 5432 + +4. **smtp_mailserver** + - Image: maildev/maildev + - Purpose: Email Testing + - Exposes: Port 1080 (MailDev UI) + +## Häufige Kommandos + +### Backend starten/stoppen +```bash +# Mit Preview Compose +docker compose -f docker-compose-preview.yml up --build + +# Mit Logs +docker compose -f docker-compose-preview.yml logs -f securecheckplus_server + +# Backend-Shell betreten +docker exec -it securecheckplus_server sh +``` + +### Datenbank-Operationen +```bash +# In der Container-Shell: +python manage.py migrate +python manage.py createsuperuser +python manage.py showmigrations +``` + +### Tests ausführen +```bash +# Im Backend Container +python manage.py test + +# Mit Coverage +pytest --cov=analyzer --cov=webserver +``` + +## Konfiguration + +### Umgebungsvariablen (backend) +- `IS_DEV`: Development-Modus (True/False) +- `FULLY_QUALIFIED_DOMAIN_NAME`: Frontend URL (für CORS) +- `DJANGO_SECRET_KEY`: Sicherheitsschlüssel +- `POSTGRES_*`: Datenbankzugangsdaten +- `NVD_API_KEY`: National Vulnerability Database API-Key +- `ADMIN_USERNAME/PASSWORD`: Superuser-Credentials +- `USER_USERNAME/PASSWORD`: Normaler User + +### LDAP Integration (Optional) +- `LDAP_HOST`: LDAP Server +- `LDAP_ADMIN_DN`: Admin Distinguished Name +- `LDAP_ADMIN_PASSWORD`: Admin Passwort +- `LDAP_USER_BASE_DN`: User Search Base +- `LDAP_ADMIN_GROUP_DN`: Admin Group DN +- etc. + +## Problembehebung + +### Issue: "Your models in app(s): 'analyzer' have changes" +**Lösung:** +Nur manuell in der Entwicklung ausführen (nicht automatisch beim Container-Start): +```bash +python manage.py makemigrations +python manage.py migrate +``` + +### Issue: "The directory '/backend/assets' does not exist" +**Lösung:** +```bash +mkdir -p backend/assets +touch backend/assets/.gitkeep +``` + +### Issue: CSRF deactivated warnings +**Erklärung:** Normal in DEV-Modus, da HTTP verwendet wird. In PROD automatisch HTTPS erzwungen. + +## Migrationen Management + +### Migrationsdatei Struktur +- `analyzer/migrations/0001_initial.py`: Erste Migrationsdatei +- `analyzer/migrations/0002_initial.py`: ForeignKey & Relations Setup + +Beim Refactoring müssen neue Migrationen erstellt werden: +Manuell durch Entwickler, bevor Änderungen committed werden: +```bash +python manage.py makemigrations analyzer webserver +python manage.py migrate +``` + +## Best Practices für Entwicklung + +1. **Immer in der Container-Shell arbeiten** für Datenbank-Operationen +2. **Hot-Reload aktiviert**: Änderungen am Backend werden automatisch neu geladen +3. **Migrationen versionieren**: Nach Model-Änderungen `makemigrations` ausführen +4. **Environment-Variablen nutzen**: Für Dev/Prod-Unterschiede +5. **Tests schreiben**: Vor Production-Deployment testen + +## Nächste Schritte (3Tier-Refactoring) + +- [ ] Alle Migrationen generieren und testen +- [ ] API-Layer vollständig separieren +- [ ] Frontend-Komponenten refaktorieren +- [ ] Authentifizierung erweitern +- [ ] Performance-Testing durchführen + diff --git a/QUICK_START.md b/QUICK_START.md new file mode 100644 index 0000000..71755fa --- /dev/null +++ b/QUICK_START.md @@ -0,0 +1,215 @@ +# Quick Start: 3-Tier Testing + +Validate the 3-tier deployment (frontend + backend + db) in about 15 minutes. + +## Prerequisites + +- Docker with `docker compose` (v2, bundled with Docker Engine 20.10+) +- About 2 GB free disk space for images and volumes + +## Step 1: Build the frontend + +```bash +cd frontend +npm install +npm run build +ls -la dist/ # Verify: index.html, app.js, login.js exist +``` + +Expected: `frontend/dist/` exists with content. + +## Step 2: Start the Docker stack + +```bash +docker compose -f docker-compose.yml -f docker-compose-preview.yml up --build -d +docker compose -f docker-compose.yml -f docker-compose-preview.yml logs -f +``` + +Expected: All containers start without errors. + +A helper script is also available: `scripts/dev-up.sh` (does the same thing). + +## Step 3: Quick verification + +### Frontend reachable + +```bash +curl -I http://localhost:3000/ +# Expected: HTTP/1.1 200 OK +``` + +### Backend API reachable + +```bash +curl -I http://localhost:8005/check_health +# Expected: HTTP/1.1 200 OK + +curl -i http://localhost:8005/api/projects +# Expected: HTTP/1.1 401/403 without login (auth is enforced) + +curl -i http://localhost:8005/api/ +# Expected: HTTP/1.1 404 (only an API prefix, no endpoint) +``` + +### Static assets via frontend proxy + +```bash +curl -I http://localhost:3000/static/rest_framework/css/default.css +# Expected: HTTP/1.1 200 OK +``` + +### Frontend assets + +```bash +curl -I http://localhost:3000/app.js +# Expected: HTTP/1.1 200 OK +``` + +### Migrations applied + +```bash +docker logs securecheckplus_server | grep -i migration +# Expected: "Migrations were applied" or "No migrations to apply" +``` + +## Step 4: Browser test + +1. Open http://localhost:3000 in a browser +2. Log in with: + - Username: `secure-user@acme.de` + - Password: `secure` +3. The dashboard should load +4. Open DevTools (F12) → Network tab and verify: + - HTML/JS/CSS served from `localhost:3000` + - API calls go to `localhost:8005/api/` + +## Checklist + +- [ ] `frontend/dist/` exists +- [ ] Frontend container is running +- [ ] Backend container is running +- [ ] No STATICFILES_DIRS warnings +- [ ] Frontend reachable on port 3000 +- [ ] Backend health endpoint reachable on port 8005 +- [ ] API returns 401/403 without authentication +- [ ] `/api/` prefix returns 404 (no endpoint) +- [ ] Static assets reachable via frontend proxy +- [ ] Migrations applied +- [ ] Browser test successful +- [ ] Logs clean (no errors) + +## Troubleshooting + +### Frontend not reachable (port 3000) + +```bash +docker logs securecheckplus_frontend +docker exec securecheckplus_frontend ls -la /usr/share/nginx/html/ +``` + +Check for Nginx errors, verify the Dockerfile, confirm `dist/` was copied. + +### Backend returns 404 for API + +```bash +docker logs securecheckplus_server | tail -50 +docker exec securecheckplus_server python manage.py check +``` + +Check for Django errors, verify URL configuration. + +### STATICFILES warning appears + +This should not happen (it was removed). If it does, check `settings.py`: + +```bash +docker exec securecheckplus_server grep STATICFILES_DIRS /backend/securecheckplus/settings.py +``` + +### Migrations failed + +```bash +docker exec securecheckplus_server python manage.py showmigrations +docker exec securecheckplus_server python manage.py migrate +``` + +### Restart everything + +```bash +docker compose -f docker-compose.yml -f docker-compose-preview.yml down +docker system prune -f +docker compose -f docker-compose.yml -f docker-compose-preview.yml up --build -d +``` + +## Expected log output + +Good output (server started): + +``` +securecheckplus_server | Waiting for postgres... +securecheckplus_server | PostgreSQL started +securecheckplus_server | System check identified no issues. +securecheckplus_server | No migrations to apply. +securecheckplus_server | 0 static files copied +securecheckplus_server | Django version 5.1.2, running development server... +securecheckplus_frontend | nginx: master process started +``` + +Good output (migrations ran): + +``` +securecheckplus_server | Running migrations... +securecheckplus_server | Applying ... OK +``` + +Bad output (old errors that should not appear): + +``` +staticfiles.W004: The directory '/backend/assets' does not exist +Your models in app(s): 'analyzer' have changes +STATICFILES_DIRS = [...] +``` + +## Support commands + +```bash +# Check status +docker compose -f docker-compose.yml -f docker-compose-preview.yml ps + +# View specific container logs +docker logs securecheckplus_server -n 100 + +# Enter a container +docker exec -it securecheckplus_server sh + +# Run Django checks +docker exec securecheckplus_server python manage.py check + +# Test Nginx config +docker exec securecheckplus_frontend nginx -t + +# Test database connection +docker exec securecheckplus_db psql -U securecheckplus -d some-db-name -c "SELECT version();" + +# Tail all logs +docker compose -f docker-compose.yml -f docker-compose-preview.yml logs --tail=200 +``` + +## Success criteria + +**Green (all OK):** +- Frontend port 3000 returns 200 +- Backend health endpoint returns 200 +- API endpoints return 401/403 without login +- `/api/` prefix returns 404 (no endpoint) +- Static assets reachable via frontend proxy +- Migrations applied +- No STATICFILES_DIRS warnings +- Browser test successful + +**Red (something is broken):** +- Frontend not reachable +- Backend errors in logs +- STATICFILES_DIRS warning present +- Browser shows 404s +- Migrations failed diff --git a/README-DEV-INSTALLATION.md b/README-DEV-INSTALLATION.md new file mode 100644 index 0000000..42e64a5 --- /dev/null +++ b/README-DEV-INSTALLATION.md @@ -0,0 +1,28 @@ +
+ +
+ +This page describes how to install and run the application SecureCheckPlus by Accso locally +for further development and testing SecureCheckPlus or just to have a look at it and try it out. + +# Running the Application using docker-compose + +## Prerequisites + +Your development environment has to meet the following criteria: + +* You must have a local docker demon running. This is usually done by installing + [Docker Desktop](https://www.docker.com/products/docker-desktop/) under Windows and macOS or a + [native Docker daemon](https://docs.docker.com/get-started/get-docker/) under Linux. +* `docker compose` is included with Docker Desktop / Docker Engine 20.10+; no separate install required. +* You must be able to start a Docker container in your local environment. +* You require to obtain a registration key from https://nvd.nist.gov/ if you don't have one already at hand. This is + necessary to download the vulnerability data from the NVD database. The registration key is free of charge. + +## Configuration + +Use the preview setup file [docker-compose-preview.yml](docker-compose-preview.yml). +Set `NVD_API_KEY` in the `securecheckplus_server` service if you want live NVD lookups. + +For local Docker user mapping, optional variables are: +`RUNNER_UID` and `GID` (defaults are used in preview if unset). diff --git a/README-INSTALLATION.md b/README-PROD-INSTALLATION.md similarity index 93% rename from README-INSTALLATION.md rename to README-PROD-INSTALLATION.md index b437d45..1aec5da 100644 --- a/README-INSTALLATION.md +++ b/README-PROD-INSTALLATION.md @@ -2,6 +2,8 @@ +This page describes how to install and run the application SecureCheckPlus by Accso in a production environment. + # Running the Application as Docker Container The application SecureCheckPlus is provided as Docker image at https://hub.docker.com/u/accso. The name of the image diff --git a/README.md b/README.md index 87962db..8640820 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ For the subsequent steps we will assume that you have the following data at hand * the name of the database user, and * the password of the database user. -See the [Server Installation Readme](README-INSTALLATION.md) for the installation of the SecureCheckPlus Plus server. +See the [Server Installation Readme](README-PROD-INSTALLATION.md) for the installation of the SecureCheckPlus Plus server. As soon as the server is set up, consult the [Webfrontend Readme](README-FRONTEND.md) to create a configuration for the first project that you would like to monitor. This will give you @@ -83,9 +83,13 @@ for the final step which is to integrate the SecureCheckPlus adapter into your C - Go (experimental) - Swift (experimental) +### Supported Report Formats + +- [OWASP Dependency-Check](https://owasp.org/www-project-dependency-check/) JSON reports +- [CycloneDX](https://cyclonedx.org/tool-center/) SBOM JSON reports +- [Trivy](https://github.com/aquasecurity/trivy) JSON reports (images, secrets, IaC files) + ### Possible future feature (also see [enhancement issues](https://github.com/accso/SecureCheckPlus/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement)): -- Support for [CycloneDX](https://cyclonedx.org/tool-center/) SBOM reports - More languages -- Support for [Trivy](https://github.com/aquasecurity/trivy) reports - Images, Secrets, IaC files - EMail notifications to developers. ### API Description diff --git a/backend/.dockerignore b/backend/.dockerignore index 2fca5d5..933df71 100644 --- a/backend/.dockerignore +++ b/backend/.dockerignore @@ -1,3 +1,3 @@ *.env .coverage -staticfiles/* \ No newline at end of file +../frontend/staticfiles/* \ No newline at end of file diff --git a/backend/Dockerfile b/backend/Dockerfile index d08bfcc..d19425d 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -18,18 +18,21 @@ RUN apk update --no-cache \ ENTRYPOINT ["sh", "/entrypoint.sh"] -CMD python manage.py runserver 0.0.0.0:8000 +CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"] -FROM dev as prod +FROM dev AS prod #ARG is required for the settings.py. Otherwise the build will fail, because required env variables have not been set ARG BUILD=1 COPY . /backend -RUN adduser -D baseuser && chown -R baseuser . +RUN adduser -D -u 1000 baseuser && chown -R baseuser . USER baseuser EXPOSE 8000 +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/check_health', timeout=2).read()" || exit 1 + # Overwrites previous CMD from stage "dev" -#CMD gunicorn securecheckplus.wsgi:application --bind 0.0.0.0:8000 --workers=2 --threads=2 --log-level INFO +CMD ["sh", "-c", "exec gunicorn securecheckplus.wsgi:application --bind 0.0.0.0:8000 --workers=${GUNICORN_WORKERS:-2} --threads=${GUNICORN_THREADS:-2} --log-level ${LOG_LEVEL:-INFO}"] diff --git a/backend/analyzer/management/commands/seed_preview_data.py b/backend/analyzer/management/commands/seed_preview_data.py new file mode 100644 index 0000000..6327985 --- /dev/null +++ b/backend/analyzer/management/commands/seed_preview_data.py @@ -0,0 +1,207 @@ +""" +Django management command: seed_preview_data +-------------------------------------------- +Creates a demo project "SecureCheckPlus" with realistic dependency and CVE +data so the preview environment shows a populated dashboard out of the box. + +The command is idempotent: running it multiple times is safe. +It is called automatically by entrypoint.sh when IS_DEV=True. +""" +import datetime + +from django.core.management.base import BaseCommand + +from analyzer.models import Project, Dependency, CVEObject, Report +from utilities.constants import ( + BaseSeverity, Status, Solution, Threshold, + AttackVector, AttackComplexity, PrivilegesRequired, + UserInteraction, ConfidentialityImpact, IntegrityImpact, + AvailabilityImpact, Scope, +) + + +DEMO_PROJECT = { + "project_id": "securecheckplus", + "project_name": "SecureCheckPlus", + "deployment_threshold": Threshold.MEDIUM.name, +} + +DEMO_DEPENDENCIES = [ + ("bootstrap", "3.3.6", "javascript", "MIT", "frontend/node_modules/bootstrap"), + ("jquery", "1.11.1", "javascript", "MIT", "frontend/node_modules/jquery"), + ("axios", "0.26.0", "javascript", "MIT", "frontend/node_modules/axios"), + ("react", "17.0.2", "javascript", "MIT", "frontend/node_modules/react"), + ("react-dom", "17.0.2", "javascript", "MIT", "frontend/node_modules/react-dom"), + ("react-query", "3.34.16","javascript", "MIT", "frontend/node_modules/react-query"), + ("react-router-dom", "6.2.2", "javascript", "MIT", "frontend/node_modules/react-router-dom"), + ("webpack", "5.70.0", "javascript", "MIT", "frontend/node_modules/webpack"), + ("Django", "5.1.2", "python", "BSD-3", "backend/requirements.txt"), + ("djangorestframework","3.15.2", "python", "BSD-3", "backend/requirements.txt"), + ("django-cors-headers","4.5.0", "python", "MIT", "backend/requirements.txt"), + ("requests", "2.32.3", "python", "Apache-2.0", "backend/requirements.txt"), + ("lxml", "5.3.0", "python", "BSD-3", "backend/requirements.txt"), + ("whitenoise", "6.7.0", "python", "MIT", "backend/requirements.txt"), +] + +DEMO_CVES = [ + ( + "CVE-2016-10735", BaseSeverity.MEDIUM.name, 6.1, 0.00384, + "In Bootstrap 3.x before 3.4.0, XSS is possible in the data-target attribute.", + AttackVector.NETWORK.value, AttackComplexity.LOW.value, PrivilegesRequired.NONE.value, + UserInteraction.Required.value, ConfidentialityImpact.LOW.value, + IntegrityImpact.LOW.value, AvailabilityImpact.NONE.value, Scope.CHANGED.value, + "https://github.com/twbs/bootstrap/pull/27033", + datetime.datetime(2019, 1, 9, tzinfo=datetime.timezone.utc), + ), + ( + "CVE-2018-14040", BaseSeverity.MEDIUM.name, 6.1, 0.00461, + "In Bootstrap before 4.1.2, XSS is possible in the collapse data-parent attribute.", + AttackVector.NETWORK.value, AttackComplexity.LOW.value, PrivilegesRequired.NONE.value, + UserInteraction.Required.value, ConfidentialityImpact.LOW.value, + IntegrityImpact.LOW.value, AvailabilityImpact.NONE.value, Scope.CHANGED.value, + "https://github.com/twbs/bootstrap/issues/26630", + datetime.datetime(2018, 7, 13, tzinfo=datetime.timezone.utc), + ), + ( + "CVE-2019-8331", BaseSeverity.MEDIUM.name, 6.1, 0.00512, + "In Bootstrap before 3.4.1 and 4.3.x before 4.3.1, XSS is possible in the " + "tooltip or popover data-template attribute.", + AttackVector.NETWORK.value, AttackComplexity.LOW.value, PrivilegesRequired.NONE.value, + UserInteraction.Required.value, ConfidentialityImpact.LOW.value, + IntegrityImpact.LOW.value, AvailabilityImpact.NONE.value, Scope.CHANGED.value, + "https://blog.getbootstrap.com/2019/02/13/bootstrap-4-3-1-and-3-4-1/", + datetime.datetime(2019, 2, 20, tzinfo=datetime.timezone.utc), + ), + ( + "CVE-2015-9251", BaseSeverity.MEDIUM.name, 6.1, 0.00698, + "jQuery before 3.0.0 is vulnerable to Cross-site Scripting (XSS) attacks when a " + "cross-domain Ajax request is performed without the dataType option.", + AttackVector.NETWORK.value, AttackComplexity.LOW.value, PrivilegesRequired.NONE.value, + UserInteraction.Required.value, ConfidentialityImpact.LOW.value, + IntegrityImpact.LOW.value, AvailabilityImpact.NONE.value, Scope.CHANGED.value, + "https://github.com/jquery/jquery/commit/753d591", + datetime.datetime(2018, 1, 18, tzinfo=datetime.timezone.utc), + ), + ( + "CVE-2019-11358", BaseSeverity.MEDIUM.name, 6.1, 0.01174, + "jQuery before 3.4.0 mishandles jQuery.extend(true, {}, ...) because of " + "Object.prototype pollution, allowing attackers to modify Object.prototype.", + AttackVector.NETWORK.value, AttackComplexity.LOW.value, PrivilegesRequired.NONE.value, + UserInteraction.Required.value, ConfidentialityImpact.LOW.value, + IntegrityImpact.LOW.value, AvailabilityImpact.NONE.value, Scope.CHANGED.value, + "https://github.com/jquery/jquery/commit/753d591", + datetime.datetime(2019, 4, 20, tzinfo=datetime.timezone.utc), + ), + ( + "CVE-2020-11022", BaseSeverity.MEDIUM.name, 6.9, 0.01987, + "In jQuery versions greater than or equal to 1.2 and before 3.5.0, " + "passing HTML from untrusted sources to jQuery's DOM manipulation methods may execute untrusted code.", + AttackVector.NETWORK.value, AttackComplexity.LOW.value, PrivilegesRequired.NONE.value, + UserInteraction.Required.value, ConfidentialityImpact.LOW.value, + IntegrityImpact.LOW.value, AvailabilityImpact.NONE.value, Scope.CHANGED.value, + "https://github.com/jquery/jquery/security/advisories/GHSA-gxr4-xjj5-5px2", + datetime.datetime(2020, 4, 29, tzinfo=datetime.timezone.utc), + ), + ( + "CVE-2021-3749", BaseSeverity.HIGH.name, 7.5, 0.00433, + "axios before 0.21.2 is vulnerable to Regular Expression Denial of Service (ReDoS) " + "via the trim function.", + AttackVector.NETWORK.value, AttackComplexity.LOW.value, PrivilegesRequired.NONE.value, + UserInteraction.NONE.value, ConfidentialityImpact.NONE.value, + IntegrityImpact.NONE.value, AvailabilityImpact.HIGH.value, Scope.UNCHANGED.value, + "https://github.com/axios/axios/releases/tag/v0.21.2", + datetime.datetime(2021, 8, 31, tzinfo=datetime.timezone.utc), + ), +] + +DEMO_REPORTS = [ + ("CVE-2016-10735", "bootstrap", "3.3.6", Status.THREAT.name, Solution.CHANGE_VERSION, "Upgrade to bootstrap >= 3.4.1."), + ("CVE-2018-14040", "bootstrap", "3.3.6", Status.REVIEW.name, Solution.NO_SOLUTION_NEEDED, ""), + ("CVE-2019-8331", "bootstrap", "3.3.6", Status.THREAT_FIXED.name, Solution.CHANGE_VERSION, "Fixed by upgrading to 4.x in next sprint."), + ("CVE-2015-9251", "jquery", "1.11.1", Status.THREAT.name, Solution.CHANGE_VERSION, "Upgrade to jquery >= 3.5.0."), + ("CVE-2019-11358", "jquery", "1.11.1", Status.REVIEW.name, Solution.NO_SOLUTION_NEEDED, ""), + ("CVE-2020-11022", "jquery", "1.11.1", Status.THREAT_WIP.name, Solution.CHANGE_VERSION, "Migration to jquery 3.x in progress."), + ("CVE-2021-3749", "axios", "0.26.0", Status.THREAT.name, Solution.CHANGE_VERSION, "Upgrade to axios >= 0.21.2."), +] + + +class Command(BaseCommand): + help = "Seeds the preview database with a demo 'SecureCheckPlus' project and sample vulnerability data." + + def handle(self, *args, **options): + self.stdout.write("Seeding preview data ...") + + project, created = Project.objects.get_or_create( + project_id=DEMO_PROJECT["project_id"], + defaults={ + "project_name": DEMO_PROJECT["project_name"], + "deployment_threshold": DEMO_PROJECT["deployment_threshold"], + }, + ) + if created: + self.stdout.write(f" ✓ Created project '{project.project_id}'") + else: + self.stdout.write(f" · Project '{project.project_id}' already exists – skipping.") + + dep_map: dict[tuple, Dependency] = {} + for dep_name, version, pkg_mgr, lic, path in DEMO_DEPENDENCIES: + dep, dep_created = Dependency.objects.get_or_create( + project=project, + dependency_name=dep_name, + version=version, + defaults={ + "package_manager": pkg_mgr, + "license": lic, + "path": path, + "in_use": True, + }, + ) + dep_map[(dep_name, version)] = dep + if dep_created: + self.stdout.write(f" ✓ Dependency {dep_name}@{version}") + + cve_map: dict[str, CVEObject] = {} + for (cve_id, severity, cvss, epss, desc, + av, ac, pr, ui, ci, ii, ai, scope, url, published) in DEMO_CVES: + cve, cve_created = CVEObject.objects.get_or_create( + cve_id=cve_id, + defaults={ + "base_severity": severity, + "cvss": cvss, + "epss": epss, + "description": desc, + "attack_vector": av, + "attack_complexity": ac, + "privileges_required": pr, + "user_interaction": ui, + "confidentiality_impact": ci, + "integrity_impact": ii, + "availability_impact": ai, + "scope": scope, + "recommended_url": url, + "published": published, + "updated": published, + }, + ) + cve_map[cve_id] = cve + if cve_created: + self.stdout.write(f" ✓ CVE {cve_id}") + + for cve_id, dep_name, dep_version, status, solution, comment in DEMO_REPORTS: + dep = dep_map.get((dep_name, dep_version)) + cve = cve_map.get(cve_id) + if not dep or not cve: + continue + _, report_created = Report.objects.get_or_create( + dependency=dep, + cve_object=cve, + defaults={ + "status": status, + "solution": solution, + "comment": comment, + }, + ) + if report_created: + self.stdout.write(f" ✓ Report {dep_name}@{dep_version} → {cve_id} [{status}]") + + self.stdout.write(self.style.SUCCESS("Preview data seeding complete.")) diff --git a/backend/analyzer/manager/project_manager.py b/backend/analyzer/manager/project_manager.py index 8f06d26..1f3e0a3 100644 --- a/backend/analyzer/manager/project_manager.py +++ b/backend/analyzer/manager/project_manager.py @@ -1,3 +1,4 @@ +import hmac import logging from secrets import token_urlsafe @@ -44,7 +45,7 @@ def verify_key(self, key: str) -> bool: """ try: - if self.project.api_key_hash == hash_key(key): + if hmac.compare_digest(self.project.api_key_hash, hash_key(key)): logging.info( f"Authentication with API-Key for {self.project.project_id} successful.") return True diff --git a/backend/analyzer/migrations/0003_alter_dependency_package_manager_and_more.py b/backend/analyzer/migrations/0003_alter_dependency_package_manager_and_more.py new file mode 100644 index 0000000..ed5196c --- /dev/null +++ b/backend/analyzer/migrations/0003_alter_dependency_package_manager_and_more.py @@ -0,0 +1,33 @@ +# Generated by Django 5.1.2 on 2025-02-10 15:44 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('analyzer', '0002_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='dependency', + name='package_manager', + field=models.CharField(default='NA', max_length=255), + ), + migrations.AlterField( + model_name='project', + name='project_id', + field=models.CharField(max_length=50, unique=True), + ), + migrations.AlterField( + model_name='project', + name='project_name', + field=models.CharField(blank=True, max_length=50), + ), + migrations.AlterField( + model_name='report', + name='overall_cvss_severity', + field=models.CharField(max_length=255, null=True), + ), + ] diff --git a/backend/analyzer/models.py b/backend/analyzer/models.py index 5aa48c5..9f798e2 100644 --- a/backend/analyzer/models.py +++ b/backend/analyzer/models.py @@ -12,8 +12,8 @@ class Project(models.Model): class Meta: db_table = constants.DB_SCHEMA_PREFIX + "project" - project_id = models.CharField(max_length=25, blank=False, unique=True) - project_name = models.CharField(max_length=25, blank=True) + project_id = models.CharField(max_length=50, blank=False, unique=True) + project_name = models.CharField(max_length=50, blank=True) updated = models.DateTimeField(auto_now=True) deployment_threshold = models.CharField(max_length=20, choices=constants.Threshold.choices, diff --git a/backend/analyzer/parser/cyclonedx_parser.py b/backend/analyzer/parser/cyclonedx_parser.py index 4dc7d39..b3769d1 100644 --- a/backend/analyzer/parser/cyclonedx_parser.py +++ b/backend/analyzer/parser/cyclonedx_parser.py @@ -24,10 +24,13 @@ def get_package_manager_name(bom_ref: str): return "NA" -def parse_json(json_data: str) -> dict[str, ParseResult]: +def parse_json(json_data: str or dict) -> dict[str, ParseResult]: try: # deserialize - bom = cast(Bom, Bom.from_json(data=json.loads(json_data))) + if isinstance(json_data, dict): + bom = cast(Bom, Bom.from_json(data=json_data)) + else: + bom = cast(Bom, Bom.from_json(data=json.loads(json_data))) data: dict[str, ParseResult] = {} # key is affected bom-ref and values are vulnerability ids diff --git a/backend/analyzer/parser/trivy_parser.py b/backend/analyzer/parser/trivy_parser.py index ddb3a46..bc7ee90 100644 --- a/backend/analyzer/parser/trivy_parser.py +++ b/backend/analyzer/parser/trivy_parser.py @@ -56,10 +56,12 @@ def parse_json(json_data: str) -> dict[str, ParseResult]: dependency_name = vul.get("PkgName") vul_id = vul.get("VulnerabilityID") - if dependency_name in data: - data.get(dependency_name).vulnerabilities.append(vul_id) + key = f"{dependency_name}:{version}" + if key in data: + if vul_id not in data[key].vulnerabilities: + data[key].vulnerabilities.append(vul_id) else: - data[dependency_name] = ParseResult( + data[key] = ParseResult( dependency_name=dependency_name, version=version, package_manager=package_manager, diff --git a/backend/analyzer/services/cve_fetcher.py b/backend/analyzer/services/cve_fetcher.py index 8fc1c10..61ca856 100644 --- a/backend/analyzer/services/cve_fetcher.py +++ b/backend/analyzer/services/cve_fetcher.py @@ -1,4 +1,5 @@ import logging +import re import time from urllib import parse @@ -11,6 +12,8 @@ logger = logging.getLogger(__name__) +CVE_ID_PATTERN = re.compile(r'^CVE-\d{4}-\d{4,}$') + class CVEFetcher: """ @@ -61,7 +64,12 @@ def __init__(self, cve_id: str): Args: cve_id (str): The CVE identifier to fetch data for. + + Raises: + ValueError: If the cve_id does not match the expected CVE format. """ + if not CVE_ID_PATTERN.match(cve_id): + raise ValueError(f"Invalid CVE ID format: {cve_id}") self.cve_id = cve_id self.data = {} self.successful = False @@ -80,7 +88,7 @@ def fetch_from_nist_gov(self): headers = {"apiKey": NVD_API_KEY} url = parse.urlunparse(NVD_ADDRESS) + self.cve_id logger.info(f"Fetching CVE data from NIST for CVE ID: {self.cve_id} using URL: {url}") - response = requests.get(url, headers=headers) + response = requests.get(url, headers=headers, timeout=30) if response.status_code != 200: logger.warning( @@ -138,7 +146,7 @@ def fetch_epss(self): try: url = parse.urlunparse(EPSS_ADDRESS) + self.cve_id logger.info(f"Fetching EPSS score for CVE ID: {self.cve_id} using URL: {url}") - epss_response = requests.get(url) + epss_response = requests.get(url, timeout=30) if epss_response.status_code != 200: raise RequestException( diff --git a/backend/analyzer/test/conftest.py b/backend/analyzer/test/conftest.py new file mode 100644 index 0000000..76f0f24 --- /dev/null +++ b/backend/analyzer/test/conftest.py @@ -0,0 +1,65 @@ +from unittest.mock import patch + +import pytest + +MOCK_NVD_RESPONSE = { + "vulnerabilities": [ + { + "cve": { + "id": "CVE-2021-44228", + "published": "2025-01-01T00:00:00Z", + "lastModified": "2025-01-01T00:00:00Z", + "descriptions": [{"value": "A test vulnerability description."}], + "metrics": { + "cvssMetricV31": [ + { + "cvssData": { + "baseScore": 7.5, + "baseSeverity": "HIGH", + "attackVector": "NETWORK", + "attackComplexity": "LOW", + "privilegesRequired": "NONE", + "userInteraction": "NONE", + "confidentialityImpact": "HIGH", + "integrityImpact": "NONE", + "availabilityImpact": "NONE", + "scope": "UNCHANGED", + } + } + ] + }, + "weaknesses": [{"description": [{"value": "CWE-94"}]}], + "references": [{"url": "https://example.com/advisory", "tags": ["Vendor Advisory"]}], + } + } + ] +} + +MOCK_EPSS_RESPONSE = {"data": [{"epss": 0.5}]} + + +def _mock_requests_get(url, **kwargs): + class MockResponse: + def __init__(self, json_data, status_code): + self.json_data = json_data + self.status_code = status_code + + def json(self): + return self.json_data + + url_str = str(url) + if "nvd.nist.gov" in url_str: + return MockResponse(MOCK_NVD_RESPONSE, 200) + if "api.first.org" in url_str: + return MockResponse(MOCK_EPSS_RESPONSE, 200) + raise ConnectionError(f"Unexpected request: {url_str}") + + +@pytest.fixture(autouse=True) +def no_nvd_network(request): + if request.node.get_closest_marker("nvd_integration"): + yield + return + with patch("analyzer.services.cve_fetcher.requests.get", side_effect=_mock_requests_get), \ + patch("analyzer.services.cve_fetcher.time.sleep"): + yield diff --git a/backend/analyzer/test/data/cyclonedx-report-securechecknext.json b/backend/analyzer/test/data/cyclonedx-report-securechecknext.json new file mode 100644 index 0000000..346f345 --- /dev/null +++ b/backend/analyzer/test/data/cyclonedx-report-securechecknext.json @@ -0,0 +1,368 @@ +{ + "components": [ + { + "bom-ref": "requirements-L1", + "description": "requirements line 1: Django==5.1.2", + "externalReferences": [ + { + "comment": "implicit dist url", + "type": "distribution", + "url": "https://pypi.org/simple/Django/" + } + ], + "name": "Django", + "purl": "pkg:pypi/django@5.1.2", + "type": "library", + "version": "5.1.2" + }, + { + "bom-ref": "requirements-L11", + "description": "requirements line 11: coverage==7.6.4", + "externalReferences": [ + { + "comment": "implicit dist url", + "type": "distribution", + "url": "https://pypi.org/simple/coverage/" + } + ], + "name": "coverage", + "purl": "pkg:pypi/coverage@7.6.4", + "type": "library", + "version": "7.6.4" + }, + { + "bom-ref": "requirements-L13", + "description": "requirements line 13: cyclonedx-python-lib==8.2.1", + "externalReferences": [ + { + "comment": "implicit dist url", + "type": "distribution", + "url": "https://pypi.org/simple/cyclonedx-python-lib/" + } + ], + "name": "cyclonedx-python-lib", + "purl": "pkg:pypi/cyclonedx-python-lib@8.2.1", + "type": "library", + "version": "8.2.1" + }, + { + "bom-ref": "requirements-L2", + "description": "requirements line 2: django-cors-headers==4.5.0", + "externalReferences": [ + { + "comment": "implicit dist url", + "type": "distribution", + "url": "https://pypi.org/simple/django-cors-headers/" + } + ], + "name": "django-cors-headers", + "purl": "pkg:pypi/django-cors-headers@4.5.0", + "type": "library", + "version": "4.5.0" + }, + { + "bom-ref": "requirements-L3", + "description": "requirements line 3: djangorestframework==3.15.2", + "externalReferences": [ + { + "comment": "implicit dist url", + "type": "distribution", + "url": "https://pypi.org/simple/djangorestframework/" + } + ], + "name": "djangorestframework", + "purl": "pkg:pypi/djangorestframework@3.15.2", + "type": "library", + "version": "3.15.2" + }, + { + "bom-ref": "requirements-L12", + "description": "requirements line 12: gunicorn==23.0.0", + "externalReferences": [ + { + "comment": "implicit dist url", + "type": "distribution", + "url": "https://pypi.org/simple/gunicorn/" + } + ], + "name": "gunicorn", + "purl": "pkg:pypi/gunicorn@23.0.0", + "type": "library", + "version": "23.0.0" + }, + { + "bom-ref": "requirements-L5", + "description": "requirements line 5: ldap3==2.9.1", + "externalReferences": [ + { + "comment": "implicit dist url", + "type": "distribution", + "url": "https://pypi.org/simple/ldap3/" + } + ], + "name": "ldap3", + "purl": "pkg:pypi/ldap3@2.9.1", + "type": "library", + "version": "2.9.1" + }, + { + "bom-ref": "requirements-L4", + "description": "requirements line 4: lxml==5.3.0", + "externalReferences": [ + { + "comment": "implicit dist url", + "type": "distribution", + "url": "https://pypi.org/simple/lxml/" + } + ], + "name": "lxml", + "purl": "pkg:pypi/lxml@5.3.0", + "type": "library", + "version": "5.3.0" + }, + { + "bom-ref": "requirements-L6", + "description": "requirements line 6: psycopg2-binary==2.9.10", + "externalReferences": [ + { + "comment": "implicit dist url", + "type": "distribution", + "url": "https://pypi.org/simple/psycopg2-binary/" + } + ], + "name": "psycopg2-binary", + "purl": "pkg:pypi/psycopg2-binary@2.9.10", + "type": "library", + "version": "2.9.10" + }, + { + "bom-ref": "requirements-L7", + "description": "requirements line 7: pytest==8.3.3", + "externalReferences": [ + { + "comment": "implicit dist url", + "type": "distribution", + "url": "https://pypi.org/simple/pytest/" + } + ], + "name": "pytest", + "purl": "pkg:pypi/pytest@8.3.3", + "type": "library", + "version": "8.3.3" + }, + { + "bom-ref": "requirements-L8", + "description": "requirements line 8: pytest-django==4.9.0", + "externalReferences": [ + { + "comment": "implicit dist url", + "type": "distribution", + "url": "https://pypi.org/simple/pytest-django/" + } + ], + "name": "pytest-django", + "purl": "pkg:pypi/pytest-django@4.9.0", + "type": "library", + "version": "4.9.0" + }, + { + "bom-ref": "requirements-L9", + "description": "requirements line 9: python-dotenv==1.0.1", + "externalReferences": [ + { + "comment": "implicit dist url", + "type": "distribution", + "url": "https://pypi.org/simple/python-dotenv/" + } + ], + "name": "python-dotenv", + "purl": "pkg:pypi/python-dotenv@1.0.1", + "type": "library", + "version": "1.0.1" + }, + { + "bom-ref": "requirements-L10", + "description": "requirements line 10: requests==2.32.3", + "externalReferences": [ + { + "comment": "implicit dist url", + "type": "distribution", + "url": "https://pypi.org/simple/requests/" + } + ], + "name": "requests", + "purl": "pkg:pypi/requests@2.32.3", + "type": "library", + "version": "2.32.3" + }, + { + "bom-ref": "requirements-L14", + "description": "requirements line 14: whitenoise==6.7.0", + "externalReferences": [ + { + "comment": "implicit dist url", + "type": "distribution", + "url": "https://pypi.org/simple/whitenoise/" + } + ], + "name": "whitenoise", + "purl": "pkg:pypi/whitenoise@6.7.0", + "type": "library", + "version": "6.7.0" + } + ], + "dependencies": [ + { + "ref": "requirements-L1" + }, + { + "ref": "requirements-L10" + }, + { + "ref": "requirements-L11" + }, + { + "ref": "requirements-L12" + }, + { + "ref": "requirements-L13" + }, + { + "ref": "requirements-L14" + }, + { + "ref": "requirements-L2" + }, + { + "ref": "requirements-L3" + }, + { + "ref": "requirements-L4" + }, + { + "ref": "requirements-L5" + }, + { + "ref": "requirements-L6" + }, + { + "ref": "requirements-L7" + }, + { + "ref": "requirements-L8" + }, + { + "ref": "requirements-L9" + } + ], + "metadata": { + "timestamp": "2026-06-26T21:30:13.200441+00:00", + "tools": { + "components": [ + { + "description": "CycloneDX Software Bill of Materials (SBOM) generator for Python projects and environments", + "externalReferences": [ + { + "type": "build-system", + "url": "https://github.com/CycloneDX/cyclonedx-python/actions" + }, + { + "type": "distribution", + "url": "https://pypi.org/project/cyclonedx-bom/" + }, + { + "type": "documentation", + "url": "https://cyclonedx-bom-tool.readthedocs.io/" + }, + { + "type": "issue-tracker", + "url": "https://github.com/CycloneDX/cyclonedx-python/issues" + }, + { + "type": "license", + "url": "https://github.com/CycloneDX/cyclonedx-python/blob/main/LICENSE" + }, + { + "type": "release-notes", + "url": "https://github.com/CycloneDX/cyclonedx-python/blob/main/CHANGELOG.md" + }, + { + "type": "vcs", + "url": "https://github.com/CycloneDX/cyclonedx-python/" + }, + { + "type": "website", + "url": "https://github.com/CycloneDX/cyclonedx-python/#readme" + } + ], + "group": "CycloneDX", + "licenses": [ + { + "license": { + "acknowledgement": "declared", + "id": "Apache-2.0" + } + } + ], + "name": "cyclonedx-py", + "type": "application", + "version": "7.3.0" + }, + { + "description": "Python library for CycloneDX", + "externalReferences": [ + { + "type": "build-system", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions" + }, + { + "type": "distribution", + "url": "https://pypi.org/project/cyclonedx-python-lib/" + }, + { + "type": "documentation", + "url": "https://cyclonedx-python-library.readthedocs.io/" + }, + { + "type": "issue-tracker", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues" + }, + { + "type": "license", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE" + }, + { + "type": "release-notes", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md" + }, + { + "type": "vcs", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib" + }, + { + "type": "website", + "url": "https://github.com/CycloneDX/cyclonedx-python-lib/#readme" + } + ], + "group": "CycloneDX", + "licenses": [ + { + "license": { + "acknowledgement": "declared", + "id": "Apache-2.0" + } + } + ], + "name": "cyclonedx-python-lib", + "type": "library", + "version": "8.2.1" + } + ] + } + }, + "serialNumber": "urn:uuid:41ae51fa-2fcb-48c6-a450-806e78ea274e", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.6.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.6" +} \ No newline at end of file diff --git a/backend/analyzer/test/data/trivy-report-securechecknext.json b/backend/analyzer/test/data/trivy-report-securechecknext.json new file mode 100644 index 0000000..90eefe2 --- /dev/null +++ b/backend/analyzer/test/data/trivy-report-securechecknext.json @@ -0,0 +1,8690 @@ +{ + "SchemaVersion": 2, + "Trivy": { + "Version": "0.71.2" + }, + "ReportID": "019f05d6-de2b-7856-b9f8-7917b78b0d8a", + "CreatedAt": "2026-06-26T18:29:55.499549413-03:00", + "ArtifactID": "sha256:8f6f8f46bb2fbf9871de2f2d3ca183ffa9fce75166210cdc0117029b66cec6bb", + "ArtifactName": ".", + "ArtifactType": "repository", + "Metadata": { + "RepoURL": "https://github.com/accso/SecureCheckPlus.git", + "Branch": "clean-history", + "Commit": "346406058d75e90bc0b082364ee0293119a538e3", + "CommitMsg": "chore: attribute CSP dicebear fix to upstream PR #45 (Niklas Büchel)\n\nUpstream PR #45 by Niklas Büchel fixed the profile picture\nloading error in production by adding api.dicebear.com to\nthe Content Security Policy img-src list. Our clean-history\nalready contains equivalent content (in 12d0589 and prior)\nwhich removed the dicebear.com URL entirely from the frontend\nin favor of local avatar generation.\n\nThis empty commit preserves author attribution to Niklas Büchel.\n\nOriginal commit: b77c8bc (Fix profile picture loading error in production)\nUpstream PR: accso/SecureCheckPlus#45\nFixes: accso/SecureCheckPlus#22\n\nCo-authored-by: Niklas Büchel \u003cniklas.buechel@accso.de\u003e", + "Author": "xMinhx \u003c55718218+xMinhx@users.noreply.github.com\u003e", + "Committer": "xMinhx \u003c55718218+xMinhx@users.noreply.github.com\u003e" + }, + "Results": [ + { + "Target": ".opencode/package-lock.json", + "Class": "lang-pkgs", + "Type": "npm", + "Packages": [ + { + "ID": "@opencode-ai/plugin@1.17.9", + "Name": "@opencode-ai/plugin", + "Identifier": { + "PURL": "pkg:npm/%40opencode-ai/plugin@1.17.9", + "UID": "6261b61793047bca" + }, + "Version": "1.17.9", + "Licenses": [ + "MIT" + ], + "Relationship": "direct", + "DependsOn": [ + "@opencode-ai/sdk@1.17.9", + "effect@4.0.0-beta.74", + "zod@4.1.8" + ], + "Locations": [ + { + "StartLine": 89, + "EndLine": 115 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.4", + "Name": "@msgpackr-extract/msgpackr-extract-darwin-arm64", + "Identifier": { + "PURL": "pkg:npm/%40msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.4", + "UID": "3434a8004a1f0a37" + }, + "Version": "3.0.4", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 11, + "EndLine": 23 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.4", + "Name": "@msgpackr-extract/msgpackr-extract-darwin-x64", + "Identifier": { + "PURL": "pkg:npm/%40msgpackr-extract/msgpackr-extract-darwin-x64@3.0.4", + "UID": "bc6fe24fe044f30a" + }, + "Version": "3.0.4", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 24, + "EndLine": 36 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@msgpackr-extract/msgpackr-extract-linux-arm@3.0.4", + "Name": "@msgpackr-extract/msgpackr-extract-linux-arm", + "Identifier": { + "PURL": "pkg:npm/%40msgpackr-extract/msgpackr-extract-linux-arm@3.0.4", + "UID": "6bc87c4bab335473" + }, + "Version": "3.0.4", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 37, + "EndLine": 49 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.4", + "Name": "@msgpackr-extract/msgpackr-extract-linux-arm64", + "Identifier": { + "PURL": "pkg:npm/%40msgpackr-extract/msgpackr-extract-linux-arm64@3.0.4", + "UID": "b0ce86bbd91d7548" + }, + "Version": "3.0.4", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 50, + "EndLine": 62 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@msgpackr-extract/msgpackr-extract-linux-x64@3.0.4", + "Name": "@msgpackr-extract/msgpackr-extract-linux-x64", + "Identifier": { + "PURL": "pkg:npm/%40msgpackr-extract/msgpackr-extract-linux-x64@3.0.4", + "UID": "e78baf098a459fe7" + }, + "Version": "3.0.4", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 63, + "EndLine": 75 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@msgpackr-extract/msgpackr-extract-win32-x64@3.0.4", + "Name": "@msgpackr-extract/msgpackr-extract-win32-x64", + "Identifier": { + "PURL": "pkg:npm/%40msgpackr-extract/msgpackr-extract-win32-x64@3.0.4", + "UID": "4df84e3856bfbf79" + }, + "Version": "3.0.4", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 76, + "EndLine": 88 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@opencode-ai/sdk@1.17.9", + "Name": "@opencode-ai/sdk", + "Identifier": { + "PURL": "pkg:npm/%40opencode-ai/sdk@1.17.9", + "UID": "4cd9091966272c8d" + }, + "Version": "1.17.9", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "cross-spawn@7.0.6" + ], + "Locations": [ + { + "StartLine": 116, + "EndLine": 124 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@standard-schema/spec@1.1.0", + "Name": "@standard-schema/spec", + "Identifier": { + "PURL": "pkg:npm/%40standard-schema/spec@1.1.0", + "UID": "6e4a42c55340e205" + }, + "Version": "1.1.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 125, + "EndLine": 130 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "cross-spawn@7.0.6", + "Name": "cross-spawn", + "Identifier": { + "PURL": "pkg:npm/cross-spawn@7.0.6", + "UID": "b9486b99b9858813" + }, + "Version": "7.0.6", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "path-key@3.1.1", + "shebang-command@2.0.0", + "which@2.0.2" + ], + "Locations": [ + { + "StartLine": 131, + "EndLine": 144 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "detect-libc@2.1.2", + "Name": "detect-libc", + "Identifier": { + "PURL": "pkg:npm/detect-libc@2.1.2", + "UID": "5a08cd0ddb7e51e5" + }, + "Version": "2.1.2", + "Licenses": [ + "Apache-2.0" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 145, + "EndLine": 154 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "effect@4.0.0-beta.74", + "Name": "effect", + "Identifier": { + "PURL": "pkg:npm/effect@4.0.0-beta.74", + "UID": "5ae915c84aa25534" + }, + "Version": "4.0.0-beta.74", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@standard-schema/spec@1.1.0", + "fast-check@4.8.0", + "find-my-way-ts@0.1.6", + "ini@7.0.0", + "kubernetes-types@1.30.0", + "msgpackr@2.0.4", + "multipasta@0.2.7", + "toml@4.1.1", + "uuid@14.0.1", + "yaml@2.9.0" + ], + "Locations": [ + { + "StartLine": 155, + "EndLine": 172 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "fast-check@4.8.0", + "Name": "fast-check", + "Identifier": { + "PURL": "pkg:npm/fast-check@4.8.0", + "UID": "35c635c8183bb988" + }, + "Version": "4.8.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "pure-rand@8.4.0" + ], + "Locations": [ + { + "StartLine": 173, + "EndLine": 194 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "find-my-way-ts@0.1.6", + "Name": "find-my-way-ts", + "Identifier": { + "PURL": "pkg:npm/find-my-way-ts@0.1.6", + "UID": "e4f8bddb9c7d03b6" + }, + "Version": "0.1.6", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 195, + "EndLine": 200 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "ini@7.0.0", + "Name": "ini", + "Identifier": { + "PURL": "pkg:npm/ini@7.0.0", + "UID": "ca16252f9efd2bc2" + }, + "Version": "7.0.0", + "Licenses": [ + "ISC" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 201, + "EndLine": 209 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "isexe@2.0.0", + "Name": "isexe", + "Identifier": { + "PURL": "pkg:npm/isexe@2.0.0", + "UID": "6835ea1f9f384256" + }, + "Version": "2.0.0", + "Licenses": [ + "ISC" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 210, + "EndLine": 215 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "kubernetes-types@1.30.0", + "Name": "kubernetes-types", + "Identifier": { + "PURL": "pkg:npm/kubernetes-types@1.30.0", + "UID": "c54d187390bc22a1" + }, + "Version": "1.30.0", + "Licenses": [ + "Apache-2.0" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 216, + "EndLine": 221 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "msgpackr@2.0.4", + "Name": "msgpackr", + "Identifier": { + "PURL": "pkg:npm/msgpackr@2.0.4", + "UID": "ada2ded33fbe21a7" + }, + "Version": "2.0.4", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "msgpackr-extract@3.0.4" + ], + "Locations": [ + { + "StartLine": 222, + "EndLine": 230 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "msgpackr-extract@3.0.4", + "Name": "msgpackr-extract", + "Identifier": { + "PURL": "pkg:npm/msgpackr-extract@3.0.4", + "UID": "8899cf4afc5e118d" + }, + "Version": "3.0.4", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.4", + "@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.4", + "@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.4", + "@msgpackr-extract/msgpackr-extract-linux-arm@3.0.4", + "@msgpackr-extract/msgpackr-extract-linux-x64@3.0.4", + "@msgpackr-extract/msgpackr-extract-win32-x64@3.0.4", + "node-gyp-build-optional-packages@5.2.2" + ], + "Locations": [ + { + "StartLine": 231, + "EndLine": 252 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "multipasta@0.2.7", + "Name": "multipasta", + "Identifier": { + "PURL": "pkg:npm/multipasta@0.2.7", + "UID": "65c7a8e7c30097ed" + }, + "Version": "0.2.7", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 253, + "EndLine": 258 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "node-gyp-build-optional-packages@5.2.2", + "Name": "node-gyp-build-optional-packages", + "Identifier": { + "PURL": "pkg:npm/node-gyp-build-optional-packages@5.2.2", + "UID": "34b15fe3aa4f9a40" + }, + "Version": "5.2.2", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "detect-libc@2.1.2" + ], + "Locations": [ + { + "StartLine": 259, + "EndLine": 273 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "path-key@3.1.1", + "Name": "path-key", + "Identifier": { + "PURL": "pkg:npm/path-key@3.1.1", + "UID": "4f69b6a9ea3ba2f7" + }, + "Version": "3.1.1", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 274, + "EndLine": 282 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "pure-rand@8.4.0", + "Name": "pure-rand", + "Identifier": { + "PURL": "pkg:npm/pure-rand@8.4.0", + "UID": "14e6b6b9e524feca" + }, + "Version": "8.4.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 283, + "EndLine": 298 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "shebang-command@2.0.0", + "Name": "shebang-command", + "Identifier": { + "PURL": "pkg:npm/shebang-command@2.0.0", + "UID": "ce5be11015eb82e8" + }, + "Version": "2.0.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "shebang-regex@3.0.0" + ], + "Locations": [ + { + "StartLine": 299, + "EndLine": 310 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "shebang-regex@3.0.0", + "Name": "shebang-regex", + "Identifier": { + "PURL": "pkg:npm/shebang-regex@3.0.0", + "UID": "faec7e5cb9ae7620" + }, + "Version": "3.0.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 311, + "EndLine": 319 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "toml@4.1.1", + "Name": "toml", + "Identifier": { + "PURL": "pkg:npm/toml@4.1.1", + "UID": "bcd2ef00a85351c" + }, + "Version": "4.1.1", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 320, + "EndLine": 328 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "uuid@14.0.1", + "Name": "uuid", + "Identifier": { + "PURL": "pkg:npm/uuid@14.0.1", + "UID": "64ef12711a7aae74" + }, + "Version": "14.0.1", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 329, + "EndLine": 341 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "which@2.0.2", + "Name": "which", + "Identifier": { + "PURL": "pkg:npm/which@2.0.2", + "UID": "8e7e9bcd2b90e8e0" + }, + "Version": "2.0.2", + "Licenses": [ + "ISC" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "isexe@2.0.0" + ], + "Locations": [ + { + "StartLine": 342, + "EndLine": 356 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "yaml@2.9.0", + "Name": "yaml", + "Identifier": { + "PURL": "pkg:npm/yaml@2.9.0", + "UID": "a9d99c97c5e7ec58" + }, + "Version": "2.9.0", + "Licenses": [ + "ISC" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 357, + "EndLine": 371 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "zod@4.1.8", + "Name": "zod", + "Identifier": { + "PURL": "pkg:npm/zod@4.1.8", + "UID": "40b9edc2449b6a32" + }, + "Version": "4.1.8", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 372, + "EndLine": 380 + } + ], + "AnalyzedBy": "npm" + } + ] + }, + { + "Target": "adapter/adapter/requirements.txt", + "Class": "lang-pkgs", + "Type": "pip", + "Packages": [ + { + "Name": "requests", + "Identifier": { + "PURL": "pkg:pypi/requests@2.32.3", + "UID": "65469ec61108dd0c" + }, + "Version": "2.32.3", + "Locations": [ + { + "StartLine": 1, + "EndLine": 1 + } + ], + "AnalyzedBy": "pip" + } + ], + "Vulnerabilities": [ + { + "VulnerabilityID": "CVE-2024-47081", + "VendorIDs": [ + "GHSA-9hjg-9r4m-mvj7" + ], + "PkgName": "requests", + "PkgIdentifier": { + "PURL": "pkg:pypi/requests@2.32.3", + "UID": "65469ec61108dd0c" + }, + "InstalledVersion": "2.32.3", + "FixedVersion": "2.32.4", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2024-47081", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory pip", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Apip" + }, + "Fingerprint": "sha256:65c332dafc6dc969c7db3f34ba77a836ca27704a902d29bd8ba6f0a82ee7b3d2", + "Title": "requests: Requests vulnerable to .netrc credentials leak via malicious URLs", + "Description": "Requests is a HTTP library. Due to a URL parsing issue, Requests releases prior to 2.32.4 may leak .netrc credentials to third parties for specific maliciously-crafted URLs. Users should upgrade to version 2.32.4 to receive a fix. For older versions of Requests, use of the .netrc file can be disabled with `trust_env=False` on one's Requests Session.", + "Severity": "MEDIUM", + "CweIDs": [ + "CWE-522" + ], + "VendorSeverity": { + "alma": 2, + "amazon": 2, + "azure": 2, + "cbl-mariner": 2, + "ghsa": 2, + "oracle-oval": 2, + "photon": 2, + "redhat": 2, + "rocky": 2, + "ubuntu": 2 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:N/A:N", + "V3Score": 5.3 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:N/A:N", + "V3Score": 5.3 + } + }, + "References": [ + "http://seclists.org/fulldisclosure/2025/Jun/2", + "http://www.openwall.com/lists/oss-security/2025/06/03/11", + "http://www.openwall.com/lists/oss-security/2025/06/03/9", + "http://www.openwall.com/lists/oss-security/2025/06/04/1", + "http://www.openwall.com/lists/oss-security/2025/06/04/6", + "https://access.redhat.com/errata/RHSA-2025:12519", + "https://access.redhat.com/security/cve/CVE-2024-47081", + "https://bugzilla.redhat.com/2371272", + "https://bugzilla.redhat.com/show_bug.cgi?id=2371272", + "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-47081", + "https://errata.almalinux.org/9/ALSA-2025-12519.html", + "https://errata.rockylinux.org/RLSA-2025:13234", + "https://github.com/psf/requests", + "https://github.com/psf/requests/commit/96ba401c1296ab1dda74a2365ef36d88f7d144ef", + "https://github.com/psf/requests/pull/6965", + "https://github.com/psf/requests/security/advisories/GHSA-9hjg-9r4m-mvj7", + "https://linux.oracle.com/cve/CVE-2024-47081.html", + "https://linux.oracle.com/errata/ELSA-2025-14999.html", + "https://nvd.nist.gov/vuln/detail/CVE-2024-47081", + "https://requests.readthedocs.io/en/latest/api/#requests.Session.trust_env", + "https://seclists.org/fulldisclosure/2025/Jun/2", + "https://ubuntu.com/security/notices/USN-7568-1", + "https://ubuntu.com/security/notices/USN-7762-1", + "https://www.cve.org/CVERecord?id=CVE-2024-47081", + "https://www.openwall.com/lists/oss-security/2025/06/03/9" + ], + "PublishedDate": "2025-06-09T18:15:24.983Z", + "LastModifiedDate": "2026-06-17T07:56:30.697Z" + }, + { + "VulnerabilityID": "CVE-2026-25645", + "VendorIDs": [ + "GHSA-gc5v-m9x4-r6x2" + ], + "PkgName": "requests", + "PkgIdentifier": { + "PURL": "pkg:pypi/requests@2.32.3", + "UID": "65469ec61108dd0c" + }, + "InstalledVersion": "2.32.3", + "FixedVersion": "2.33.0", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2026-25645", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory pip", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Apip" + }, + "Fingerprint": "sha256:893044e529466655a8d7d08376611eeb0ce8a0f98785f924c9172e4be1d4006a", + "Title": "requests: Requests: Security bypass due to predictable temporary file creation", + "Description": "Requests is a HTTP library. Prior to version 2.33.0, the `requests.utils.extract_zipped_paths()` utility function uses a predictable filename when extracting files from zip archives into the system temporary directory. If the target file already exists, it is reused without validation. A local attacker with write access to the temp directory could pre-create a malicious file that would be loaded in place of the legitimate one. Standard usage of the Requests library is not affected by this vulnerability. Only applications that call `extract_zipped_paths()` directly are impacted. Starting in version 2.33.0, the library extracts files to a non-deterministic location. If developers are unable to upgrade, they can set `TMPDIR` in their environment to a directory with restricted write access.", + "Severity": "MEDIUM", + "CweIDs": [ + "CWE-377" + ], + "VendorSeverity": { + "azure": 2, + "ghsa": 2, + "nvd": 2, + "photon": 2, + "redhat": 2 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:L/AC:H/PR:L/UI:R/S:U/C:N/I:H/A:N", + "V3Score": 4.4 + }, + "nvd": { + "V3Vector": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N", + "V3Score": 5.5 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:H/A:N", + "V3Score": 4.7 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2026-25645", + "https://github.com/psf/requests", + "https://github.com/psf/requests/commit/66d21cb07bd6255b1280291c4fafb71803cdb3b7", + "https://github.com/psf/requests/releases/tag/v2.33.0", + "https://github.com/psf/requests/security/advisories/GHSA-gc5v-m9x4-r6x2", + "https://nvd.nist.gov/vuln/detail/CVE-2026-25645", + "https://www.cve.org/CVERecord?id=CVE-2026-25645" + ], + "PublishedDate": "2026-03-25T17:16:52.97Z", + "LastModifiedDate": "2026-06-17T10:25:00.443Z" + } + ] + }, + { + "Target": "backend/requirements.txt", + "Class": "lang-pkgs", + "Type": "pip", + "Packages": [ + { + "Name": "Django", + "Identifier": { + "PURL": "pkg:pypi/django@5.1.2", + "UID": "dcc48896f46aa13d" + }, + "Version": "5.1.2", + "Locations": [ + { + "StartLine": 1, + "EndLine": 1 + } + ], + "AnalyzedBy": "pip" + }, + { + "Name": "coverage", + "Identifier": { + "PURL": "pkg:pypi/coverage@7.6.4", + "UID": "3c031366654801ea" + }, + "Version": "7.6.4", + "Locations": [ + { + "StartLine": 11, + "EndLine": 11 + } + ], + "AnalyzedBy": "pip" + }, + { + "Name": "cyclonedx-python-lib", + "Identifier": { + "PURL": "pkg:pypi/cyclonedx-python-lib@8.2.1", + "UID": "15fe40be65c764b2" + }, + "Version": "8.2.1", + "Locations": [ + { + "StartLine": 13, + "EndLine": 13 + } + ], + "AnalyzedBy": "pip" + }, + { + "Name": "django-cors-headers", + "Identifier": { + "PURL": "pkg:pypi/django-cors-headers@4.5.0", + "UID": "cf845cc698aea386" + }, + "Version": "4.5.0", + "Locations": [ + { + "StartLine": 2, + "EndLine": 2 + } + ], + "AnalyzedBy": "pip" + }, + { + "Name": "djangorestframework", + "Identifier": { + "PURL": "pkg:pypi/djangorestframework@3.15.2", + "UID": "50e65f76d8a785b" + }, + "Version": "3.15.2", + "Locations": [ + { + "StartLine": 3, + "EndLine": 3 + } + ], + "AnalyzedBy": "pip" + }, + { + "Name": "gunicorn", + "Identifier": { + "PURL": "pkg:pypi/gunicorn@23.0.0", + "UID": "fea2baf10f59cdcd" + }, + "Version": "23.0.0", + "Locations": [ + { + "StartLine": 12, + "EndLine": 12 + } + ], + "AnalyzedBy": "pip" + }, + { + "Name": "ldap3", + "Identifier": { + "PURL": "pkg:pypi/ldap3@2.9.1", + "UID": "45b1ed1edc056da6" + }, + "Version": "2.9.1", + "Locations": [ + { + "StartLine": 5, + "EndLine": 5 + } + ], + "AnalyzedBy": "pip" + }, + { + "Name": "lxml", + "Identifier": { + "PURL": "pkg:pypi/lxml@5.3.0", + "UID": "81c5b0c899da3408" + }, + "Version": "5.3.0", + "Locations": [ + { + "StartLine": 4, + "EndLine": 4 + } + ], + "AnalyzedBy": "pip" + }, + { + "Name": "psycopg2-binary", + "Identifier": { + "PURL": "pkg:pypi/psycopg2-binary@2.9.10", + "UID": "dbc72f733212e97b" + }, + "Version": "2.9.10", + "Locations": [ + { + "StartLine": 6, + "EndLine": 6 + } + ], + "AnalyzedBy": "pip" + }, + { + "Name": "pytest", + "Identifier": { + "PURL": "pkg:pypi/pytest@8.3.3", + "UID": "9d504b1ef2a92265" + }, + "Version": "8.3.3", + "Locations": [ + { + "StartLine": 7, + "EndLine": 7 + } + ], + "AnalyzedBy": "pip" + }, + { + "Name": "pytest-django", + "Identifier": { + "PURL": "pkg:pypi/pytest-django@4.9.0", + "UID": "e419c6b053f5be84" + }, + "Version": "4.9.0", + "Locations": [ + { + "StartLine": 8, + "EndLine": 8 + } + ], + "AnalyzedBy": "pip" + }, + { + "Name": "python-dotenv", + "Identifier": { + "PURL": "pkg:pypi/python-dotenv@1.0.1", + "UID": "da168a05e25283ab" + }, + "Version": "1.0.1", + "Locations": [ + { + "StartLine": 9, + "EndLine": 9 + } + ], + "AnalyzedBy": "pip" + }, + { + "Name": "requests", + "Identifier": { + "PURL": "pkg:pypi/requests@2.32.3", + "UID": "c15ff9e490806b50" + }, + "Version": "2.32.3", + "Locations": [ + { + "StartLine": 10, + "EndLine": 10 + } + ], + "AnalyzedBy": "pip" + }, + { + "Name": "whitenoise", + "Identifier": { + "PURL": "pkg:pypi/whitenoise@6.7.0", + "UID": "f5045fe6122d9157" + }, + "Version": "6.7.0", + "Locations": [ + { + "StartLine": 14, + "EndLine": 14 + } + ], + "AnalyzedBy": "pip" + } + ], + "Vulnerabilities": [ + { + "VulnerabilityID": "CVE-2025-64459", + "VendorIDs": [ + "GHSA-frmv-pr5f-9mcr" + ], + "PkgName": "Django", + "PkgIdentifier": { + "PURL": "pkg:pypi/django@5.1.2", + "UID": "dcc48896f46aa13d" + }, + "InstalledVersion": "5.1.2", + "FixedVersion": "5.2.8, 5.1.14, 4.2.26", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2025-64459", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory pip", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Apip" + }, + "Fingerprint": "sha256:a277909e64b04da46bfd0c3db8564003dd0351641b07098f9e5e7a07910e4779", + "Title": "django: Django SQL injection", + "Description": "An issue was discovered in 5.1 before 5.1.14, 4.2 before 4.2.26, and 5.2 before 5.2.8.\nThe methods `QuerySet.filter()`, `QuerySet.exclude()`, and `QuerySet.get()`, and the class `Q()`, are subject to SQL injection when using a suitably crafted dictionary, with dictionary expansion, as the `_connector` argument.\nEarlier, unsupported Django series (such as 5.0.x, 4.1.x, and 3.2.x) were not evaluated and may also be affected.\nDjango would like to thank cyberstan for reporting this issue.", + "Severity": "CRITICAL", + "CweIDs": [ + "CWE-89" + ], + "VendorSeverity": { + "bitnami": 4, + "ghsa": 4, + "redhat": 3, + "ubuntu": 2 + }, + "CVSS": { + "bitnami": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N", + "V3Score": 9.1 + }, + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N", + "V3Score": 9.1 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:L", + "V3Score": 8.3 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2025-64459", + "https://docs.djangoproject.com/en/dev/releases/security", + "https://docs.djangoproject.com/en/dev/releases/security/", + "https://github.com/django/django", + "https://github.com/django/django/commit/06dd38324ac3d60d83d9f3adabf0dcdf423d2a85", + "https://github.com/django/django/commit/59ae82e67053d281ff4562a24bbba21299f0a7d4", + "https://github.com/django/django/commit/6703f364d767e949c5b0e4016433ef75063b4f9b", + "https://github.com/django/django/commit/72d2c87431f2ae0431d65d0ec792047f078c8241", + "https://github.com/django/django/commit/c880530ddd4fabd5939bab0e148bebe36699432a", + "https://github.com/omarkurt/django-connector-CVE-2025-64459-testbed", + "https://github.com/pypa/advisory-database/tree/main/vulns/django/PYSEC-2025-108.yaml", + "https://groups.google.com/g/django-announce", + "https://nvd.nist.gov/vuln/detail/CVE-2025-64459", + "https://shivasurya.me/security/django/2025/11/07/django-sql-injection-CVE-2025-64459.html", + "https://ubuntu.com/security/notices/USN-7859-1", + "https://www.cve.org/CVERecord?id=CVE-2025-64459", + "https://www.djangoproject.com/weblog/2025/nov/05/security-releases", + "https://www.djangoproject.com/weblog/2025/nov/05/security-releases/" + ], + "PublishedDate": "2025-11-05T15:15:41.08Z", + "LastModifiedDate": "2026-06-17T09:54:24.473Z" + }, + { + "VulnerabilityID": "CVE-2024-53908", + "VendorIDs": [ + "GHSA-m9g8-fxxm-xg86" + ], + "PkgName": "Django", + "PkgIdentifier": { + "PURL": "pkg:pypi/django@5.1.2", + "UID": "dcc48896f46aa13d" + }, + "InstalledVersion": "5.1.2", + "FixedVersion": "5.0.10, 5.1.4, 4.2.17", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2024-53908", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory pip", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Apip" + }, + "Fingerprint": "sha256:805fc6df6daf9818fa44ad2ce0012075a41b51ad202c13ca43db0bc6f1227e42", + "Title": "django: Potential SQL injection in HasKey(lhs, rhs) on Oracle", + "Description": "An issue was discovered in Django 5.1 before 5.1.4, 5.0 before 5.0.10, and 4.2 before 4.2.17. Direct usage of the django.db.models.fields.json.HasKey lookup, when an Oracle database is used, is subject to SQL injection if untrusted data is used as an lhs value. (Applications that use the jsonfield.has_key lookup via __ are unaffected.)", + "Severity": "HIGH", + "CweIDs": [ + "CWE-89" + ], + "VendorSeverity": { + "bitnami": 4, + "ghsa": 3, + "redhat": 3, + "ubuntu": 2 + }, + "CVSS": { + "bitnami": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", + "V3Score": 9.8 + }, + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", + "V40Vector": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:U", + "V3Score": 9.8, + "V40Score": 7.2 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N", + "V3Score": 9.1 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2024-53908", + "https://docs.djangoproject.com/en/dev/releases/security", + "https://docs.djangoproject.com/en/dev/releases/security/", + "https://github.com/django/django", + "https://github.com/pypa/advisory-database/tree/main/vulns/django/PYSEC-2024-157.yaml", + "https://groups.google.com/g/django-announce", + "https://nvd.nist.gov/vuln/detail/CVE-2024-53908", + "https://ubuntu.com/security/notices/USN-7136-1", + "https://www.cve.org/CVERecord?id=CVE-2024-53908", + "https://www.djangoproject.com/weblog/2024/dec/04/security-releases", + "https://www.djangoproject.com/weblog/2024/dec/04/security-releases/", + "https://www.openwall.com/lists/oss-security/2024/12/04/3" + ], + "PublishedDate": "2024-12-06T12:15:18.583Z", + "LastModifiedDate": "2026-06-17T08:09:28.87Z" + }, + { + "VulnerabilityID": "CVE-2025-57833", + "VendorIDs": [ + "GHSA-6w2r-r2m5-xq5w" + ], + "PkgName": "Django", + "PkgIdentifier": { + "PURL": "pkg:pypi/django@5.1.2", + "UID": "dcc48896f46aa13d" + }, + "InstalledVersion": "5.1.2", + "FixedVersion": "4.2.24, 5.1.12, 5.2.6", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2025-57833", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory pip", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Apip" + }, + "Fingerprint": "sha256:1559cc5fa53b7faf4498a72236697a494a5ff05c3bd1abefe35de79309fa228f", + "Title": "django: Django SQL injection in FilteredRelation column aliases", + "Description": "An issue was discovered in Django 4.2 before 4.2.24, 5.1 before 5.1.12, and 5.2 before 5.2.6. FilteredRelation is subject to SQL injection in column aliases, using a suitably crafted dictionary, with dictionary expansion, as the **kwargs passed QuerySet.annotate() or QuerySet.alias().", + "Severity": "HIGH", + "CweIDs": [ + "CWE-89" + ], + "VendorSeverity": { + "bitnami": 3, + "ghsa": 3, + "nvd": 3, + "redhat": 3, + "ubuntu": 2 + }, + "CVSS": { + "bitnami": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H", + "V3Score": 8.1 + }, + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:L/A:N", + "V3Score": 7.1 + }, + "nvd": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H", + "V3Score": 8.1 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:L/A:N", + "V3Score": 7.1 + } + }, + "References": [ + "http://www.openwall.com/lists/oss-security/2025/09/03/3", + "https://access.redhat.com/security/cve/CVE-2025-57833", + "https://docs.djangoproject.com/en/dev/releases/security", + "https://docs.djangoproject.com/en/dev/releases/security/", + "https://github.com/django/django", + "https://github.com/django/django/commit/102965ea93072fe3c39a30be437c683ec1106ef5", + "https://github.com/django/django/commit/31334e6965ad136a5e369993b01721499c5d1a92", + "https://github.com/django/django/commit/4c044fcc866ec226f612c475950b690b0139d243", + "https://github.com/pypa/advisory-database/tree/main/vulns/django/PYSEC-2025-105.yaml", + "https://groups.google.com/g/django-announce", + "https://lists.debian.org/debian-lts-announce/2025/09/msg00017.html", + "https://medium.com/@EyalSec/django-unauthenticated-0-click-rce-and-sql-injection-using-default-configuration-059964f3f898", + "https://nvd.nist.gov/vuln/detail/CVE-2025-57833", + "https://ubuntu.com/security/notices/USN-7736-1", + "https://www.cve.org/CVERecord?id=CVE-2025-57833", + "https://www.djangoproject.com/weblog/2025/sep/03/security-releases", + "https://www.djangoproject.com/weblog/2025/sep/03/security-releases/" + ], + "PublishedDate": "2025-09-03T21:15:32.85Z", + "LastModifiedDate": "2026-06-17T09:43:30.48Z" + }, + { + "VulnerabilityID": "CVE-2025-59681", + "VendorIDs": [ + "GHSA-hpr9-3m2g-3j9p" + ], + "PkgName": "Django", + "PkgIdentifier": { + "PURL": "pkg:pypi/django@5.1.2", + "UID": "dcc48896f46aa13d" + }, + "InstalledVersion": "5.1.2", + "FixedVersion": "4.2.25, 5.1.13, 5.2.7", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2025-59681", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory pip", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Apip" + }, + "Fingerprint": "sha256:1e159998249b005eeefe28476d2309e5d38b645311c1acb94415ffc874b3f8e8", + "Title": "django: Potential SQL injection in QuerySet.annotate(), alias(), aggregate(), and extra() on MySQL and MariaDB1", + "Description": "An issue was discovered in Django 4.2 before 4.2.25, 5.1 before 5.1.13, and 5.2 before 5.2.7. QuerySet.annotate(), QuerySet.alias(), QuerySet.aggregate(), and QuerySet.extra() are subject to SQL injection in column aliases, when using a suitably crafted dictionary, with dictionary expansion, as the **kwargs passed to these methods (on MySQL and MariaDB).", + "Severity": "HIGH", + "CweIDs": [ + "CWE-89" + ], + "VendorSeverity": { + "bitnami": 4, + "ghsa": 3, + "nvd": 4, + "redhat": 3, + "ubuntu": 2 + }, + "CVSS": { + "bitnami": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", + "V3Score": 9.8 + }, + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:L/A:N", + "V3Score": 7.1 + }, + "nvd": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", + "V3Score": 9.8 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N", + "V3Score": 8.1 + } + }, + "References": [ + "http://www.openwall.com/lists/oss-security/2025/10/01/3", + "https://access.redhat.com/security/cve/CVE-2025-59681", + "https://docs.djangoproject.com/en/dev/releases/security", + "https://docs.djangoproject.com/en/dev/releases/security/", + "https://github.com/django/django", + "https://github.com/django/django/commit/41b43c74bda19753c757036673ea9db74acf494a", + "https://github.com/django/django/commit/43d84aef04a9e71164c21a74885996981857e66e", + "https://github.com/pypa/advisory-database/tree/main/vulns/django/PYSEC-2025-106.yaml", + "https://groups.google.com/g/django-announce", + "https://nvd.nist.gov/vuln/detail/CVE-2025-59681", + "https://ubuntu.com/security/notices/USN-7794-1", + "https://www.cve.org/CVERecord?id=CVE-2025-59681", + "https://www.djangoproject.com/weblog/2025/oct/01/security-releases", + "https://www.djangoproject.com/weblog/2025/oct/01/security-releases/" + ], + "PublishedDate": "2025-10-01T19:15:36.487Z", + "LastModifiedDate": "2026-06-17T09:46:30.74Z" + }, + { + "VulnerabilityID": "CVE-2025-64458", + "VendorIDs": [ + "GHSA-qw25-v68c-qjf3" + ], + "PkgName": "Django", + "PkgIdentifier": { + "PURL": "pkg:pypi/django@5.1.2", + "UID": "dcc48896f46aa13d" + }, + "InstalledVersion": "5.1.2", + "FixedVersion": "5.2.8, 5.1.14, 4.2.26", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2025-64458", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory pip", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Apip" + }, + "Fingerprint": "sha256:611a17b1d71931d55dbbb61aaf8adfff9ca4e97cf35d89506b25825835104226", + "Title": "Django: Denial-of-service vulnerability in Django on Windows", + "Description": "An issue was discovered in 5.1 before 5.1.14, 4.2 before 4.2.26, and 5.2 before 5.2.8.\nNFKC normalization in Python is slow on Windows. As a consequence, `django.http.HttpResponseRedirect`, `django.http.HttpResponsePermanentRedirect`, and the shortcut `django.shortcuts.redirect` were subject to a potential denial-of-service attack via certain inputs with a very large number of Unicode characters.\nEarlier, unsupported Django series (such as 5.0.x, 4.1.x, and 3.2.x) were not evaluated and may also be affected.\nDjango would like to thank Seokchan Yoon for reporting this issue.", + "Severity": "HIGH", + "CweIDs": [ + "CWE-407" + ], + "VendorSeverity": { + "bitnami": 3, + "ghsa": 3, + "redhat": 3 + }, + "CVSS": { + "bitnami": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V3Score": 7.5 + }, + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V3Score": 7.5 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V3Score": 7.5 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2025-64458", + "https://docs.djangoproject.com/en/dev/releases/security", + "https://docs.djangoproject.com/en/dev/releases/security/", + "https://github.com/django/django", + "https://github.com/django/django/commit/3790593781d26168e7306b5b2f8ea0309de16242", + "https://github.com/django/django/commit/4f5d904b63751dea9ffc3b0e046404a7fa5881ac", + "https://github.com/django/django/commit/6e13348436fccf8f22982921d6a3a3e65c956a9f", + "https://github.com/django/django/commit/770eea38d7a0e9ba9455140b5a9a9e33618226a7", + "https://github.com/pypa/advisory-database/tree/main/vulns/django/PYSEC-2025-107.yaml", + "https://groups.google.com/g/django-announce", + "https://nvd.nist.gov/vuln/detail/CVE-2025-64458", + "https://www.cve.org/CVERecord?id=CVE-2025-64458", + "https://www.djangoproject.com/weblog/2025/nov/05/security-releases", + "https://www.djangoproject.com/weblog/2025/nov/05/security-releases/" + ], + "PublishedDate": "2025-11-05T15:15:40.94Z", + "LastModifiedDate": "2026-06-17T09:54:24.323Z" + }, + { + "VulnerabilityID": "CVE-2024-53907", + "VendorIDs": [ + "GHSA-8498-2h75-472j" + ], + "PkgName": "Django", + "PkgIdentifier": { + "PURL": "pkg:pypi/django@5.1.2", + "UID": "dcc48896f46aa13d" + }, + "InstalledVersion": "5.1.2", + "FixedVersion": "5.1.4, 4.2.17, 5.0.10", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2024-53907", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory pip", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Apip" + }, + "Fingerprint": "sha256:c0dc0983c52e7a9b3fdee6bf76db973d055daf6287e34dc9a0198040afd1c7a5", + "Title": "django: Potential denial-of-service in django.utils.html.strip_tags()", + "Description": "An issue was discovered in Django 5.1 before 5.1.4, 5.0 before 5.0.10, and 4.2 before 4.2.17. The strip_tags() method and striptags template filter are subject to a potential denial-of-service attack via certain inputs containing large sequences of nested incomplete HTML entities.", + "Severity": "MEDIUM", + "CweIDs": [ + "CWE-770" + ], + "VendorSeverity": { + "bitnami": 3, + "ghsa": 2, + "redhat": 2, + "ubuntu": 2 + }, + "CVSS": { + "bitnami": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V3Score": 7.5 + }, + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V40Vector": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:U", + "V3Score": 7.5, + "V40Score": 6.6 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H", + "V3Score": 6.5 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2024-53907", + "https://docs.djangoproject.com/en/dev/releases/security", + "https://docs.djangoproject.com/en/dev/releases/security/", + "https://github.com/django/django", + "https://github.com/pypa/advisory-database/tree/main/vulns/django/PYSEC-2024-156.yaml", + "https://groups.google.com/g/django-announce", + "https://lists.debian.org/debian-lts-announce/2024/12/msg00028.html", + "https://nvd.nist.gov/vuln/detail/CVE-2024-53907", + "https://ubuntu.com/security/notices/USN-7136-1", + "https://ubuntu.com/security/notices/USN-7136-2", + "https://www.cve.org/CVERecord?id=CVE-2024-53907", + "https://www.djangoproject.com/weblog/2024/dec/04/security-releases", + "https://www.djangoproject.com/weblog/2024/dec/04/security-releases/", + "https://www.openwall.com/lists/oss-security/2024/12/04/3" + ], + "PublishedDate": "2024-12-06T12:15:17.73Z", + "LastModifiedDate": "2026-06-17T08:09:28.707Z" + }, + { + "VulnerabilityID": "CVE-2024-56374", + "VendorIDs": [ + "GHSA-qcgg-j2x8-h9g8" + ], + "PkgName": "Django", + "PkgIdentifier": { + "PURL": "pkg:pypi/django@5.1.2", + "UID": "dcc48896f46aa13d" + }, + "InstalledVersion": "5.1.2", + "FixedVersion": "5.1.5, 5.0.11, 4.2.18", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2024-56374", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory pip", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Apip" + }, + "Fingerprint": "sha256:838d7cab46537d41b99b5f1e3345325c2ed072888a9904d67c3924eaa3f18095", + "Title": "django: potential denial-of-service vulnerability in IPv6 validation", + "Description": "An issue was discovered in Django 5.1 before 5.1.5, 5.0 before 5.0.11, and 4.2 before 4.2.18. Lack of upper-bound limit enforcement in strings passed when performing IPv6 validation could lead to a potential denial-of-service attack. The undocumented and private functions clean_ipv6_address and is_valid_ipv6_address are vulnerable, as is the django.forms.GenericIPAddressField form field. (The django.db.models.GenericIPAddressField model field is not affected.)", + "Severity": "MEDIUM", + "CweIDs": [ + "CWE-770" + ], + "VendorSeverity": { + "bitnami": 3, + "ghsa": 2, + "nvd": 3, + "redhat": 2, + "ubuntu": 2 + }, + "CVSS": { + "bitnami": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V3Score": 7.5 + }, + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:N/A:L", + "V3Score": 5.8 + }, + "nvd": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V3Score": 7.5 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:N/A:L", + "V3Score": 5.8 + } + }, + "References": [ + "http://www.openwall.com/lists/oss-security/2025/01/14/2", + "https://access.redhat.com/security/cve/CVE-2024-56374", + "https://docs.djangoproject.com/en/dev/releases/security", + "https://docs.djangoproject.com/en/dev/releases/security/", + "https://github.com/django/django", + "https://github.com/django/django/commit/4806731e58f3e8700a3c802e77899d54ac6021fe", + "https://github.com/django/django/commit/ad866a1ca3e7d60da888d25d27e46a8adb2ed36e", + "https://github.com/django/django/commit/ca2be7724e1244a4cb723de40a070f873c6e94bf", + "https://github.com/django/django/commit/e8d4a2005955dcf962193600b53bf461b190b455", + "https://github.com/pypa/advisory-database/tree/main/vulns/django/PYSEC-2025-1.yaml", + "https://groups.google.com/g/django-announce", + "https://lists.debian.org/debian-lts-announce/2025/01/msg00024.html", + "https://nvd.nist.gov/vuln/detail/CVE-2024-56374", + "https://ubuntu.com/security/notices/USN-7205-1", + "https://ubuntu.com/security/notices/USN-7205-2", + "https://www.cve.org/CVERecord?id=CVE-2024-56374", + "https://www.djangoproject.com/weblog/2025/jan/14/security-releases", + "https://www.djangoproject.com/weblog/2025/jan/14/security-releases/" + ], + "PublishedDate": "2025-01-14T19:15:32.51Z", + "LastModifiedDate": "2026-06-17T08:12:08.04Z" + }, + { + "VulnerabilityID": "CVE-2025-13372", + "VendorIDs": [ + "GHSA-rqw2-ghq9-44m7" + ], + "PkgName": "Django", + "PkgIdentifier": { + "PURL": "pkg:pypi/django@5.1.2", + "UID": "dcc48896f46aa13d" + }, + "InstalledVersion": "5.1.2", + "FixedVersion": "5.2.9, 5.1.15, 4.2.27", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2025-13372", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory pip", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Apip" + }, + "Fingerprint": "sha256:6b3016b05fc27dc7e32867e7de4d6f84339e544edbbfdf9d530feae76016ac14", + "Title": "django: Django: SQL injection in FilteredRelation column aliases", + "Description": "An issue was discovered in 5.2 before 5.2.9, 5.1 before 5.1.15, and 4.2 before 4.2.27.\n`FilteredRelation` is subject to SQL injection in column aliases, using a suitably crafted dictionary, with dictionary expansion, as the `**kwargs` passed to `QuerySet.annotate()` or `QuerySet.alias()` on PostgreSQL.\nEarlier, unsupported Django series (such as 5.0.x, 4.1.x, and 3.2.x) were not evaluated and may also be affected.\nDjango would like to thank Stackered for reporting this issue.", + "Severity": "MEDIUM", + "CweIDs": [ + "CWE-89" + ], + "VendorSeverity": { + "bitnami": 2, + "ghsa": 2, + "redhat": 2, + "ubuntu": 2 + }, + "CVSS": { + "bitnami": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N", + "V3Score": 4.3 + }, + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N", + "V3Score": 4.3 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N", + "V3Score": 4.3 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2025-13372", + "https://docs.djangoproject.com/en/dev/releases/security", + "https://docs.djangoproject.com/en/dev/releases/security/", + "https://github.com/django/django", + "https://github.com/django/django/commit/479415ce5249bcdebeb6570c72df2a87f45a7bbf", + "https://github.com/django/django/commit/56aea00c3c5e1aacf4ed05f8ee06c2e78f02cea0", + "https://github.com/django/django/commit/5b90ca1e7591fa36fccf2d6dad67cf1477e6293e", + "https://github.com/django/django/commit/9c6a5bde24240382807d13bc3748d08444709355", + "https://github.com/django/django/commit/f997037b235f6b5c9e7c4a501491ec45f3400f3d", + "https://github.com/pypa/advisory-database/tree/main/vulns/django/PYSEC-2025-104.yaml", + "https://groups.google.com/g/django-announce", + "https://nvd.nist.gov/vuln/detail/CVE-2025-13372", + "https://ubuntu.com/security/notices/USN-7903-1", + "https://www.cve.org/CVERecord?id=CVE-2025-13372", + "https://www.djangoproject.com/weblog/2025/dec/02/security-releases", + "https://www.djangoproject.com/weblog/2025/dec/02/security-releases/" + ], + "PublishedDate": "2025-12-02T16:15:53.907Z", + "LastModifiedDate": "2026-06-17T08:34:00.51Z" + }, + { + "VulnerabilityID": "CVE-2025-26699", + "VendorIDs": [ + "GHSA-p3fp-8748-vqfq" + ], + "PkgName": "Django", + "PkgIdentifier": { + "PURL": "pkg:pypi/django@5.1.2", + "UID": "dcc48896f46aa13d" + }, + "InstalledVersion": "5.1.2", + "FixedVersion": "4.2.20, 5.0.13, 5.1.7", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2025-26699", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory pip", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Apip" + }, + "Fingerprint": "sha256:44d7ecc63de761a89d6a47a3435021d80c5b01925b66c23dc0ede2d33c302a33", + "Title": "django: Potential denial-of-service vulnerability in django.utils.text.wrap()", + "Description": "An issue was discovered in Django 5.1 before 5.1.7, 5.0 before 5.0.13, and 4.2 before 4.2.20. The django.utils.text.wrap() method and wordwrap template filter are subject to a potential denial-of-service attack when used with very long strings.", + "Severity": "MEDIUM", + "CweIDs": [ + "CWE-770" + ], + "VendorSeverity": { + "bitnami": 3, + "ghsa": 2, + "nvd": 3, + "redhat": 2, + "ubuntu": 2 + }, + "CVSS": { + "bitnami": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V3Score": 7.5 + }, + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:N/I:N/A:L", + "V3Score": 5 + }, + "nvd": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V3Score": 7.5 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V3Score": 7.5 + } + }, + "References": [ + "http://www.openwall.com/lists/oss-security/2025/03/06/12", + "https://access.redhat.com/security/cve/CVE-2025-26699", + "https://docs.djangoproject.com/en/dev/releases/security", + "https://docs.djangoproject.com/en/dev/releases/security/", + "https://github.com/advisories/GHSA-p3fp-8748-vqfq", + "https://github.com/django/django", + "https://github.com/pypa/advisory-database/tree/main/vulns/django/PYSEC-2025-13.yaml", + "https://groups.google.com/g/django-announce", + "https://lists.debian.org/debian-lts-announce/2025/03/msg00012.html", + "https://nvd.nist.gov/vuln/detail/CVE-2025-26699", + "https://ubuntu.com/security/notices/USN-7335-1", + "https://www.cve.org/CVERecord?id=CVE-2025-26699", + "https://www.djangoproject.com/security/", + "https://www.djangoproject.com/weblog/2025/mar/06/security-releases", + "https://www.djangoproject.com/weblog/2025/mar/06/security-releases/" + ], + "PublishedDate": "2025-03-06T19:15:27.683Z", + "LastModifiedDate": "2026-06-17T09:02:18.903Z" + }, + { + "VulnerabilityID": "CVE-2025-27556", + "VendorIDs": [ + "GHSA-wqfg-m96j-85vm" + ], + "PkgName": "Django", + "PkgIdentifier": { + "PURL": "pkg:pypi/django@5.1.2", + "UID": "dcc48896f46aa13d" + }, + "InstalledVersion": "5.1.2", + "FixedVersion": "5.0.14, 5.1.8", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2025-27556", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory pip", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Apip" + }, + "Fingerprint": "sha256:90d7d9881b3c77b7be93e566f4dc43f5b7613a228e012bc7dff789db75f1e10d", + "Title": "django: Django DoS Unicode Attack", + "Description": "An issue was discovered in Django 5.1 before 5.1.8 and 5.0 before 5.0.14. The NFKC normalization is slow on Windows. As a consequence, django.contrib.auth.views.LoginView, django.contrib.auth.views.LogoutView, and django.views.i18n.set_language are subject to a potential denial-of-service attack via certain inputs with a very large number of Unicode characters.", + "Severity": "MEDIUM", + "CweIDs": [ + "CWE-770" + ], + "VendorSeverity": { + "bitnami": 3, + "ghsa": 2, + "nvd": 3, + "redhat": 2 + }, + "CVSS": { + "bitnami": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V3Score": 7.5 + }, + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:N/A:L", + "V3Score": 5.8 + }, + "nvd": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V3Score": 7.5 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:N/A:L", + "V3Score": 5.8 + } + }, + "References": [ + "http://www.openwall.com/lists/oss-security/2025/04/02/2", + "https://access.redhat.com/security/cve/CVE-2025-27556", + "https://docs.djangoproject.com/en/dev/releases/security", + "https://docs.djangoproject.com/en/dev/releases/security/", + "https://github.com/django/django", + "https://github.com/django/django/commit/2cb311f7b069723027fb5def4044d1816d7d2afd", + "https://github.com/django/django/commit/39e2297210d9d2938c75fc911d45f0e863dc4821", + "https://github.com/django/django/commit/8c6871b097b6c49d2a782c0d80d908bcbe2116f1", + "https://github.com/django/django/commit/edc2716d01a6fdd84b173c02031695231bcee1f8", + "https://github.com/pypa/advisory-database/tree/main/vulns/django/PYSEC-2025-14.yaml", + "https://groups.google.com/g/django-announce", + "https://nvd.nist.gov/vuln/detail/CVE-2025-27556", + "https://www.cve.org/CVERecord?id=CVE-2025-27556", + "https://www.djangoproject.com/weblog/2025/apr/02/security-releases", + "https://www.djangoproject.com/weblog/2025/apr/02/security-releases/" + ], + "PublishedDate": "2025-04-02T13:15:44.373Z", + "LastModifiedDate": "2026-06-17T09:03:47.89Z" + }, + { + "VulnerabilityID": "CVE-2025-32873", + "VendorIDs": [ + "GHSA-8j24-cjrq-gr2m" + ], + "PkgName": "Django", + "PkgIdentifier": { + "PURL": "pkg:pypi/django@5.1.2", + "UID": "dcc48896f46aa13d" + }, + "InstalledVersion": "5.1.2", + "FixedVersion": "4.2.21, 5.1.9, 5.2.1", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2025-32873", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory pip", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Apip" + }, + "Fingerprint": "sha256:d3dd283a71147b2d02986b8b8d222a2b60e3be6b5ed9655a47b303ec2c0bda71", + "Title": "django: Django StripTags Denial of Service", + "Description": "An issue was discovered in Django 4.2 before 4.2.21, 5.1 before 5.1.9, and 5.2 before 5.2.1. The django.utils.html.strip_tags() function is vulnerable to a potential denial-of-service (slow performance) when processing inputs containing large sequences of incomplete HTML tags. The template filter striptags is also vulnerable, because it is built on top of strip_tags().", + "Severity": "MEDIUM", + "CweIDs": [ + "CWE-770" + ], + "VendorSeverity": { + "bitnami": 2, + "ghsa": 2, + "nvd": 2, + "redhat": 2, + "ubuntu": 2 + }, + "CVSS": { + "bitnami": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L", + "V3Score": 5.3 + }, + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L", + "V3Score": 5.3 + }, + "nvd": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L", + "V3Score": 5.3 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L", + "V3Score": 5.3 + } + }, + "References": [ + "http://www.openwall.com/lists/oss-security/2025/05/07/1", + "https://access.redhat.com/security/cve/CVE-2025-32873", + "https://docs.djangoproject.com/en/dev/releases/security", + "https://docs.djangoproject.com/en/dev/releases/security/", + "https://github.com/django/django", + "https://github.com/django/django/commit/9f3419b519799d69f2aba70b9d25abe2e70d03e0", + "https://github.com/pypa/advisory-database/tree/main/vulns/django/PYSEC-2025-37.yaml", + "https://groups.google.com/g/django-announce", + "https://nvd.nist.gov/vuln/detail/CVE-2025-32873", + "https://ubuntu.com/security/notices/USN-7501-1", + "https://ubuntu.com/security/notices/USN-7501-2", + "https://www.cve.org/CVERecord?id=CVE-2025-32873", + "https://www.djangoproject.com/weblog/2025/may/07/security-releases", + "https://www.djangoproject.com/weblog/2025/may/07/security-releases/" + ], + "PublishedDate": "2025-05-08T04:17:18.157Z", + "LastModifiedDate": "2026-06-17T09:12:43.77Z" + }, + { + "VulnerabilityID": "CVE-2025-48432", + "VendorIDs": [ + "GHSA-7xr5-9hcq-chf9" + ], + "PkgName": "Django", + "PkgIdentifier": { + "PURL": "pkg:pypi/django@5.1.2", + "UID": "dcc48896f46aa13d" + }, + "InstalledVersion": "5.1.2", + "FixedVersion": "5.2.2, 5.1.10, 4.2.22", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2025-48432", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory pip", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Apip" + }, + "Fingerprint": "sha256:256cc69094e1556c452099750c9a756797ab3af9c9d57f7e7222ac29e650f75f", + "Title": "django: Django Path Injection Vulnerability", + "Description": "An issue was discovered in Django 5.2 before 5.2.3, 5.1 before 5.1.11, and 4.2 before 4.2.23. Internal HTTP response logging does not escape request.path, which allows remote attackers to potentially manipulate log output via crafted URLs. This may lead to log injection or forgery when logs are viewed in terminals or processed by external systems.", + "Severity": "MEDIUM", + "CweIDs": [ + "CWE-117" + ], + "VendorSeverity": { + "bitnami": 2, + "ghsa": 2, + "nvd": 2, + "redhat": 2, + "ubuntu": 1 + }, + "CVSS": { + "bitnami": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N", + "V3Score": 5.3 + }, + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:N/I:L/A:N", + "V3Score": 4 + }, + "nvd": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N", + "V3Score": 5.3 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:L/I:L/A:N", + "V3Score": 5.4 + } + }, + "References": [ + "http://www.openwall.com/lists/oss-security/2025/06/04/5", + "http://www.openwall.com/lists/oss-security/2025/06/10/2", + "http://www.openwall.com/lists/oss-security/2025/06/10/3", + "http://www.openwall.com/lists/oss-security/2025/06/10/4", + "https://access.redhat.com/security/cve/CVE-2025-48432", + "https://docs.djangoproject.com/en/dev/releases/security", + "https://docs.djangoproject.com/en/dev/releases/security/", + "https://github.com/django/django", + "https://github.com/pypa/advisory-database/tree/main/vulns/django/PYSEC-2025-47.yaml", + "https://groups.google.com/g/django-announce", + "https://nvd.nist.gov/vuln/detail/CVE-2025-48432", + "https://ubuntu.com/security/notices/USN-7555-1", + "https://ubuntu.com/security/notices/USN-7555-2", + "https://ubuntu.com/security/notices/USN-7555-3", + "https://www.cve.org/CVERecord?id=CVE-2025-48432", + "https://www.djangoproject.com/weblog/2025/jun/04/security-releases", + "https://www.djangoproject.com/weblog/2025/jun/04/security-releases/", + "https://www.djangoproject.com/weblog/2025/jun/10/bugfix-releases", + "https://www.djangoproject.com/weblog/2025/jun/10/bugfix-releases/" + ], + "PublishedDate": "2025-06-05T03:15:25.563Z", + "LastModifiedDate": "2026-06-17T09:29:38.22Z" + }, + { + "VulnerabilityID": "CVE-2025-64460", + "VendorIDs": [ + "GHSA-vrcr-9hj9-jcg6" + ], + "PkgName": "Django", + "PkgIdentifier": { + "PURL": "pkg:pypi/django@5.1.2", + "UID": "dcc48896f46aa13d" + }, + "InstalledVersion": "5.1.2", + "FixedVersion": "5.2.9, 5.1.15, 4.2.27", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2025-64460", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory pip", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Apip" + }, + "Fingerprint": "sha256:33f773708a96ebd5d61949f427b593ef7a0f52fcb74e64f47580111516edff3e", + "Title": "Django: Django: Algorithmic complexity in XML Deserializer leads to denial of service", + "Description": "An issue was discovered in 5.2 before 5.2.9, 5.1 before 5.1.15, and 4.2 before 4.2.27.\nAlgorithmic complexity in `django.core.serializers.xml_serializer.getInnerText()` allows a remote attacker to cause a potential denial-of-service attack triggering CPU and memory exhaustion via specially crafted XML input processed by the XML `Deserializer`.\nEarlier, unsupported Django series (such as 5.0.x, 4.1.x, and 3.2.x) were not evaluated and may also be affected.\nDjango would like to thank Seokchan Yoon for reporting this issue.", + "Severity": "MEDIUM", + "CweIDs": [ + "CWE-407" + ], + "VendorSeverity": { + "bitnami": 3, + "ghsa": 2, + "redhat": 3, + "ubuntu": 2 + }, + "CVSS": { + "bitnami": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V3Score": 7.5 + }, + "ghsa": { + "V40Vector": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N", + "V40Score": 6.3 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V3Score": 7.5 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2025-64460", + "https://docs.djangoproject.com/en/dev/releases/security", + "https://docs.djangoproject.com/en/dev/releases/security/", + "https://github.com/django/django", + "https://github.com/django/django/commit/0db9ea4669312f1f4973e09f4bca06ab9c1ec74b", + "https://github.com/django/django/commit/1dbd07a608e495a0c229edaaf84d58d8976313b5", + "https://github.com/django/django/commit/4d2b8803bebcdefd2b76e9e8fc528d5fddea93f0", + "https://github.com/django/django/commit/99e7d22f55497278d0bcb2e15e72ef532e62a31d", + "https://github.com/pypa/advisory-database/tree/main/vulns/django/PYSEC-2025-109.yaml", + "https://groups.google.com/g/django-announce", + "https://nvd.nist.gov/vuln/detail/CVE-2025-64460", + "https://ubuntu.com/security/notices/USN-7903-1", + "https://www.cve.org/CVERecord?id=CVE-2025-64460", + "https://www.djangoproject.com/weblog/2025/dec/02/security-releases", + "https://www.djangoproject.com/weblog/2025/dec/02/security-releases/" + ], + "PublishedDate": "2025-12-02T16:15:56.013Z", + "LastModifiedDate": "2026-06-17T09:54:24.63Z" + }, + { + "VulnerabilityID": "CVE-2025-59682", + "VendorIDs": [ + "GHSA-q95w-c7qg-hrff" + ], + "PkgName": "Django", + "PkgIdentifier": { + "PURL": "pkg:pypi/django@5.1.2", + "UID": "dcc48896f46aa13d" + }, + "InstalledVersion": "5.1.2", + "FixedVersion": "4.2.25, 5.1.13, 5.2.7", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2025-59682", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory pip", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Apip" + }, + "Fingerprint": "sha256:c1a2d1a61722af508af85e4569a5151886074b6b91754c5148282bb34c3dd5db", + "Title": "django: Potential partial directory-traversal via archive.extract()", + "Description": "An issue was discovered in Django 4.2 before 4.2.25, 5.1 before 5.1.13, and 5.2 before 5.2.7. The django.utils.archive.extract() function, used by the \"startapp --template\" and \"startproject --template\" commands, allows partial directory traversal via an archive with file paths sharing a common prefix with the target directory.", + "Severity": "LOW", + "CweIDs": [ + "CWE-23" + ], + "VendorSeverity": { + "bitnami": 2, + "ghsa": 1, + "nvd": 2, + "redhat": 3, + "ubuntu": 2 + }, + "CVSS": { + "bitnami": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N", + "V3Score": 6.5 + }, + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N", + "V3Score": 3.1 + }, + "nvd": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N", + "V3Score": 6.5 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H", + "V3Score": 8.8 + } + }, + "References": [ + "http://www.openwall.com/lists/oss-security/2025/10/01/3", + "https://access.redhat.com/security/cve/CVE-2025-59682", + "https://docs.djangoproject.com/en/dev/releases/security", + "https://docs.djangoproject.com/en/dev/releases/security/", + "https://github.com/django/django", + "https://github.com/django/django/commit/43d84aef04a9e71164c21a74885996981857e66e", + "https://github.com/django/django/commit/924a0c092e65fa2d0953fd1855d2dc8786d94de2", + "https://groups.google.com/g/django-announce", + "https://nvd.nist.gov/vuln/detail/CVE-2025-59682", + "https://ubuntu.com/security/notices/USN-7794-1", + "https://www.cve.org/CVERecord?id=CVE-2025-59682", + "https://www.djangoproject.com/weblog/2025/oct/01/security-releases", + "https://www.djangoproject.com/weblog/2025/oct/01/security-releases/" + ], + "PublishedDate": "2025-10-01T19:15:37.007Z", + "LastModifiedDate": "2026-06-17T09:46:30.87Z" + }, + { + "VulnerabilityID": "CVE-2026-41066", + "VendorIDs": [ + "GHSA-vfmq-68hx-4jfw" + ], + "PkgName": "lxml", + "PkgIdentifier": { + "PURL": "pkg:pypi/lxml@5.3.0", + "UID": "81c5b0c899da3408" + }, + "InstalledVersion": "5.3.0", + "FixedVersion": "6.1.0", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2026-41066", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory pip", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Apip" + }, + "Fingerprint": "sha256:d63bfe127c38cca40a771631a83f86d9149df189c31a299179b1261b8a397625", + "Title": "lxml: python: lxml: Information disclosure via untrusted XML input leading to local file read", + "Description": "lxml is a library for processing XML and HTML in the Python language. Prior to 6.1.0, using either of the two parsers in the default configuration (with resolve_entities=True) allows untrusted XML input to read local files. Setting the resolve_entities option explicitly to resolve_entities='internal' or resolve_entities=False disables the local file access. This vulnerability is fixed in 6.1.0.", + "Severity": "HIGH", + "CweIDs": [ + "CWE-611" + ], + "VendorSeverity": { + "amazon": 3, + "azure": 3, + "ghsa": 3, + "photon": 3, + "redhat": 2, + "ubuntu": 2 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N", + "V3Score": 7.5 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N", + "V3Score": 5.9 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2026-41066", + "https://bugs.launchpad.net/lxml/+bug/2146291", + "https://github.com/lxml/lxml", + "https://github.com/lxml/lxml/releases/tag/lxml-6.1.0", + "https://github.com/lxml/lxml/security/advisories/GHSA-vfmq-68hx-4jfw", + "https://github.com/pypa/advisory-database/tree/main/vulns/lxml/PYSEC-2026-87.yaml", + "https://nvd.nist.gov/vuln/detail/CVE-2026-41066", + "https://www.cve.org/CVERecord?id=CVE-2026-41066" + ], + "PublishedDate": "2026-04-24T17:16:20.933Z", + "LastModifiedDate": "2026-06-17T10:46:06.993Z" + }, + { + "VulnerabilityID": "CVE-2025-71176", + "VendorIDs": [ + "GHSA-6w46-j5rx-g56g" + ], + "PkgName": "pytest", + "PkgIdentifier": { + "PURL": "pkg:pypi/pytest@8.3.3", + "UID": "9d504b1ef2a92265" + }, + "InstalledVersion": "8.3.3", + "FixedVersion": "9.0.3", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2025-71176", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory pip", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Apip" + }, + "Fingerprint": "sha256:8ef845ef6e0e130d05626cebea2e75159f3fea96188eac75109f49f550c1ba4c", + "Title": "pytest: pytest: Denial of Service or Privilege Escalation via insecure temporary directory handling", + "Description": "pytest through 9.0.2 on UNIX relies on directories with the /tmp/pytest-of-{user} name pattern, which allows local users to cause a denial of service or possibly gain privileges.", + "Severity": "MEDIUM", + "CweIDs": [ + "CWE-379" + ], + "VendorSeverity": { + "amazon": 2, + "ghsa": 2, + "redhat": 2 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:L", + "V3Score": 6.8 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:L", + "V3Score": 6.8 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2025-71176", + "https://github.com/pytest-dev/pytes", + "https://github.com/pytest-dev/pytest/commit/95d8423bd24992deea5b9df32555fa1741679e2c", + "https://github.com/pytest-dev/pytest/issues/13669", + "https://github.com/pytest-dev/pytest/pull/14343", + "https://github.com/pytest-dev/pytest/releases/tag/9.0.3", + "https://nvd.nist.gov/vuln/detail/CVE-2025-71176", + "https://www.cve.org/CVERecord?id=CVE-2025-71176", + "https://www.openwall.com/lists/oss-security/2026/01/21/5" + ], + "PublishedDate": "2026-01-22T05:16:17.577Z", + "LastModifiedDate": "2026-06-17T10:03:47.83Z" + }, + { + "VulnerabilityID": "CVE-2026-28684", + "VendorIDs": [ + "GHSA-mf9w-mj56-hr94" + ], + "PkgName": "python-dotenv", + "PkgIdentifier": { + "PURL": "pkg:pypi/python-dotenv@1.0.1", + "UID": "da168a05e25283ab" + }, + "InstalledVersion": "1.0.1", + "FixedVersion": "1.2.2", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2026-28684", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory pip", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Apip" + }, + "Fingerprint": "sha256:bb02aba9dbe76c038d5a33ee09fd4a775310b12422f0b85012698ea13e29d375", + "Title": "python-dotenv: python-dotenv: Arbitrary file overwrite via symbolic link following", + "Description": "python-dotenv reads key-value pairs from a .env file and can set them as environment variables. Prior to version 1.2.2, `set_key()` and `unset_key()` in python-dotenv follow symbolic links when rewriting `.env` files, allowing a local attacker to overwrite arbitrary files via a crafted symlink when a cross-device rename fallback is triggered. Users should upgrade to v.1.2.2 or, as a workaround, apply the patch manually.", + "Severity": "MEDIUM", + "CweIDs": [ + "CWE-59", + "CWE-61" + ], + "VendorSeverity": { + "ghsa": 2, + "redhat": 2 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:L/AC:L/PR:L/UI:R/S:U/C:N/I:H/A:H", + "V3Score": 6.6 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H", + "V3Score": 7.1 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2026-28684", + "https://github.com/theskumar/python-dotenv", + "https://github.com/theskumar/python-dotenv/commit/790c5c02991100aa1bf41ee5330aca75edc51311", + "https://github.com/theskumar/python-dotenv/commit/790c5c02991100aa1bf41ee5330aca75edc51311.patch", + "https://github.com/theskumar/python-dotenv/releases/tag/v1.2.2", + "https://github.com/theskumar/python-dotenv/security/advisories/GHSA-mf9w-mj56-hr94", + "https://nvd.nist.gov/vuln/detail/CVE-2026-28684", + "https://www.cve.org/CVERecord?id=CVE-2026-28684" + ], + "PublishedDate": "2026-04-20T17:16:33.087Z", + "LastModifiedDate": "2026-06-17T10:28:54.243Z" + }, + { + "VulnerabilityID": "CVE-2024-47081", + "VendorIDs": [ + "GHSA-9hjg-9r4m-mvj7" + ], + "PkgName": "requests", + "PkgIdentifier": { + "PURL": "pkg:pypi/requests@2.32.3", + "UID": "c15ff9e490806b50" + }, + "InstalledVersion": "2.32.3", + "FixedVersion": "2.32.4", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2024-47081", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory pip", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Apip" + }, + "Fingerprint": "sha256:91fbcdb4c78e77152c5b4a5b495ce33e039b34b1ad11485f24c39a22ece1523e", + "Title": "requests: Requests vulnerable to .netrc credentials leak via malicious URLs", + "Description": "Requests is a HTTP library. Due to a URL parsing issue, Requests releases prior to 2.32.4 may leak .netrc credentials to third parties for specific maliciously-crafted URLs. Users should upgrade to version 2.32.4 to receive a fix. For older versions of Requests, use of the .netrc file can be disabled with `trust_env=False` on one's Requests Session.", + "Severity": "MEDIUM", + "CweIDs": [ + "CWE-522" + ], + "VendorSeverity": { + "alma": 2, + "amazon": 2, + "azure": 2, + "cbl-mariner": 2, + "ghsa": 2, + "oracle-oval": 2, + "photon": 2, + "redhat": 2, + "rocky": 2, + "ubuntu": 2 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:N/A:N", + "V3Score": 5.3 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:N/A:N", + "V3Score": 5.3 + } + }, + "References": [ + "http://seclists.org/fulldisclosure/2025/Jun/2", + "http://www.openwall.com/lists/oss-security/2025/06/03/11", + "http://www.openwall.com/lists/oss-security/2025/06/03/9", + "http://www.openwall.com/lists/oss-security/2025/06/04/1", + "http://www.openwall.com/lists/oss-security/2025/06/04/6", + "https://access.redhat.com/errata/RHSA-2025:12519", + "https://access.redhat.com/security/cve/CVE-2024-47081", + "https://bugzilla.redhat.com/2371272", + "https://bugzilla.redhat.com/show_bug.cgi?id=2371272", + "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-47081", + "https://errata.almalinux.org/9/ALSA-2025-12519.html", + "https://errata.rockylinux.org/RLSA-2025:13234", + "https://github.com/psf/requests", + "https://github.com/psf/requests/commit/96ba401c1296ab1dda74a2365ef36d88f7d144ef", + "https://github.com/psf/requests/pull/6965", + "https://github.com/psf/requests/security/advisories/GHSA-9hjg-9r4m-mvj7", + "https://linux.oracle.com/cve/CVE-2024-47081.html", + "https://linux.oracle.com/errata/ELSA-2025-14999.html", + "https://nvd.nist.gov/vuln/detail/CVE-2024-47081", + "https://requests.readthedocs.io/en/latest/api/#requests.Session.trust_env", + "https://seclists.org/fulldisclosure/2025/Jun/2", + "https://ubuntu.com/security/notices/USN-7568-1", + "https://ubuntu.com/security/notices/USN-7762-1", + "https://www.cve.org/CVERecord?id=CVE-2024-47081", + "https://www.openwall.com/lists/oss-security/2025/06/03/9" + ], + "PublishedDate": "2025-06-09T18:15:24.983Z", + "LastModifiedDate": "2026-06-17T07:56:30.697Z" + }, + { + "VulnerabilityID": "CVE-2026-25645", + "VendorIDs": [ + "GHSA-gc5v-m9x4-r6x2" + ], + "PkgName": "requests", + "PkgIdentifier": { + "PURL": "pkg:pypi/requests@2.32.3", + "UID": "c15ff9e490806b50" + }, + "InstalledVersion": "2.32.3", + "FixedVersion": "2.33.0", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2026-25645", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory pip", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Apip" + }, + "Fingerprint": "sha256:bd8c4953c865790e66c677808e1b6cbc4d2d56db7af35c6aa781f154ee985dd8", + "Title": "requests: Requests: Security bypass due to predictable temporary file creation", + "Description": "Requests is a HTTP library. Prior to version 2.33.0, the `requests.utils.extract_zipped_paths()` utility function uses a predictable filename when extracting files from zip archives into the system temporary directory. If the target file already exists, it is reused without validation. A local attacker with write access to the temp directory could pre-create a malicious file that would be loaded in place of the legitimate one. Standard usage of the Requests library is not affected by this vulnerability. Only applications that call `extract_zipped_paths()` directly are impacted. Starting in version 2.33.0, the library extracts files to a non-deterministic location. If developers are unable to upgrade, they can set `TMPDIR` in their environment to a directory with restricted write access.", + "Severity": "MEDIUM", + "CweIDs": [ + "CWE-377" + ], + "VendorSeverity": { + "azure": 2, + "ghsa": 2, + "nvd": 2, + "photon": 2, + "redhat": 2 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:L/AC:H/PR:L/UI:R/S:U/C:N/I:H/A:N", + "V3Score": 4.4 + }, + "nvd": { + "V3Vector": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N", + "V3Score": 5.5 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:H/A:N", + "V3Score": 4.7 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2026-25645", + "https://github.com/psf/requests", + "https://github.com/psf/requests/commit/66d21cb07bd6255b1280291c4fafb71803cdb3b7", + "https://github.com/psf/requests/releases/tag/v2.33.0", + "https://github.com/psf/requests/security/advisories/GHSA-gc5v-m9x4-r6x2", + "https://nvd.nist.gov/vuln/detail/CVE-2026-25645", + "https://www.cve.org/CVERecord?id=CVE-2026-25645" + ], + "PublishedDate": "2026-03-25T17:16:52.97Z", + "LastModifiedDate": "2026-06-17T10:25:00.443Z" + } + ] + }, + { + "Target": "frontend/package-lock.json", + "Class": "lang-pkgs", + "Type": "npm", + "Packages": [ + { + "ID": "@babel/core@7.17.5", + "Name": "@babel/core", + "Identifier": { + "PURL": "pkg:npm/%40babel/core@7.17.5", + "UID": "2a6160dcdc31d62a" + }, + "Version": "7.17.5", + "Licenses": [ + "MIT" + ], + "Relationship": "direct", + "DependsOn": [ + "@ampproject/remapping@2.1.2", + "@babel/code-frame@7.18.6", + "@babel/generator@7.18.9", + "@babel/helper-compilation-targets@7.16.7", + "@babel/helper-module-transforms@7.17.6", + "@babel/helpers@7.17.2", + "@babel/parser@7.18.9", + "@babel/template@7.18.6", + "@babel/traverse@7.18.9", + "@babel/types@7.18.9", + "convert-source-map@1.8.0", + "debug@4.3.3", + "gensync@1.0.0-beta.2", + "json5@2.2.0", + "semver@6.3.0" + ], + "Locations": [ + { + "StartLine": 88, + "EndLine": 117 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@dicebear/bottts-neutral@9.4.2", + "Name": "@dicebear/bottts-neutral", + "Identifier": { + "PURL": "pkg:npm/%40dicebear/bottts-neutral@9.4.2", + "UID": "21c8314fdec8ab6c" + }, + "Version": "9.4.2", + "Licenses": [ + "See LICENSE file" + ], + "Relationship": "direct", + "DependsOn": [ + "@dicebear/core@9.4.2" + ], + "Locations": [ + { + "StartLine": 1756, + "EndLine": 1767 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@dicebear/core@9.4.2", + "Name": "@dicebear/core", + "Identifier": { + "PURL": "pkg:npm/%40dicebear/core@9.4.2", + "UID": "e54ffbd5b02dabb3" + }, + "Version": "9.4.2", + "Licenses": [ + "MIT" + ], + "Relationship": "direct", + "DependsOn": [ + "@types/json-schema@7.0.15" + ], + "Locations": [ + { + "StartLine": 1768, + "EndLine": 1779 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@emotion/react@11.11.1", + "Name": "@emotion/react", + "Identifier": { + "PURL": "pkg:npm/%40emotion/react@11.11.1", + "UID": "76e610441a871745" + }, + "Version": "11.11.1", + "Licenses": [ + "MIT" + ], + "Relationship": "direct", + "DependsOn": [ + "@babel/runtime@7.23.2", + "@emotion/babel-plugin@11.11.0", + "@emotion/cache@11.11.0", + "@emotion/serialize@1.1.2", + "@emotion/use-insertion-effect-with-fallbacks@1.0.1", + "@emotion/utils@1.2.1", + "@emotion/weak-memoize@0.3.1", + "hoist-non-react-statics@3.3.2", + "react@17.0.2" + ], + "Locations": [ + { + "StartLine": 1858, + "EndLine": 1880 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@emotion/styled@11.8.1", + "Name": "@emotion/styled", + "Identifier": { + "PURL": "pkg:npm/%40emotion/styled@11.8.1", + "UID": "f4994f00572813cf" + }, + "Version": "11.8.1", + "Licenses": [ + "MIT" + ], + "Relationship": "direct", + "DependsOn": [ + "@babel/core@7.17.5", + "@babel/runtime@7.23.2", + "@emotion/babel-plugin@11.11.0", + "@emotion/is-prop-valid@1.1.2", + "@emotion/react@11.11.1", + "@emotion/serialize@1.1.2", + "@emotion/utils@1.2.1", + "react@17.0.2" + ], + "Locations": [ + { + "StartLine": 1903, + "EndLine": 1927 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@mui/icons-material@5.4.4", + "Name": "@mui/icons-material", + "Identifier": { + "PURL": "pkg:npm/%40mui/icons-material@5.4.4", + "UID": "cb1017299e41f70a" + }, + "Version": "5.4.4", + "Licenses": [ + "MIT" + ], + "Relationship": "direct", + "DependsOn": [ + "@babel/runtime@7.23.2", + "@mui/material@5.14.15", + "@types/react@17.0.39", + "react@17.0.2" + ], + "Locations": [ + { + "StartLine": 2091, + "EndLine": 2115 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@mui/material@5.14.15", + "Name": "@mui/material", + "Identifier": { + "PURL": "pkg:npm/%40mui/material@5.14.15", + "UID": "c467146234338e90" + }, + "Version": "5.14.15", + "Licenses": [ + "MIT" + ], + "Relationship": "direct", + "DependsOn": [ + "@babel/runtime@7.23.2", + "@emotion/react@11.11.1", + "@emotion/styled@11.8.1", + "@mui/base@5.0.0-beta.21", + "@mui/core-downloads-tracker@5.14.15", + "@mui/system@5.14.15", + "@mui/types@7.2.7", + "@mui/utils@5.14.15", + "@types/react-transition-group@4.4.8", + "@types/react@17.0.39", + "clsx@2.0.0", + "csstype@3.1.2", + "prop-types@15.8.1", + "react-dom@17.0.2", + "react-is@18.2.0", + "react-transition-group@4.4.5", + "react@17.0.2" + ], + "Locations": [ + { + "StartLine": 2116, + "EndLine": 2159 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@mui/x-data-grid@5.7.0", + "Name": "@mui/x-data-grid", + "Identifier": { + "PURL": "pkg:npm/%40mui/x-data-grid@5.7.0", + "UID": "f71c0f61148c4062" + }, + "Version": "5.7.0", + "Licenses": [ + "MIT" + ], + "Relationship": "direct", + "DependsOn": [ + "@mui/material@5.14.15", + "@mui/system@5.14.15", + "@mui/utils@5.14.15", + "clsx@1.1.1", + "prop-types@15.8.1", + "react@17.0.2", + "reselect@4.1.5" + ], + "Locations": [ + { + "StartLine": 2322, + "EndLine": 2344 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@mui/x-date-pickers@6.16.3", + "Name": "@mui/x-date-pickers", + "Identifier": { + "PURL": "pkg:npm/%40mui/x-date-pickers@6.16.3", + "UID": "9057b109c0dfaedb" + }, + "Version": "6.16.3", + "Licenses": [ + "MIT" + ], + "Relationship": "direct", + "DependsOn": [ + "@babel/runtime@7.23.2", + "@emotion/react@11.11.1", + "@emotion/styled@11.8.1", + "@mui/base@5.0.0-beta.21", + "@mui/material@5.14.15", + "@mui/system@5.14.15", + "@mui/utils@5.14.15", + "@types/react-transition-group@4.4.8", + "clsx@2.0.0", + "date-fns@2.30.0", + "dayjs@1.11.10", + "prop-types@15.8.1", + "react-dom@17.0.2", + "react-transition-group@4.4.5", + "react@17.0.2" + ], + "Locations": [ + { + "StartLine": 2345, + "EndLine": 2409 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@types/react@17.0.39", + "Name": "@types/react", + "Identifier": { + "PURL": "pkg:npm/%40types/react@17.0.39", + "UID": "a0b4eb25ac33c618" + }, + "Version": "17.0.39", + "Licenses": [ + "MIT" + ], + "Relationship": "direct", + "DependsOn": [ + "@types/prop-types@15.7.9", + "@types/scheduler@0.16.2", + "csstype@3.1.2" + ], + "Locations": [ + { + "StartLine": 2604, + "EndLine": 2613 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "axios@0.26.0", + "Name": "axios", + "Identifier": { + "PURL": "pkg:npm/axios@0.26.0", + "UID": "ab38b41ae3d6e87b" + }, + "Version": "0.26.0", + "Licenses": [ + "MIT" + ], + "Relationship": "direct", + "DependsOn": [ + "follow-redirects@1.14.9" + ], + "Locations": [ + { + "StartLine": 3056, + "EndLine": 3063 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "chart.js@3.7.1", + "Name": "chart.js", + "Identifier": { + "PURL": "pkg:npm/chart.js@3.7.1", + "UID": "f0986c37f9c6410e" + }, + "Version": "3.7.1", + "Licenses": [ + "MIT" + ], + "Relationship": "direct", + "Locations": [ + { + "StartLine": 3597, + "EndLine": 3601 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "chartjs-plugin-datalabels@2.0.0", + "Name": "chartjs-plugin-datalabels", + "Identifier": { + "PURL": "pkg:npm/chartjs-plugin-datalabels@2.0.0", + "UID": "91c7f7caf0778568" + }, + "Version": "2.0.0", + "Licenses": [ + "MIT" + ], + "Relationship": "direct", + "DependsOn": [ + "chart.js@3.7.1" + ], + "Locations": [ + { + "StartLine": 3602, + "EndLine": 3609 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "date-fns@2.30.0", + "Name": "date-fns", + "Identifier": { + "PURL": "pkg:npm/date-fns@2.30.0", + "UID": "43e00731f90fd229" + }, + "Version": "2.30.0", + "Licenses": [ + "MIT" + ], + "Relationship": "direct", + "DependsOn": [ + "@babel/runtime@7.23.2" + ], + "Locations": [ + { + "StartLine": 4004, + "EndLine": 4018 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "dayjs@1.11.10", + "Name": "dayjs", + "Identifier": { + "PURL": "pkg:npm/dayjs@1.11.10", + "UID": "d7a30d02899e6f01" + }, + "Version": "1.11.10", + "Licenses": [ + "MIT" + ], + "Relationship": "direct", + "Locations": [ + { + "StartLine": 4019, + "EndLine": 4023 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "framer-motion@6.3.0", + "Name": "framer-motion", + "Identifier": { + "PURL": "pkg:npm/framer-motion@6.3.0", + "UID": "dbfeafb480d6c466" + }, + "Version": "6.3.0", + "Licenses": [ + "MIT" + ], + "Relationship": "direct", + "DependsOn": [ + "@emotion/is-prop-valid@0.8.8", + "framesync@6.0.1", + "hey-listen@1.0.8", + "popmotion@11.0.3", + "react-dom@17.0.2", + "react@17.0.2", + "style-value-types@5.0.0", + "tslib@2.3.1" + ], + "Locations": [ + { + "StartLine": 4848, + "EndLine": 4866 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "react@17.0.2", + "Name": "react", + "Identifier": { + "PURL": "pkg:npm/react@17.0.2", + "UID": "ca4224001bb376a5" + }, + "Version": "17.0.2", + "Licenses": [ + "MIT" + ], + "Relationship": "direct", + "DependsOn": [ + "loose-envify@1.4.0", + "object-assign@4.1.1" + ], + "Locations": [ + { + "StartLine": 6803, + "EndLine": 6814 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "react-chartjs-2@4.0.1", + "Name": "react-chartjs-2", + "Identifier": { + "PURL": "pkg:npm/react-chartjs-2@4.0.1", + "UID": "3bdbe6a2d0ec0295" + }, + "Version": "4.0.1", + "Licenses": [ + "MIT" + ], + "Relationship": "direct", + "DependsOn": [ + "chart.js@3.7.1", + "react@17.0.2" + ], + "Locations": [ + { + "StartLine": 6815, + "EndLine": 6823 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "react-dom@17.0.2", + "Name": "react-dom", + "Identifier": { + "PURL": "pkg:npm/react-dom@17.0.2", + "UID": "5ef3a106536a5528" + }, + "Version": "17.0.2", + "Licenses": [ + "MIT" + ], + "Relationship": "direct", + "DependsOn": [ + "loose-envify@1.4.0", + "object-assign@4.1.1", + "react@17.0.2", + "scheduler@0.20.2" + ], + "Locations": [ + { + "StartLine": 6824, + "EndLine": 6836 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "react-intersection-observer@8.33.1", + "Name": "react-intersection-observer", + "Identifier": { + "PURL": "pkg:npm/react-intersection-observer@8.33.1", + "UID": "713a155c41165c41" + }, + "Version": "8.33.1", + "Licenses": [ + "MIT" + ], + "Relationship": "direct", + "DependsOn": [ + "react@17.0.2" + ], + "Locations": [ + { + "StartLine": 6837, + "EndLine": 6844 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "react-query@3.34.16", + "Name": "react-query", + "Identifier": { + "PURL": "pkg:npm/react-query@3.34.16", + "UID": "484c1c7b82562ddc" + }, + "Version": "3.34.16", + "Licenses": [ + "MIT" + ], + "Relationship": "direct", + "DependsOn": [ + "@babel/runtime@7.23.2", + "broadcast-channel@3.7.0", + "match-sorter@6.3.1", + "react@17.0.2" + ], + "Locations": [ + { + "StartLine": 6850, + "EndLine": 6874 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "react-router-dom@6.2.2", + "Name": "react-router-dom", + "Identifier": { + "PURL": "pkg:npm/react-router-dom@6.2.2", + "UID": "f434d05fc469c36d" + }, + "Version": "6.2.2", + "Licenses": [ + "MIT" + ], + "Relationship": "direct", + "DependsOn": [ + "history@5.3.0", + "react-dom@17.0.2", + "react-router@6.2.2", + "react@17.0.2" + ], + "Locations": [ + { + "StartLine": 6886, + "EndLine": 6898 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "typescript@4.6.2", + "Name": "typescript", + "Identifier": { + "PURL": "pkg:npm/typescript@4.6.2", + "UID": "77f28aaa30694da0" + }, + "Version": "4.6.2", + "Licenses": [ + "Apache-2.0" + ], + "Relationship": "direct", + "Locations": [ + { + "StartLine": 7891, + "EndLine": 7902 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@ampproject/remapping@2.1.2", + "Name": "@ampproject/remapping", + "Identifier": { + "PURL": "pkg:npm/%40ampproject/remapping@2.1.2", + "UID": "e778c9dfcdde5aae" + }, + "Version": "2.1.2", + "Licenses": [ + "Apache-2.0" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@jridgewell/trace-mapping@0.3.14" + ], + "Locations": [ + { + "StartLine": 56, + "EndLine": 67 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@babel/code-frame@7.18.6", + "Name": "@babel/code-frame", + "Identifier": { + "PURL": "pkg:npm/%40babel/code-frame@7.18.6", + "UID": "efd44c77b03a6076" + }, + "Version": "7.18.6", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@babel/highlight@7.18.6" + ], + "Locations": [ + { + "StartLine": 68, + "EndLine": 78 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@babel/compat-data@7.17.0", + "Name": "@babel/compat-data", + "Identifier": { + "PURL": "pkg:npm/%40babel/compat-data@7.17.0", + "UID": "ae898b0fa2d4c48f" + }, + "Version": "7.17.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 79, + "EndLine": 87 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@babel/generator@7.18.9", + "Name": "@babel/generator", + "Identifier": { + "PURL": "pkg:npm/%40babel/generator@7.18.9", + "UID": "de42d0be6df970ad" + }, + "Version": "7.18.9", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@babel/types@7.18.9", + "@jridgewell/gen-mapping@0.3.2", + "jsesc@2.5.2" + ], + "Locations": [ + { + "StartLine": 118, + "EndLine": 131 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@babel/helper-compilation-targets@7.16.7", + "Name": "@babel/helper-compilation-targets", + "Identifier": { + "PURL": "pkg:npm/%40babel/helper-compilation-targets@7.16.7", + "UID": "32dc6fdf8746cfa3" + }, + "Version": "7.16.7", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@babel/compat-data@7.17.0", + "@babel/core@7.17.5", + "@babel/helper-validator-option@7.18.6", + "browserslist@4.19.3", + "semver@6.3.0" + ], + "Locations": [ + { + "StartLine": 157, + "EndLine": 174 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@babel/helper-environment-visitor@7.18.9", + "Name": "@babel/helper-environment-visitor", + "Identifier": { + "PURL": "pkg:npm/%40babel/helper-environment-visitor@7.18.9", + "UID": "b6d03f00f85ac2c5" + }, + "Version": "7.18.9", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 231, + "EndLine": 239 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@babel/helper-function-name@7.18.9", + "Name": "@babel/helper-function-name", + "Identifier": { + "PURL": "pkg:npm/%40babel/helper-function-name@7.18.9", + "UID": "7b226411d468103f" + }, + "Version": "7.18.9", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@babel/template@7.18.6", + "@babel/types@7.18.9" + ], + "Locations": [ + { + "StartLine": 252, + "EndLine": 264 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@babel/helper-hoist-variables@7.18.6", + "Name": "@babel/helper-hoist-variables", + "Identifier": { + "PURL": "pkg:npm/%40babel/helper-hoist-variables@7.18.6", + "UID": "8b51a624b1f38801" + }, + "Version": "7.18.6", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@babel/types@7.18.9" + ], + "Locations": [ + { + "StartLine": 265, + "EndLine": 276 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@babel/helper-module-imports@7.16.7", + "Name": "@babel/helper-module-imports", + "Identifier": { + "PURL": "pkg:npm/%40babel/helper-module-imports@7.16.7", + "UID": "815261f052013343" + }, + "Version": "7.16.7", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@babel/types@7.18.9" + ], + "Locations": [ + { + "StartLine": 289, + "EndLine": 299 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@babel/helper-module-transforms@7.17.6", + "Name": "@babel/helper-module-transforms", + "Identifier": { + "PURL": "pkg:npm/%40babel/helper-module-transforms@7.17.6", + "UID": "463b953af82c30bd" + }, + "Version": "7.17.6", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@babel/helper-environment-visitor@7.18.9", + "@babel/helper-module-imports@7.16.7", + "@babel/helper-simple-access@7.16.7", + "@babel/helper-split-export-declaration@7.18.6", + "@babel/helper-validator-identifier@7.18.6", + "@babel/template@7.18.6", + "@babel/traverse@7.18.9", + "@babel/types@7.18.9" + ], + "Locations": [ + { + "StartLine": 300, + "EndLine": 318 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@babel/helper-simple-access@7.16.7", + "Name": "@babel/helper-simple-access", + "Identifier": { + "PURL": "pkg:npm/%40babel/helper-simple-access@7.16.7", + "UID": "5f55df72c58d396e" + }, + "Version": "7.16.7", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@babel/types@7.18.9" + ], + "Locations": [ + { + "StartLine": 370, + "EndLine": 381 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@babel/helper-split-export-declaration@7.18.6", + "Name": "@babel/helper-split-export-declaration", + "Identifier": { + "PURL": "pkg:npm/%40babel/helper-split-export-declaration@7.18.6", + "UID": "ea522c5fb8641cbc" + }, + "Version": "7.18.6", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@babel/types@7.18.9" + ], + "Locations": [ + { + "StartLine": 394, + "EndLine": 405 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@babel/helper-validator-identifier@7.18.6", + "Name": "@babel/helper-validator-identifier", + "Identifier": { + "PURL": "pkg:npm/%40babel/helper-validator-identifier@7.18.6", + "UID": "f37265b901739ab0" + }, + "Version": "7.18.6", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 406, + "EndLine": 413 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@babel/helper-validator-option@7.18.6", + "Name": "@babel/helper-validator-option", + "Identifier": { + "PURL": "pkg:npm/%40babel/helper-validator-option@7.18.6", + "UID": "49b0d477f8b8fe46" + }, + "Version": "7.18.6", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 414, + "EndLine": 422 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@babel/helpers@7.17.2", + "Name": "@babel/helpers", + "Identifier": { + "PURL": "pkg:npm/%40babel/helpers@7.17.2", + "UID": "73434025ffc769ba" + }, + "Version": "7.17.2", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@babel/template@7.18.6", + "@babel/traverse@7.18.9", + "@babel/types@7.18.9" + ], + "Locations": [ + { + "StartLine": 438, + "EndLine": 451 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@babel/highlight@7.18.6", + "Name": "@babel/highlight", + "Identifier": { + "PURL": "pkg:npm/%40babel/highlight@7.18.6", + "UID": "519990e367ae9fcd" + }, + "Version": "7.18.6", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@babel/helper-validator-identifier@7.18.6", + "chalk@2.4.2", + "js-tokens@4.0.0" + ], + "Locations": [ + { + "StartLine": 452, + "EndLine": 464 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@babel/parser@7.18.9", + "Name": "@babel/parser", + "Identifier": { + "PURL": "pkg:npm/%40babel/parser@7.18.9", + "UID": "ed32472c94dad5c8" + }, + "Version": "7.18.9", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 465, + "EndLine": 476 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@babel/runtime@7.23.2", + "Name": "@babel/runtime", + "Identifier": { + "PURL": "pkg:npm/%40babel/runtime@7.23.2", + "UID": "a263c07ce5d88868" + }, + "Version": "7.23.2", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "regenerator-runtime@0.14.0" + ], + "Locations": [ + { + "StartLine": 1693, + "EndLine": 1703 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@babel/template@7.18.6", + "Name": "@babel/template", + "Identifier": { + "PURL": "pkg:npm/%40babel/template@7.18.6", + "UID": "c7b10567647dbadd" + }, + "Version": "7.18.6", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@babel/code-frame@7.18.6", + "@babel/parser@7.18.9", + "@babel/types@7.18.9" + ], + "Locations": [ + { + "StartLine": 1709, + "EndLine": 1722 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@babel/traverse@7.18.9", + "Name": "@babel/traverse", + "Identifier": { + "PURL": "pkg:npm/%40babel/traverse@7.18.9", + "UID": "4a85c92d0db3846c" + }, + "Version": "7.18.9", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@babel/code-frame@7.18.6", + "@babel/generator@7.18.9", + "@babel/helper-environment-visitor@7.18.9", + "@babel/helper-function-name@7.18.9", + "@babel/helper-hoist-variables@7.18.6", + "@babel/helper-split-export-declaration@7.18.6", + "@babel/parser@7.18.9", + "@babel/types@7.18.9", + "debug@4.3.3", + "globals@11.12.0" + ], + "Locations": [ + { + "StartLine": 1723, + "EndLine": 1743 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@babel/types@7.18.9", + "Name": "@babel/types", + "Identifier": { + "PURL": "pkg:npm/%40babel/types@7.18.9", + "UID": "edcdf7942269e1c9" + }, + "Version": "7.18.9", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@babel/helper-validator-identifier@7.18.6", + "to-fast-properties@2.0.0" + ], + "Locations": [ + { + "StartLine": 1744, + "EndLine": 1755 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@emotion/babel-plugin@11.11.0", + "Name": "@emotion/babel-plugin", + "Identifier": { + "PURL": "pkg:npm/%40emotion/babel-plugin@11.11.0", + "UID": "4df42ee8d4183ca5" + }, + "Version": "11.11.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@babel/helper-module-imports@7.16.7", + "@babel/runtime@7.23.2", + "@emotion/hash@0.9.1", + "@emotion/memoize@0.8.1", + "@emotion/serialize@1.1.2", + "babel-plugin-macros@3.1.0", + "convert-source-map@1.8.0", + "escape-string-regexp@4.0.0", + "find-root@1.1.0", + "source-map@0.5.7", + "stylis@4.2.0" + ], + "Locations": [ + { + "StartLine": 1789, + "EndLine": 1806 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@emotion/cache@11.11.0", + "Name": "@emotion/cache", + "Identifier": { + "PURL": "pkg:npm/%40emotion/cache@11.11.0", + "UID": "15ed534817999b1e" + }, + "Version": "11.11.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@emotion/memoize@0.8.1", + "@emotion/sheet@1.2.2", + "@emotion/utils@1.2.1", + "@emotion/weak-memoize@0.3.1", + "stylis@4.2.0" + ], + "Locations": [ + { + "StartLine": 1823, + "EndLine": 1834 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@emotion/hash@0.9.1", + "Name": "@emotion/hash", + "Identifier": { + "PURL": "pkg:npm/%40emotion/hash@0.9.1", + "UID": "1bf6ca873b4e2b28" + }, + "Version": "0.9.1", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 1840, + "EndLine": 1844 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@emotion/is-prop-valid@0.8.8", + "Name": "@emotion/is-prop-valid", + "Identifier": { + "PURL": "pkg:npm/%40emotion/is-prop-valid@0.8.8", + "UID": "9122545e1ed6f222" + }, + "Version": "0.8.8", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@emotion/memoize@0.7.4" + ], + "Locations": [ + { + "StartLine": 4867, + "EndLine": 4875 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@emotion/is-prop-valid@1.1.2", + "Name": "@emotion/is-prop-valid", + "Identifier": { + "PURL": "pkg:npm/%40emotion/is-prop-valid@1.1.2", + "UID": "bf2f1f32eafe885e" + }, + "Version": "1.1.2", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@emotion/memoize@0.7.5" + ], + "Locations": [ + { + "StartLine": 1845, + "EndLine": 1852 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@emotion/memoize@0.7.4", + "Name": "@emotion/memoize", + "Identifier": { + "PURL": "pkg:npm/%40emotion/memoize@0.7.4", + "UID": "1ad944e40f7bc43f" + }, + "Version": "0.7.4", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 4876, + "EndLine": 4881 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@emotion/memoize@0.7.5", + "Name": "@emotion/memoize", + "Identifier": { + "PURL": "pkg:npm/%40emotion/memoize@0.7.5", + "UID": "dd953c40a67ec065" + }, + "Version": "0.7.5", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 1853, + "EndLine": 1857 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@emotion/memoize@0.8.1", + "Name": "@emotion/memoize", + "Identifier": { + "PURL": "pkg:npm/%40emotion/memoize@0.8.1", + "UID": "ef9e0047365b73e7" + }, + "Version": "0.8.1", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 1807, + "EndLine": 1811 + }, + { + "StartLine": 1835, + "EndLine": 1839 + }, + { + "StartLine": 1893, + "EndLine": 1897 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@emotion/serialize@1.1.2", + "Name": "@emotion/serialize", + "Identifier": { + "PURL": "pkg:npm/%40emotion/serialize@1.1.2", + "UID": "55faf3de44c24779" + }, + "Version": "1.1.2", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@emotion/hash@0.9.1", + "@emotion/memoize@0.8.1", + "@emotion/unitless@0.8.1", + "@emotion/utils@1.2.1", + "csstype@3.1.2" + ], + "Locations": [ + { + "StartLine": 1881, + "EndLine": 1892 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@emotion/sheet@1.2.2", + "Name": "@emotion/sheet", + "Identifier": { + "PURL": "pkg:npm/%40emotion/sheet@1.2.2", + "UID": "1d46775f76a35aae" + }, + "Version": "1.2.2", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 1898, + "EndLine": 1902 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@emotion/unitless@0.8.1", + "Name": "@emotion/unitless", + "Identifier": { + "PURL": "pkg:npm/%40emotion/unitless@0.8.1", + "UID": "38411883f3657437" + }, + "Version": "0.8.1", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 1928, + "EndLine": 1932 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@emotion/use-insertion-effect-with-fallbacks@1.0.1", + "Name": "@emotion/use-insertion-effect-with-fallbacks", + "Identifier": { + "PURL": "pkg:npm/%40emotion/use-insertion-effect-with-fallbacks@1.0.1", + "UID": "cc6ccd7b3b5ed52d" + }, + "Version": "1.0.1", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "react@17.0.2" + ], + "Locations": [ + { + "StartLine": 1933, + "EndLine": 1940 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@emotion/utils@1.2.1", + "Name": "@emotion/utils", + "Identifier": { + "PURL": "pkg:npm/%40emotion/utils@1.2.1", + "UID": "eebcb7a0c1e38537" + }, + "Version": "1.2.1", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 1941, + "EndLine": 1945 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@emotion/weak-memoize@0.3.1", + "Name": "@emotion/weak-memoize", + "Identifier": { + "PURL": "pkg:npm/%40emotion/weak-memoize@0.3.1", + "UID": "ddc22859d76d894c" + }, + "Version": "0.3.1", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 1946, + "EndLine": 1950 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@floating-ui/core@1.5.0", + "Name": "@floating-ui/core", + "Identifier": { + "PURL": "pkg:npm/%40floating-ui/core@1.5.0", + "UID": "95376197ebb5974f" + }, + "Version": "1.5.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@floating-ui/utils@0.1.6" + ], + "Locations": [ + { + "StartLine": 1951, + "EndLine": 1958 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@floating-ui/dom@1.5.3", + "Name": "@floating-ui/dom", + "Identifier": { + "PURL": "pkg:npm/%40floating-ui/dom@1.5.3", + "UID": "5b318e5a680e75b2" + }, + "Version": "1.5.3", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@floating-ui/core@1.5.0", + "@floating-ui/utils@0.1.6" + ], + "Locations": [ + { + "StartLine": 1959, + "EndLine": 1967 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@floating-ui/react-dom@2.0.2", + "Name": "@floating-ui/react-dom", + "Identifier": { + "PURL": "pkg:npm/%40floating-ui/react-dom@2.0.2", + "UID": "81446ce3571bc49a" + }, + "Version": "2.0.2", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@floating-ui/dom@1.5.3", + "react-dom@17.0.2", + "react@17.0.2" + ], + "Locations": [ + { + "StartLine": 1968, + "EndLine": 1979 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@floating-ui/utils@0.1.6", + "Name": "@floating-ui/utils", + "Identifier": { + "PURL": "pkg:npm/%40floating-ui/utils@0.1.6", + "UID": "f3172a090281a9a3" + }, + "Version": "0.1.6", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 1980, + "EndLine": 1984 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@jridgewell/gen-mapping@0.3.2", + "Name": "@jridgewell/gen-mapping", + "Identifier": { + "PURL": "pkg:npm/%40jridgewell/gen-mapping@0.3.2", + "UID": "60afe7c264d68de7" + }, + "Version": "0.3.2", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@jridgewell/set-array@1.1.2", + "@jridgewell/sourcemap-codec@1.4.11", + "@jridgewell/trace-mapping@0.3.14" + ], + "Locations": [ + { + "StartLine": 1985, + "EndLine": 1998 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@jridgewell/resolve-uri@3.0.5", + "Name": "@jridgewell/resolve-uri", + "Identifier": { + "PURL": "pkg:npm/%40jridgewell/resolve-uri@3.0.5", + "UID": "308b98d3a3f867e8" + }, + "Version": "3.0.5", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 1999, + "EndLine": 2007 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@jridgewell/set-array@1.1.2", + "Name": "@jridgewell/set-array", + "Identifier": { + "PURL": "pkg:npm/%40jridgewell/set-array@1.1.2", + "UID": "f74c915a2c465c00" + }, + "Version": "1.1.2", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 2008, + "EndLine": 2016 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@jridgewell/sourcemap-codec@1.4.11", + "Name": "@jridgewell/sourcemap-codec", + "Identifier": { + "PURL": "pkg:npm/%40jridgewell/sourcemap-codec@1.4.11", + "UID": "3a584137afd3f9f1" + }, + "Version": "1.4.11", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 2027, + "EndLine": 2032 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@jridgewell/trace-mapping@0.3.14", + "Name": "@jridgewell/trace-mapping", + "Identifier": { + "PURL": "pkg:npm/%40jridgewell/trace-mapping@0.3.14", + "UID": "3ea2960168a4da63" + }, + "Version": "0.3.14", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@jridgewell/resolve-uri@3.0.5", + "@jridgewell/sourcemap-codec@1.4.11" + ], + "Locations": [ + { + "StartLine": 2033, + "EndLine": 2042 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@mui/base@5.0.0-beta.21", + "Name": "@mui/base", + "Identifier": { + "PURL": "pkg:npm/%40mui/base@5.0.0-beta.21", + "UID": "68ea20c927b98690" + }, + "Version": "5.0.0-beta.21", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@babel/runtime@7.23.2", + "@floating-ui/react-dom@2.0.2", + "@mui/types@7.2.7", + "@mui/utils@5.14.15", + "@popperjs/core@2.11.8", + "@types/react@17.0.39", + "clsx@2.0.0", + "prop-types@15.8.1", + "react-dom@17.0.2", + "react@17.0.2" + ], + "Locations": [ + { + "StartLine": 2043, + "EndLine": 2073 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@mui/core-downloads-tracker@5.14.15", + "Name": "@mui/core-downloads-tracker", + "Identifier": { + "PURL": "pkg:npm/%40mui/core-downloads-tracker@5.14.15", + "UID": "fbbcd30ae350415f" + }, + "Version": "5.14.15", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 2082, + "EndLine": 2090 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@mui/private-theming@5.14.15", + "Name": "@mui/private-theming", + "Identifier": { + "PURL": "pkg:npm/%40mui/private-theming@5.14.15", + "UID": "f5abeae0d6e5ccdc" + }, + "Version": "5.14.15", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@babel/runtime@7.23.2", + "@mui/utils@5.14.15", + "@types/react@17.0.39", + "prop-types@15.8.1", + "react@17.0.2" + ], + "Locations": [ + { + "StartLine": 2173, + "EndLine": 2198 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@mui/styled-engine@5.14.15", + "Name": "@mui/styled-engine", + "Identifier": { + "PURL": "pkg:npm/%40mui/styled-engine@5.14.15", + "UID": "7a11d54f28a79011" + }, + "Version": "5.14.15", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@babel/runtime@7.23.2", + "@emotion/cache@11.11.0", + "@emotion/react@11.11.1", + "@emotion/styled@11.8.1", + "csstype@3.1.2", + "prop-types@15.8.1", + "react@17.0.2" + ], + "Locations": [ + { + "StartLine": 2199, + "EndLine": 2229 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@mui/system@5.14.15", + "Name": "@mui/system", + "Identifier": { + "PURL": "pkg:npm/%40mui/system@5.14.15", + "UID": "dd3412093437633b" + }, + "Version": "5.14.15", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@babel/runtime@7.23.2", + "@emotion/react@11.11.1", + "@emotion/styled@11.8.1", + "@mui/private-theming@5.14.15", + "@mui/styled-engine@5.14.15", + "@mui/types@7.2.7", + "@mui/utils@5.14.15", + "@types/react@17.0.39", + "clsx@2.0.0", + "csstype@3.1.2", + "prop-types@15.8.1", + "react@17.0.2" + ], + "Locations": [ + { + "StartLine": 2230, + "EndLine": 2268 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@mui/types@7.2.7", + "Name": "@mui/types", + "Identifier": { + "PURL": "pkg:npm/%40mui/types@7.2.7", + "UID": "deded1aafe3bbea" + }, + "Version": "7.2.7", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@types/react@17.0.39" + ], + "Locations": [ + { + "StartLine": 2277, + "EndLine": 2289 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@mui/utils@5.14.15", + "Name": "@mui/utils", + "Identifier": { + "PURL": "pkg:npm/%40mui/utils@5.14.15", + "UID": "9116dcf588b522ba" + }, + "Version": "5.14.15", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@babel/runtime@7.23.2", + "@types/prop-types@15.7.9", + "@types/react@17.0.39", + "prop-types@15.8.1", + "react-is@18.2.0", + "react@17.0.2" + ], + "Locations": [ + { + "StartLine": 2290, + "EndLine": 2316 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@popperjs/core@2.11.8", + "Name": "@popperjs/core", + "Identifier": { + "PURL": "pkg:npm/%40popperjs/core@2.11.8", + "UID": "d4df5e4442ecc59a" + }, + "Version": "2.11.8", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 2453, + "EndLine": 2461 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@types/json-schema@7.0.15", + "Name": "@types/json-schema", + "Identifier": { + "PURL": "pkg:npm/%40types/json-schema@7.0.15", + "UID": "7175ced1a0190607" + }, + "Version": "7.0.15", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 2564, + "EndLine": 2569 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@types/parse-json@4.0.0", + "Name": "@types/parse-json", + "Identifier": { + "PURL": "pkg:npm/%40types/parse-json@4.0.0", + "UID": "ce4e29cf7fa8f3c3" + }, + "Version": "4.0.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 2582, + "EndLine": 2586 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@types/prop-types@15.7.9", + "Name": "@types/prop-types", + "Identifier": { + "PURL": "pkg:npm/%40types/prop-types@15.7.9", + "UID": "4aaa9064291bee85" + }, + "Version": "15.7.9", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 2587, + "EndLine": 2591 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@types/react-transition-group@4.4.8", + "Name": "@types/react-transition-group", + "Identifier": { + "PURL": "pkg:npm/%40types/react-transition-group@4.4.8", + "UID": "109c5ef46024ff62" + }, + "Version": "4.4.8", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@types/react@17.0.39" + ], + "Locations": [ + { + "StartLine": 2623, + "EndLine": 2630 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "@types/scheduler@0.16.2", + "Name": "@types/scheduler", + "Identifier": { + "PURL": "pkg:npm/%40types/scheduler@0.16.2", + "UID": "514d17137158b75f" + }, + "Version": "0.16.2", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 2637, + "EndLine": 2641 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "ansi-styles@3.2.1", + "Name": "ansi-styles", + "Identifier": { + "PURL": "pkg:npm/ansi-styles@3.2.1", + "UID": "2f9cfed2e02a50d2" + }, + "Version": "3.2.1", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "color-convert@1.9.3" + ], + "Locations": [ + { + "StartLine": 3008, + "EndLine": 3018 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "babel-plugin-macros@3.1.0", + "Name": "babel-plugin-macros", + "Identifier": { + "PURL": "pkg:npm/babel-plugin-macros@3.1.0", + "UID": "bc149be0ef5d0d1c" + }, + "Version": "3.1.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@babel/runtime@7.23.2", + "cosmiconfig@7.1.0", + "resolve@1.22.0" + ], + "Locations": [ + { + "StartLine": 3196, + "EndLine": 3209 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "balanced-match@1.0.2", + "Name": "balanced-match", + "Identifier": { + "PURL": "pkg:npm/balanced-match@1.0.2", + "UID": "f31a871a36c8a40a" + }, + "Version": "1.0.2", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 3361, + "EndLine": 3365 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "big-integer@1.6.51", + "Name": "big-integer", + "Identifier": { + "PURL": "pkg:npm/big-integer@1.6.51", + "UID": "713efce95b1770f0" + }, + "Version": "1.6.51", + "Licenses": [ + "Unlicense" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 3372, + "EndLine": 3379 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "brace-expansion@1.1.11", + "Name": "brace-expansion", + "Identifier": { + "PURL": "pkg:npm/brace-expansion@1.1.11", + "UID": "4ea94b15f15f23cd" + }, + "Version": "1.1.11", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "balanced-match@1.0.2", + "concat-map@0.0.1" + ], + "Locations": [ + { + "StartLine": 3463, + "EndLine": 3471 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "broadcast-channel@3.7.0", + "Name": "broadcast-channel", + "Identifier": { + "PURL": "pkg:npm/broadcast-channel@3.7.0", + "UID": "5556f02c308390b4" + }, + "Version": "3.7.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@babel/runtime@7.23.2", + "detect-node@2.1.0", + "js-sha3@0.8.0", + "microseconds@0.2.0", + "nano-time@1.0.0", + "oblivious-set@1.0.0", + "rimraf@3.0.2", + "unload@2.2.0" + ], + "Locations": [ + { + "StartLine": 3484, + "EndLine": 3498 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "browserslist@4.19.3", + "Name": "browserslist", + "Identifier": { + "PURL": "pkg:npm/browserslist@4.19.3", + "UID": "c09ff45476aa3607" + }, + "Version": "4.19.3", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "caniuse-lite@1.0.30001313", + "electron-to-chromium@1.4.76", + "escalade@3.1.1", + "node-releases@2.0.2", + "picocolors@1.0.0" + ], + "Locations": [ + { + "StartLine": 3499, + "EndLine": 3521 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "callsites@3.1.0", + "Name": "callsites", + "Identifier": { + "PURL": "pkg:npm/callsites@3.1.0", + "UID": "f874ebdda1e422c6" + }, + "Version": "3.1.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 3556, + "EndLine": 3563 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "caniuse-lite@1.0.30001313", + "Name": "caniuse-lite", + "Identifier": { + "PURL": "pkg:npm/caniuse-lite@1.0.30001313", + "UID": "d295cf9ff804f047" + }, + "Version": "1.0.30001313", + "Licenses": [ + "CC-BY-4.0" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 3574, + "EndLine": 3583 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "chalk@2.4.2", + "Name": "chalk", + "Identifier": { + "PURL": "pkg:npm/chalk@2.4.2", + "UID": "35be92659349157e" + }, + "Version": "2.4.2", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "ansi-styles@3.2.1", + "escape-string-regexp@1.0.5", + "supports-color@5.5.0" + ], + "Locations": [ + { + "StartLine": 3584, + "EndLine": 3596 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "clsx@1.1.1", + "Name": "clsx", + "Identifier": { + "PURL": "pkg:npm/clsx@1.1.1", + "UID": "46007e6037073301" + }, + "Version": "1.1.1", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 3690, + "EndLine": 3697 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "clsx@2.0.0", + "Name": "clsx", + "Identifier": { + "PURL": "pkg:npm/clsx@2.0.0", + "UID": "a26ec626382f76d" + }, + "Version": "2.0.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 2074, + "EndLine": 2081 + }, + { + "StartLine": 2160, + "EndLine": 2167 + }, + { + "StartLine": 2269, + "EndLine": 2276 + }, + { + "StartLine": 2410, + "EndLine": 2417 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "color-convert@1.9.3", + "Name": "color-convert", + "Identifier": { + "PURL": "pkg:npm/color-convert@1.9.3", + "UID": "5a305e816f2f3e49" + }, + "Version": "1.9.3", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "color-name@1.1.3" + ], + "Locations": [ + { + "StartLine": 3698, + "EndLine": 3705 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "color-name@1.1.3", + "Name": "color-name", + "Identifier": { + "PURL": "pkg:npm/color-name@1.1.3", + "UID": "3876bf258abde8f6" + }, + "Version": "1.1.3", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 3706, + "EndLine": 3710 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "concat-map@0.0.1", + "Name": "concat-map", + "Identifier": { + "PURL": "pkg:npm/concat-map@0.0.1", + "UID": "460dd4e733d68127" + }, + "Version": "0.0.1", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 3774, + "EndLine": 3778 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "convert-source-map@1.8.0", + "Name": "convert-source-map", + "Identifier": { + "PURL": "pkg:npm/convert-source-map@1.8.0", + "UID": "93c7faa0e7c504a5" + }, + "Version": "1.8.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "safe-buffer@5.1.2" + ], + "Locations": [ + { + "StartLine": 3829, + "EndLine": 3836 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "cosmiconfig@7.1.0", + "Name": "cosmiconfig", + "Identifier": { + "PURL": "pkg:npm/cosmiconfig@7.1.0", + "UID": "eb0d613ec34413bb" + }, + "Version": "7.1.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@types/parse-json@4.0.0", + "import-fresh@3.3.0", + "parse-json@5.2.0", + "path-type@4.0.0", + "yaml@1.10.2" + ], + "Locations": [ + { + "StartLine": 3889, + "EndLine": 3903 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "csstype@3.1.2", + "Name": "csstype", + "Identifier": { + "PURL": "pkg:npm/csstype@3.1.2", + "UID": "b0256288aa0f9dc8" + }, + "Version": "3.1.2", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 3999, + "EndLine": 4003 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "debug@4.3.3", + "Name": "debug", + "Identifier": { + "PURL": "pkg:npm/debug@4.3.3", + "UID": "41d59586a04d7300" + }, + "Version": "4.3.3", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "ms@2.1.2" + ], + "Locations": [ + { + "StartLine": 4024, + "EndLine": 4040 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "detect-node@2.1.0", + "Name": "detect-node", + "Identifier": { + "PURL": "pkg:npm/detect-node@2.1.0", + "UID": "5021e9f11ecfa0f8" + }, + "Version": "2.1.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 4141, + "EndLine": 4145 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "dom-helpers@5.2.1", + "Name": "dom-helpers", + "Identifier": { + "PURL": "pkg:npm/dom-helpers@5.2.1", + "UID": "8a47b482ef7c502" + }, + "Version": "5.2.1", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@babel/runtime@7.23.2", + "csstype@3.1.2" + ], + "Locations": [ + { + "StartLine": 4192, + "EndLine": 4200 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "electron-to-chromium@1.4.76", + "Name": "electron-to-chromium", + "Identifier": { + "PURL": "pkg:npm/electron-to-chromium@1.4.76", + "UID": "f4d4c74cbada13e9" + }, + "Version": "1.4.76", + "Licenses": [ + "ISC" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 4272, + "EndLine": 4277 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "error-ex@1.3.2", + "Name": "error-ex", + "Identifier": { + "PURL": "pkg:npm/error-ex@1.3.2", + "UID": "bff1d3c9b6a74b2e" + }, + "Version": "1.3.2", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "is-arrayish@0.2.1" + ], + "Locations": [ + { + "StartLine": 4330, + "EndLine": 4337 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "escalade@3.1.1", + "Name": "escalade", + "Identifier": { + "PURL": "pkg:npm/escalade@3.1.1", + "UID": "b8b2ff942456492c" + }, + "Version": "3.1.1", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 4344, + "EndLine": 4352 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "escape-string-regexp@1.0.5", + "Name": "escape-string-regexp", + "Identifier": { + "PURL": "pkg:npm/escape-string-regexp@1.0.5", + "UID": "9ddb71baaed0768d" + }, + "Version": "1.0.5", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 4359, + "EndLine": 4366 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "escape-string-regexp@4.0.0", + "Name": "escape-string-regexp", + "Identifier": { + "PURL": "pkg:npm/escape-string-regexp@4.0.0", + "UID": "8177bf231b9b688a" + }, + "Version": "4.0.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 1812, + "EndLine": 1822 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "find-root@1.1.0", + "Name": "find-root", + "Identifier": { + "PURL": "pkg:npm/find-root@1.1.0", + "UID": "e6543a915ec7b507" + }, + "Version": "1.1.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 4665, + "EndLine": 4669 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "follow-redirects@1.14.9", + "Name": "follow-redirects", + "Identifier": { + "PURL": "pkg:npm/follow-redirects@1.14.9", + "UID": "dc97ccb86bb0a662" + }, + "Version": "1.14.9", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 4683, + "EndLine": 4701 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "framesync@6.0.1", + "Name": "framesync", + "Identifier": { + "PURL": "pkg:npm/framesync@6.0.1", + "UID": "89cb116749c12589" + }, + "Version": "6.0.1", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "tslib@2.3.1" + ], + "Locations": [ + { + "StartLine": 4882, + "EndLine": 4889 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "fs.realpath@1.0.0", + "Name": "fs.realpath", + "Identifier": { + "PURL": "pkg:npm/fs.realpath@1.0.0", + "UID": "55af3fe60acb3b75" + }, + "Version": "1.0.0", + "Licenses": [ + "ISC" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 4919, + "EndLine": 4923 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "function-bind@1.1.1", + "Name": "function-bind", + "Identifier": { + "PURL": "pkg:npm/function-bind@1.1.1", + "UID": "c033678758b7ed40" + }, + "Version": "1.1.1", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 4938, + "EndLine": 4942 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "gensync@1.0.0-beta.2", + "Name": "gensync", + "Identifier": { + "PURL": "pkg:npm/gensync@1.0.0-beta.2", + "UID": "616723f15d1e2ae6" + }, + "Version": "1.0.0-beta.2", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 4952, + "EndLine": 4960 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "glob@7.2.0", + "Name": "glob", + "Identifier": { + "PURL": "pkg:npm/glob@7.2.0", + "UID": "f029c12c84b452d9" + }, + "Version": "7.2.0", + "Licenses": [ + "ISC" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "fs.realpath@1.0.0", + "inflight@1.0.6", + "inherits@2.0.4", + "minimatch@3.1.2", + "once@1.4.0", + "path-is-absolute@1.0.1" + ], + "Locations": [ + { + "StartLine": 4987, + "EndLine": 5005 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "globals@11.12.0", + "Name": "globals", + "Identifier": { + "PURL": "pkg:npm/globals@11.12.0", + "UID": "32293af937f8446" + }, + "Version": "11.12.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 5024, + "EndLine": 5032 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "has@1.0.3", + "Name": "has", + "Identifier": { + "PURL": "pkg:npm/has@1.0.3", + "UID": "c8521f8c605fa06b" + }, + "Version": "1.0.3", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "function-bind@1.1.1" + ], + "Locations": [ + { + "StartLine": 5065, + "EndLine": 5075 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "has-flag@3.0.0", + "Name": "has-flag", + "Identifier": { + "PURL": "pkg:npm/has-flag@3.0.0", + "UID": "be518d5ab2cc3779" + }, + "Version": "3.0.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 5097, + "EndLine": 5104 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "hey-listen@1.0.8", + "Name": "hey-listen", + "Identifier": { + "PURL": "pkg:npm/hey-listen@1.0.8", + "UID": "66154369f8f9384c" + }, + "Version": "1.0.8", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 5153, + "EndLine": 5157 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "history@5.3.0", + "Name": "history", + "Identifier": { + "PURL": "pkg:npm/history@5.3.0", + "UID": "bc93e47512e6e0b5" + }, + "Version": "5.3.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@babel/runtime@7.23.2" + ], + "Locations": [ + { + "StartLine": 5158, + "EndLine": 5165 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "hoist-non-react-statics@3.3.2", + "Name": "hoist-non-react-statics", + "Identifier": { + "PURL": "pkg:npm/hoist-non-react-statics@3.3.2", + "UID": "e3301c092d45aa98" + }, + "Version": "3.3.2", + "Licenses": [ + "BSD-3-Clause" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "react-is@16.13.1" + ], + "Locations": [ + { + "StartLine": 5166, + "EndLine": 5173 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "import-fresh@3.3.0", + "Name": "import-fresh", + "Identifier": { + "PURL": "pkg:npm/import-fresh@3.3.0", + "UID": "ea778bf21cebf75c" + }, + "Version": "3.3.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "parent-module@1.0.1", + "resolve-from@4.0.0" + ], + "Locations": [ + { + "StartLine": 5396, + "EndLine": 5410 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "inflight@1.0.6", + "Name": "inflight", + "Identifier": { + "PURL": "pkg:npm/inflight@1.0.6", + "UID": "7cc1daf0f0c0b420" + }, + "Version": "1.0.6", + "Licenses": [ + "ISC" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "once@1.4.0", + "wrappy@1.0.2" + ], + "Locations": [ + { + "StartLine": 5447, + "EndLine": 5455 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "inherits@2.0.4", + "Name": "inherits", + "Identifier": { + "PURL": "pkg:npm/inherits@2.0.4", + "UID": "30c43b7391a3c096" + }, + "Version": "2.0.4", + "Licenses": [ + "ISC" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 5456, + "EndLine": 5460 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "is-arrayish@0.2.1", + "Name": "is-arrayish", + "Identifier": { + "PURL": "pkg:npm/is-arrayish@0.2.1", + "UID": "6f313fb335ef58b6" + }, + "Version": "0.2.1", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 5510, + "EndLine": 5514 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "is-core-module@2.8.1", + "Name": "is-core-module", + "Identifier": { + "PURL": "pkg:npm/is-core-module@2.8.1", + "UID": "6e3a6add15487426" + }, + "Version": "2.8.1", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "has@1.0.3" + ], + "Locations": [ + { + "StartLine": 5527, + "EndLine": 5537 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "js-sha3@0.8.0", + "Name": "js-sha3", + "Identifier": { + "PURL": "pkg:npm/js-sha3@0.8.0", + "UID": "133b98dda8b7fa4a" + }, + "Version": "0.8.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 5739, + "EndLine": 5743 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "js-tokens@4.0.0", + "Name": "js-tokens", + "Identifier": { + "PURL": "pkg:npm/js-tokens@4.0.0", + "UID": "603273bc3043fcc9" + }, + "Version": "4.0.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 5744, + "EndLine": 5748 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "jsesc@2.5.2", + "Name": "jsesc", + "Identifier": { + "PURL": "pkg:npm/jsesc@2.5.2", + "UID": "7cc8378e669b88a8" + }, + "Version": "2.5.2", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 5749, + "EndLine": 5760 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "json-parse-even-better-errors@2.3.1", + "Name": "json-parse-even-better-errors", + "Identifier": { + "PURL": "pkg:npm/json-parse-even-better-errors@2.3.1", + "UID": "e0f8c45a534c594a" + }, + "Version": "2.3.1", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 5767, + "EndLine": 5771 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "json5@2.2.0", + "Name": "json5", + "Identifier": { + "PURL": "pkg:npm/json5@2.2.0", + "UID": "ca319a23f8885c6e" + }, + "Version": "2.2.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "minimist@1.2.6" + ], + "Locations": [ + { + "StartLine": 5778, + "EndLine": 5792 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "lines-and-columns@1.2.4", + "Name": "lines-and-columns", + "Identifier": { + "PURL": "pkg:npm/lines-and-columns@1.2.4", + "UID": "57e13fbb67030a7b" + }, + "Version": "1.2.4", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 5814, + "EndLine": 5818 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "loose-envify@1.4.0", + "Name": "loose-envify", + "Identifier": { + "PURL": "pkg:npm/loose-envify@1.4.0", + "UID": "13c41b2daf1f4329" + }, + "Version": "1.4.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "js-tokens@4.0.0" + ], + "Locations": [ + { + "StartLine": 5878, + "EndLine": 5888 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "match-sorter@6.3.1", + "Name": "match-sorter", + "Identifier": { + "PURL": "pkg:npm/match-sorter@6.3.1", + "UID": "92a4130433f0ecef" + }, + "Version": "6.3.1", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@babel/runtime@7.23.2", + "remove-accents@0.4.2" + ], + "Locations": [ + { + "StartLine": 5925, + "EndLine": 5933 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "microseconds@0.2.0", + "Name": "microseconds", + "Identifier": { + "PURL": "pkg:npm/microseconds@0.2.0", + "UID": "1b1ed76ec8f2581" + }, + "Version": "0.2.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 5998, + "EndLine": 6002 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "minimatch@3.1.2", + "Name": "minimatch", + "Identifier": { + "PURL": "pkg:npm/minimatch@3.1.2", + "UID": "b5e061939f2d832f" + }, + "Version": "3.1.2", + "Licenses": [ + "ISC" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "brace-expansion@1.1.11" + ], + "Locations": [ + { + "StartLine": 6051, + "EndLine": 6061 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "minimist@1.2.6", + "Name": "minimist", + "Identifier": { + "PURL": "pkg:npm/minimist@1.2.6", + "UID": "eae154a6389becf5" + }, + "Version": "1.2.6", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 6062, + "EndLine": 6067 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "ms@2.1.2", + "Name": "ms", + "Identifier": { + "PURL": "pkg:npm/ms@2.1.2", + "UID": "5c41772c98cb2da8" + }, + "Version": "2.1.2", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 6080, + "EndLine": 6085 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "nano-time@1.0.0", + "Name": "nano-time", + "Identifier": { + "PURL": "pkg:npm/nano-time@1.0.0", + "UID": "250bcd643cc0508" + }, + "Version": "1.0.0", + "Licenses": [ + "ISC" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "big-integer@1.6.51" + ], + "Locations": [ + { + "StartLine": 6105, + "EndLine": 6112 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "node-releases@2.0.2", + "Name": "node-releases", + "Identifier": { + "PURL": "pkg:npm/node-releases@2.0.2", + "UID": "d43659f89d795fd8" + }, + "Version": "2.0.2", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 6165, + "EndLine": 6170 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "object-assign@4.1.1", + "Name": "object-assign", + "Identifier": { + "PURL": "pkg:npm/object-assign@4.1.1", + "UID": "1b465699b5916b54" + }, + "Version": "4.1.1", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 6204, + "EndLine": 6211 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "oblivious-set@1.0.0", + "Name": "oblivious-set", + "Identifier": { + "PURL": "pkg:npm/oblivious-set@1.0.0", + "UID": "e5baa4f4965f085a" + }, + "Version": "1.0.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 6255, + "EndLine": 6259 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "once@1.4.0", + "Name": "once", + "Identifier": { + "PURL": "pkg:npm/once@1.4.0", + "UID": "e9d0ff4be88ed15a" + }, + "Version": "1.4.0", + "Licenses": [ + "ISC" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "wrappy@1.0.2" + ], + "Locations": [ + { + "StartLine": 6287, + "EndLine": 6294 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "parent-module@1.0.1", + "Name": "parent-module", + "Identifier": { + "PURL": "pkg:npm/parent-module@1.0.1", + "UID": "f3decc757b149a74" + }, + "Version": "1.0.1", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "callsites@3.1.0" + ], + "Locations": [ + { + "StartLine": 6401, + "EndLine": 6411 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "parse-json@5.2.0", + "Name": "parse-json", + "Identifier": { + "PURL": "pkg:npm/parse-json@5.2.0", + "UID": "93af9f238931920e" + }, + "Version": "5.2.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@babel/code-frame@7.18.6", + "error-ex@1.3.2", + "json-parse-even-better-errors@2.3.1", + "lines-and-columns@1.2.4" + ], + "Locations": [ + { + "StartLine": 6412, + "EndLine": 6428 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "path-is-absolute@1.0.1", + "Name": "path-is-absolute", + "Identifier": { + "PURL": "pkg:npm/path-is-absolute@1.0.1", + "UID": "e68ac84ba607f3a7" + }, + "Version": "1.0.1", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 6467, + "EndLine": 6474 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "path-parse@1.0.7", + "Name": "path-parse", + "Identifier": { + "PURL": "pkg:npm/path-parse@1.0.7", + "UID": "919682a4e198ad51" + }, + "Version": "1.0.7", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 6484, + "EndLine": 6488 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "path-type@4.0.0", + "Name": "path-type", + "Identifier": { + "PURL": "pkg:npm/path-type@4.0.0", + "UID": "30f7b2f4c332225f" + }, + "Version": "4.0.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 6495, + "EndLine": 6502 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "picocolors@1.0.0", + "Name": "picocolors", + "Identifier": { + "PURL": "pkg:npm/picocolors@1.0.0", + "UID": "d8370d68d688f167" + }, + "Version": "1.0.0", + "Licenses": [ + "ISC" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 6503, + "EndLine": 6508 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "popmotion@11.0.3", + "Name": "popmotion", + "Identifier": { + "PURL": "pkg:npm/popmotion@11.0.3", + "UID": "e436388b0ea3634e" + }, + "Version": "11.0.3", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "framesync@6.0.1", + "hey-listen@1.0.8", + "style-value-types@5.0.0", + "tslib@2.3.1" + ], + "Locations": [ + { + "StartLine": 6533, + "EndLine": 6543 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "prop-types@15.8.1", + "Name": "prop-types", + "Identifier": { + "PURL": "pkg:npm/prop-types@15.8.1", + "UID": "ff83304644662043" + }, + "Version": "15.8.1", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "loose-envify@1.4.0", + "object-assign@4.1.1", + "react-is@16.13.1" + ], + "Locations": [ + { + "StartLine": 6688, + "EndLine": 6697 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "react-is@16.13.1", + "Name": "react-is", + "Identifier": { + "PURL": "pkg:npm/react-is@16.13.1", + "UID": "ccd373f83fcab67d" + }, + "Version": "16.13.1", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 6845, + "EndLine": 6849 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "react-is@18.2.0", + "Name": "react-is", + "Identifier": { + "PURL": "pkg:npm/react-is@18.2.0", + "UID": "f1f87c7b3fc2aa8b" + }, + "Version": "18.2.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 2168, + "EndLine": 2172 + }, + { + "StartLine": 2317, + "EndLine": 2321 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "react-router@6.2.2", + "Name": "react-router", + "Identifier": { + "PURL": "pkg:npm/react-router@6.2.2", + "UID": "a480eb42587bd283" + }, + "Version": "6.2.2", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "history@5.3.0", + "react@17.0.2" + ], + "Locations": [ + { + "StartLine": 6875, + "EndLine": 6885 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "react-transition-group@4.4.5", + "Name": "react-transition-group", + "Identifier": { + "PURL": "pkg:npm/react-transition-group@4.4.5", + "UID": "cccc50efc61e619d" + }, + "Version": "4.4.5", + "Licenses": [ + "BSD-3-Clause" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@babel/runtime@7.23.2", + "dom-helpers@5.2.1", + "loose-envify@1.4.0", + "prop-types@15.8.1", + "react-dom@17.0.2", + "react@17.0.2" + ], + "Locations": [ + { + "StartLine": 6899, + "EndLine": 6913 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "regenerator-runtime@0.14.0", + "Name": "regenerator-runtime", + "Identifier": { + "PURL": "pkg:npm/regenerator-runtime@0.14.0", + "UID": "6d24ee7910758a98" + }, + "Version": "0.14.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 1704, + "EndLine": 1708 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "remove-accents@0.4.2", + "Name": "remove-accents", + "Identifier": { + "PURL": "pkg:npm/remove-accents@0.4.2", + "UID": "f4bfd5461d559ee" + }, + "Version": "0.4.2", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 7055, + "EndLine": 7059 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "reselect@4.1.5", + "Name": "reselect", + "Identifier": { + "PURL": "pkg:npm/reselect@4.1.5", + "UID": "8f202169a3ac592d" + }, + "Version": "4.1.5", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 7109, + "EndLine": 7113 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "resolve@1.22.0", + "Name": "resolve", + "Identifier": { + "PURL": "pkg:npm/resolve@1.22.0", + "UID": "b6a8e50ddf653228" + }, + "Version": "1.22.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "is-core-module@2.8.1", + "path-parse@1.0.7", + "supports-preserve-symlinks-flag@1.0.0" + ], + "Locations": [ + { + "StartLine": 7114, + "EndLine": 7129 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "resolve-from@4.0.0", + "Name": "resolve-from", + "Identifier": { + "PURL": "pkg:npm/resolve-from@4.0.0", + "UID": "432966957938fa64" + }, + "Version": "4.0.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 5411, + "EndLine": 5418 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "rimraf@3.0.2", + "Name": "rimraf", + "Identifier": { + "PURL": "pkg:npm/rimraf@3.0.2", + "UID": "6ee28c410e1b8387" + }, + "Version": "3.0.2", + "Licenses": [ + "ISC" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "glob@7.2.0" + ], + "Locations": [ + { + "StartLine": 7170, + "EndLine": 7183 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "safe-buffer@5.1.2", + "Name": "safe-buffer", + "Identifier": { + "PURL": "pkg:npm/safe-buffer@5.1.2", + "UID": "75a759b5c7fecdb6" + }, + "Version": "5.1.2", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 7207, + "EndLine": 7211 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "scheduler@0.20.2", + "Name": "scheduler", + "Identifier": { + "PURL": "pkg:npm/scheduler@0.20.2", + "UID": "3f8f8ac6d8288ecf" + }, + "Version": "0.20.2", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "loose-envify@1.4.0", + "object-assign@4.1.1" + ], + "Locations": [ + { + "StartLine": 7218, + "EndLine": 7226 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "semver@6.3.0", + "Name": "semver", + "Identifier": { + "PURL": "pkg:npm/semver@6.3.0", + "UID": "9c3173199e88b8ee" + }, + "Version": "6.3.0", + "Licenses": [ + "ISC" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 7263, + "EndLine": 7271 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "source-map@0.5.7", + "Name": "source-map", + "Identifier": { + "PURL": "pkg:npm/source-map@0.5.7", + "UID": "50222df13dab4887" + }, + "Version": "0.5.7", + "Licenses": [ + "BSD-3-Clause" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 7466, + "EndLine": 7473 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "style-value-types@5.0.0", + "Name": "style-value-types", + "Identifier": { + "PURL": "pkg:npm/style-value-types@5.0.0", + "UID": "6efa25039d7054e2" + }, + "Version": "5.0.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "hey-listen@1.0.8", + "tslib@2.3.1" + ], + "Locations": [ + { + "StartLine": 7610, + "EndLine": 7618 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "stylis@4.2.0", + "Name": "stylis", + "Identifier": { + "PURL": "pkg:npm/stylis@4.2.0", + "UID": "748ad02cc602ec39" + }, + "Version": "4.2.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 7619, + "EndLine": 7623 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "supports-color@5.5.0", + "Name": "supports-color", + "Identifier": { + "PURL": "pkg:npm/supports-color@5.5.0", + "UID": "a99815e972b76a4d" + }, + "Version": "5.5.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "has-flag@3.0.0" + ], + "Locations": [ + { + "StartLine": 7624, + "EndLine": 7634 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "supports-preserve-symlinks-flag@1.0.0", + "Name": "supports-preserve-symlinks-flag", + "Identifier": { + "PURL": "pkg:npm/supports-preserve-symlinks-flag@1.0.0", + "UID": "fdcdba35765affb" + }, + "Version": "1.0.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 7635, + "EndLine": 7645 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "to-fast-properties@2.0.0", + "Name": "to-fast-properties", + "Identifier": { + "PURL": "pkg:npm/to-fast-properties@2.0.0", + "UID": "57a223fdd6b1e198" + }, + "Version": "2.0.0", + "Licenses": [ + "MIT" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 7740, + "EndLine": 7747 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "tslib@2.3.1", + "Name": "tslib", + "Identifier": { + "PURL": "pkg:npm/tslib@2.3.1", + "UID": "78efc7253ecad6f6" + }, + "Version": "2.3.1", + "Licenses": [ + "0BSD" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 7873, + "EndLine": 7877 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "unload@2.2.0", + "Name": "unload", + "Identifier": { + "PURL": "pkg:npm/unload@2.2.0", + "UID": "a5df1e91c73151b3" + }, + "Version": "2.2.0", + "Licenses": [ + "Apache-2.0" + ], + "Indirect": true, + "Relationship": "indirect", + "DependsOn": [ + "@babel/runtime@7.23.2", + "detect-node@2.1.0" + ], + "Locations": [ + { + "StartLine": 7952, + "EndLine": 7960 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "wrappy@1.0.2", + "Name": "wrappy", + "Identifier": { + "PURL": "pkg:npm/wrappy@1.0.2", + "UID": "b5b916b640189e61" + }, + "Version": "1.0.2", + "Licenses": [ + "ISC" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 8419, + "EndLine": 8423 + } + ], + "AnalyzedBy": "npm" + }, + { + "ID": "yaml@1.10.2", + "Name": "yaml", + "Identifier": { + "PURL": "pkg:npm/yaml@1.10.2", + "UID": "da529d3cb346002b" + }, + "Version": "1.10.2", + "Licenses": [ + "ISC" + ], + "Indirect": true, + "Relationship": "indirect", + "Locations": [ + { + "StartLine": 8451, + "EndLine": 8458 + } + ], + "AnalyzedBy": "npm" + } + ], + "Vulnerabilities": [ + { + "VulnerabilityID": "CVE-2026-49356", + "VendorIDs": [ + "GHSA-4x5r-pxfx-6jf8" + ], + "PkgID": "@babel/core@7.17.5", + "PkgName": "@babel/core", + "PkgIdentifier": { + "PURL": "pkg:npm/%40babel/core@7.17.5", + "UID": "2a6160dcdc31d62a" + }, + "InstalledVersion": "7.17.5", + "FixedVersion": "8.0.0-rc.6, 7.29.6", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2026-49356", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:fe209a900c12901cf3db3e1eca992f6b37bf41eb28f1878c81796ad253568c9b", + "Title": "Babel is a compiler for writing next generation JavaScript. Prior to 8 ...", + "Description": "Babel is a compiler for writing next generation JavaScript. Prior to 8.0.0-rc.6 and 7.29.6, @babel/core affected by an arbitrary file read via a sourceMappingURL comment. Using @babel/core to compile maliciously crafted code can allow an attacker to read any source map from the system that is running Babel, if the attacker controls the input source code, can read the output source code, and knows the path of the source map file that they want to read. This vulnerability is fixed in 8.0.0-rc.6 and 7.29.6.", + "Severity": "LOW", + "CweIDs": [ + "CWE-22", + "CWE-200" + ], + "VendorSeverity": { + "ghsa": 1 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:L/AC:H/PR:N/UI:N/S:C/C:L/I:N/A:N", + "V3Score": 3.2 + } + }, + "References": [ + "https://babeljs.io/docs/options#inputsourcemap", + "https://github.com/babel/babel", + "https://github.com/babel/babel/security/advisories/GHSA-4x5r-pxfx-6jf8" + ], + "PublishedDate": "2026-06-22T18:16:41.107Z", + "LastModifiedDate": "2026-06-23T16:04:55.583Z" + }, + { + "VulnerabilityID": "CVE-2025-27789", + "VendorIDs": [ + "GHSA-968p-4wvh-cqc8" + ], + "PkgID": "@babel/helpers@7.17.2", + "PkgName": "@babel/helpers", + "PkgIdentifier": { + "PURL": "pkg:npm/%40babel/helpers@7.17.2", + "UID": "73434025ffc769ba" + }, + "InstalledVersion": "7.17.2", + "FixedVersion": "7.26.10, 8.0.0-alpha.17", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2025-27789", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:c9142145f877ec6cca89444aa26247dd2373e69175942ea2d231582f9d0d6adf", + "Title": "Babel has inefficient RegExp complexity in generated code with .replace when transpiling named capturing groups", + "Description": "Babel is a compiler for writing next generation JavaScript. When using versions of Babel prior to 7.26.10 and 8.0.0-alpha.17 to compile regular expression named capturing groups, Babel will generate a polyfill for the `.replace` method that has quadratic complexity on some specific replacement pattern strings (i.e. the second argument passed to `.replace`). Generated code is vulnerable if all the following conditions are true: Using Babel to compile regular expression named capturing groups, using the `.replace` method on a regular expression that contains named capturing groups, and the code using untrusted strings as the second argument of `.replace`. This problem has been fixed in `@babel/helpers` and `@babel/runtime` 7.26.10 and 8.0.0-alpha.17. It's likely that individual users do not directly depend on `@babel/helpers`, and instead depend on `@babel/core` (which itself depends on `@babel/helpers`). Upgrading to `@babel/core` 7.26.10 is not required, but it guarantees use of a new enough `@babel/helpers` version. Note that just updating Babel dependencies is not enough; one will also need to re-compile the code. No known workarounds are available.", + "Severity": "MEDIUM", + "CweIDs": [ + "CWE-1333" + ], + "VendorSeverity": { + "ghsa": 2 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V3Score": 6.2 + } + }, + "References": [ + "https://github.com/babel/babel", + "https://github.com/babel/babel/commit/d5952e80c0faa5ec20e35085531b6e572d31dad4", + "https://github.com/babel/babel/pull/17173", + "https://github.com/babel/babel/security/advisories/GHSA-968p-4wvh-cqc8", + "https://nvd.nist.gov/vuln/detail/CVE-2025-27789" + ], + "PublishedDate": "2025-03-11T20:15:18.33Z", + "LastModifiedDate": "2026-06-17T09:04:13.763Z" + }, + { + "VulnerabilityID": "CVE-2025-27789", + "VendorIDs": [ + "GHSA-968p-4wvh-cqc8" + ], + "PkgID": "@babel/runtime@7.23.2", + "PkgName": "@babel/runtime", + "PkgIdentifier": { + "PURL": "pkg:npm/%40babel/runtime@7.23.2", + "UID": "a263c07ce5d88868" + }, + "InstalledVersion": "7.23.2", + "FixedVersion": "7.26.10, 8.0.0-alpha.17", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2025-27789", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:21113427b19e4ba912f24aca54163779b58ab6969a501b208aa14b9535b34fa0", + "Title": "Babel has inefficient RegExp complexity in generated code with .replace when transpiling named capturing groups", + "Description": "Babel is a compiler for writing next generation JavaScript. When using versions of Babel prior to 7.26.10 and 8.0.0-alpha.17 to compile regular expression named capturing groups, Babel will generate a polyfill for the `.replace` method that has quadratic complexity on some specific replacement pattern strings (i.e. the second argument passed to `.replace`). Generated code is vulnerable if all the following conditions are true: Using Babel to compile regular expression named capturing groups, using the `.replace` method on a regular expression that contains named capturing groups, and the code using untrusted strings as the second argument of `.replace`. This problem has been fixed in `@babel/helpers` and `@babel/runtime` 7.26.10 and 8.0.0-alpha.17. It's likely that individual users do not directly depend on `@babel/helpers`, and instead depend on `@babel/core` (which itself depends on `@babel/helpers`). Upgrading to `@babel/core` 7.26.10 is not required, but it guarantees use of a new enough `@babel/helpers` version. Note that just updating Babel dependencies is not enough; one will also need to re-compile the code. No known workarounds are available.", + "Severity": "MEDIUM", + "CweIDs": [ + "CWE-1333" + ], + "VendorSeverity": { + "ghsa": 2 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V3Score": 6.2 + } + }, + "References": [ + "https://github.com/babel/babel", + "https://github.com/babel/babel/commit/d5952e80c0faa5ec20e35085531b6e572d31dad4", + "https://github.com/babel/babel/pull/17173", + "https://github.com/babel/babel/security/advisories/GHSA-968p-4wvh-cqc8", + "https://nvd.nist.gov/vuln/detail/CVE-2025-27789" + ], + "PublishedDate": "2025-03-11T20:15:18.33Z", + "LastModifiedDate": "2026-06-17T09:04:13.763Z" + }, + { + "VulnerabilityID": "CVE-2023-45133", + "VendorIDs": [ + "GHSA-67hx-6x53-jw92" + ], + "PkgID": "@babel/traverse@7.18.9", + "PkgName": "@babel/traverse", + "PkgIdentifier": { + "PURL": "pkg:npm/%40babel/traverse@7.18.9", + "UID": "4a85c92d0db3846c" + }, + "InstalledVersion": "7.18.9", + "FixedVersion": "7.23.2, 8.0.0-alpha.4", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2023-45133", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:28301b2b130ba2fc456ce84bf4b97f437717377f748c255f9084d568606cf519", + "Title": "babel: arbitrary code execution", + "Description": "Babel is a compiler for writingJavaScript. In `@babel/traverse` prior to versions 7.23.2 and 8.0.0-alpha.4 and all versions of `babel-traverse`, using Babel to compile code that was specifically crafted by an attacker can lead to arbitrary code execution during compilation, when using plugins that rely on the `path.evaluate()`or `path.evaluateTruthy()` internal Babel methods. Known affected plugins are `@babel/plugin-transform-runtime`; `@babel/preset-env` when using its `useBuiltIns` option; and any \"polyfill provider\" plugin that depends on `@babel/helper-define-polyfill-provider`, such as `babel-plugin-polyfill-corejs3`, `babel-plugin-polyfill-corejs2`, `babel-plugin-polyfill-es-shims`, `babel-plugin-polyfill-regenerator`. No other plugins under the `@babel/` namespace are impacted, but third-party plugins might be. Users that only compile trusted code are not impacted. The vulnerability has been fixed in `@babel/traverse@7.23.2` and `@babel/traverse@8.0.0-alpha.4`. Those who cannot upgrade `@babel/traverse` and are using one of the affected packages mentioned above should upgrade them to their latest version to avoid triggering the vulnerable code path in affected `@babel/traverse` versions: `@babel/plugin-transform-runtime` v7.23.2, `@babel/preset-env` v7.23.2, `@babel/helper-define-polyfill-provider` v0.4.3, `babel-plugin-polyfill-corejs2` v0.4.6, `babel-plugin-polyfill-corejs3` v0.8.5, `babel-plugin-polyfill-es-shims` v0.10.0, `babel-plugin-polyfill-regenerator` v0.5.3.", + "Severity": "CRITICAL", + "CweIDs": [ + "CWE-184", + "CWE-697" + ], + "VendorSeverity": { + "ghsa": 4, + "nvd": 3, + "redhat": 3 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H", + "V3Score": 9.4 + }, + "nvd": { + "V3Vector": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H", + "V3Score": 8.8 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H", + "V3Score": 8.8 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2023-45133", + "https://babeljs.io/blog/2023/10/16/cve-2023-45133", + "https://github.com/babel/babel", + "https://github.com/babel/babel/commit/b13376b346946e3f62fc0848c1d2a23223314c82", + "https://github.com/babel/babel/pull/16033", + "https://github.com/babel/babel/releases/tag/v7.23.2", + "https://github.com/babel/babel/releases/tag/v8.0.0-alpha.4", + "https://github.com/babel/babel/security/advisories/GHSA-67hx-6x53-jw92", + "https://lists.debian.org/debian-lts-announce/2023/10/msg00026.html", + "https://nvd.nist.gov/vuln/detail/CVE-2023-45133", + "https://www.cve.org/CVERecord?id=CVE-2023-45133", + "https://www.debian.org/security/2023/dsa-5528" + ], + "PublishedDate": "2023-10-12T17:15:09.797Z", + "LastModifiedDate": "2026-06-17T06:28:17.02Z" + }, + { + "VulnerabilityID": "CVE-2025-27152", + "VendorIDs": [ + "GHSA-jr5f-v2jv-69x6" + ], + "PkgID": "axios@0.26.0", + "PkgName": "axios", + "PkgIdentifier": { + "PURL": "pkg:npm/axios@0.26.0", + "UID": "ab38b41ae3d6e87b" + }, + "InstalledVersion": "0.26.0", + "FixedVersion": "1.8.2, 0.30.0", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2025-27152", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:04de8c2bd7870fbf2c5504f98af8195417a9919f1a86584b00aee12165ab887f", + "Title": "axios: Possible SSRF and Credential Leakage via Absolute URL in axios Requests", + "Description": "axios is a promise based HTTP client for the browser and node.js. The issue occurs when passing absolute URLs rather than protocol-relative URLs to axios. Even if ⁠baseURL is set, axios sends the request to the specified absolute URL, potentially causing SSRF and credential leakage. This issue impacts both server-side and client-side usage of axios. This issue is fixed in 1.8.2.", + "Severity": "HIGH", + "CweIDs": [ + "CWE-918" + ], + "VendorSeverity": { + "ghsa": 3, + "nvd": 2, + "redhat": 2 + }, + "CVSS": { + "ghsa": { + "V40Vector": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N/E:P", + "V40Score": 7.7 + }, + "nvd": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N", + "V3Score": 5.3 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N", + "V3Score": 5.3 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2025-27152", + "https://github.com/axios/axios", + "https://github.com/axios/axios/commit/02c3c69ced0f8fd86407c23203835892313d7fde", + "https://github.com/axios/axios/commit/fb8eec214ce7744b5ca787f2c3b8339b2f54b00f", + "https://github.com/axios/axios/issues/6463", + "https://github.com/axios/axios/pull/6829", + "https://github.com/axios/axios/releases/tag/v1.8.2", + "https://github.com/axios/axios/security/advisories/GHSA-jr5f-v2jv-69x6", + "https://nvd.nist.gov/vuln/detail/CVE-2025-27152", + "https://www.cve.org/CVERecord?id=CVE-2025-27152" + ], + "PublishedDate": "2025-03-07T16:15:38.773Z", + "LastModifiedDate": "2026-06-17T09:03:06.57Z" + }, + { + "VulnerabilityID": "CVE-2026-25639", + "VendorIDs": [ + "GHSA-43fc-jf86-j433" + ], + "PkgID": "axios@0.26.0", + "PkgName": "axios", + "PkgIdentifier": { + "PURL": "pkg:npm/axios@0.26.0", + "UID": "ab38b41ae3d6e87b" + }, + "InstalledVersion": "0.26.0", + "FixedVersion": "1.13.5, 0.30.3", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2026-25639", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:c71429909240b15cbcf42f14019e9c6bf614ff91c6c23a783de040048dcebe84", + "Title": "axios: Axios affected by Denial of Service via __proto__ Key in mergeConfig", + "Description": "Axios is a promise based HTTP client for the browser and Node.js. Prior to versions 0.30.3 and 1.13.5, the mergeConfig function in axios crashes with a TypeError when processing configuration objects containing __proto__ as an own property. An attacker can trigger this by providing a malicious configuration object created via JSON.parse(), causing complete denial of service. This vulnerability is fixed in versions 0.30.3 and 1.13.5.", + "Severity": "HIGH", + "CweIDs": [ + "CWE-754" + ], + "VendorSeverity": { + "ghsa": 3, + "redhat": 3 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V3Score": 7.5 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V3Score": 7.5 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2026-25639", + "https://github.com/axios/axios", + "https://github.com/axios/axios/commit/28c721588c7a77e7503d0a434e016f852c597b57", + "https://github.com/axios/axios/commit/d7ff1409c68168d3057fc3891f911b2b92616f9e", + "https://github.com/axios/axios/pull/7369", + "https://github.com/axios/axios/pull/7388", + "https://github.com/axios/axios/releases/tag/v0.30.3", + "https://github.com/axios/axios/releases/tag/v1.13.5", + "https://github.com/axios/axios/security/advisories/GHSA-43fc-jf86-j433", + "https://nvd.nist.gov/vuln/detail/CVE-2026-25639", + "https://www.cve.org/CVERecord?id=CVE-2026-25639" + ], + "PublishedDate": "2026-02-09T21:15:49.01Z", + "LastModifiedDate": "2026-06-17T10:24:59.767Z" + }, + { + "VulnerabilityID": "CVE-2026-42033", + "VendorIDs": [ + "GHSA-pf86-5x62-jrwf" + ], + "PkgID": "axios@0.26.0", + "PkgName": "axios", + "PkgIdentifier": { + "PURL": "pkg:npm/axios@0.26.0", + "UID": "ab38b41ae3d6e87b" + }, + "InstalledVersion": "0.26.0", + "FixedVersion": "1.15.1, 0.31.1", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2026-42033", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:d4cfa4a4c8ec46c143e07b2da5ac9309a0a3bf84daedde1d1b0565a9242f214c", + "Title": "axios: Axios: HTTP Transport Hijacking via Prototype Pollution", + "Description": "Axios is a promise based HTTP client for the browser and Node.js. Prior to 1.15.1 and 0.31.1, when Object.prototype has been polluted by any co-dependency with keys that axios reads without a hasOwnProperty guard, an attacker can (a) silently intercept and modify every JSON response before the application sees it, or (b) fully hijack the underlying HTTP transport, gaining access to request credentials, headers, and body. The precondition is prototype pollution from a separate source in the same process. This vulnerability is fixed in 1.15.1 and 0.31.1.", + "Severity": "HIGH", + "CweIDs": [ + "CWE-1321" + ], + "VendorSeverity": { + "ghsa": 3, + "redhat": 3 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N", + "V3Score": 7.4 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N", + "V3Score": 7.4 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2026-42033", + "https://github.com/axios/axios", + "https://github.com/axios/axios/security/advisories/GHSA-pf86-5x62-jrwf", + "https://nvd.nist.gov/vuln/detail/CVE-2026-42033", + "https://www.cve.org/CVERecord?id=CVE-2026-42033" + ], + "PublishedDate": "2026-04-24T18:16:29.993Z", + "LastModifiedDate": "2026-06-17T10:47:20.447Z" + }, + { + "VulnerabilityID": "CVE-2026-42035", + "VendorIDs": [ + "GHSA-6chq-wfr3-2hj9" + ], + "PkgID": "axios@0.26.0", + "PkgName": "axios", + "PkgIdentifier": { + "PURL": "pkg:npm/axios@0.26.0", + "UID": "ab38b41ae3d6e87b" + }, + "InstalledVersion": "0.26.0", + "FixedVersion": "1.15.1, 0.31.1", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2026-42035", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:9a129a90723dc5dbd50943d91b6c59094b8a81f05bccc3bb71a26e305128327f", + "Title": "axios: Axios: Arbitrary HTTP header injection via prototype pollution", + "Description": "Axios is a promise based HTTP client for the browser and Node.js. Prior to 1.15.1 and 0.31.1, a prototype pollution gadget exists in the Axios HTTP adapter (lib/adapters/http.js) that allows an attacker to inject arbitrary HTTP headers into outgoing requests. The vulnerability exploits duck-type checking of the data payload, where if Object.prototype is polluted with getHeaders, append, pipe, on, once, and Symbol.toStringTag, Axios misidentifies any plain object payload as a FormData instance and calls the attacker-controlled getHeaders() function, merging the returned headers into the outgoing request. The vulnerable code resides exclusively in lib/adapters/http.js. The prototype pollution source does not need to originate from Axios itself — any prototype pollution primitive in any dependency in the application's dependency tree is sufficient to trigger this gadget. This vulnerability is fixed in 1.15.1 and 0.31.1.", + "Severity": "HIGH", + "CweIDs": [ + "CWE-113", + "CWE-1321" + ], + "VendorSeverity": { + "ghsa": 3, + "redhat": 2 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N", + "V3Score": 7.4 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N", + "V3Score": 7.4 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2026-42035", + "https://github.com/axios/axios", + "https://github.com/axios/axios/security/advisories/GHSA-6chq-wfr3-2hj9", + "https://nvd.nist.gov/vuln/detail/CVE-2026-42035", + "https://www.cve.org/CVERecord?id=CVE-2026-42035" + ], + "PublishedDate": "2026-04-24T18:16:30.273Z", + "LastModifiedDate": "2026-06-17T10:47:20.66Z" + }, + { + "VulnerabilityID": "CVE-2026-42043", + "VendorIDs": [ + "GHSA-pmwg-cvhr-8vh7" + ], + "PkgID": "axios@0.26.0", + "PkgName": "axios", + "PkgIdentifier": { + "PURL": "pkg:npm/axios@0.26.0", + "UID": "ab38b41ae3d6e87b" + }, + "InstalledVersion": "0.26.0", + "FixedVersion": "1.15.1, 0.31.1", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2026-42043", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:a1a6c8d47fe25d686bfa1bd548d3cde2b5005da9b2b53193f42fca7214945fe7", + "Title": "axios: Axios: NO_PROXY bypass via crafted URL", + "Description": "Axios is a promise based HTTP client for the browser and Node.js. Prior to 1.15.1 and 0.31.1, an attacker who can influence the target URL of an Axios request can use any address in the 127.0.0.0/8 range (other than 127.0.0.1) to completely bypass the NO_PROXY protection. This vulnerability is due to an incomplete for CVE-2025-62718, This vulnerability is fixed in 1.15.1 and 0.31.1.", + "Severity": "HIGH", + "CweIDs": [ + "CWE-183", + "CWE-441", + "CWE-918" + ], + "VendorSeverity": { + "ghsa": 3, + "nvd": 4, + "redhat": 3 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N", + "V3Score": 7.2 + }, + "nvd": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N", + "V3Score": 10 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N", + "V3Score": 7.2 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2026-42043", + "https://github.com/axios/axios", + "https://github.com/axios/axios/security/advisories/GHSA-pmwg-cvhr-8vh7", + "https://nvd.nist.gov/vuln/detail/CVE-2026-42043", + "https://www.cve.org/CVERecord?id=CVE-2026-42043" + ], + "PublishedDate": "2026-04-24T18:16:31.457Z", + "LastModifiedDate": "2026-06-17T10:47:21.53Z" + }, + { + "VulnerabilityID": "CVE-2026-44486", + "VendorIDs": [ + "GHSA-j5f8-grm9-p9fc" + ], + "PkgID": "axios@0.26.0", + "PkgName": "axios", + "PkgIdentifier": { + "PURL": "pkg:npm/axios@0.26.0", + "UID": "ab38b41ae3d6e87b" + }, + "InstalledVersion": "0.26.0", + "FixedVersion": "1.16.0, 0.32.0", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2026-44486", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:cec4ef247c959f5ecdcb4e5161ccc7850280bba1487719ea57b34737afe73975", + "Title": "axios: Axios: Information disclosure of proxy credentials via HTTP redirects", + "Description": "Axios is a promise based HTTP client for the browser and Node.js. Prior to 0.32.0 and 1.16.0, Axios’ Node.js HTTP adapter can leak proxy credentials to a redirect target in affected versions. When a request is sent through an authenticated proxy, Axios may add a Proxy-Authorization header. If Axios then follows a redirect and the redirected request is no longer sent through that proxy, the stale Proxy-Authorization header can remain on the redirected request and be sent to the redirect target. This affects Node.js's use of Axios with automatic redirects enabled and an authenticated proxy configuration. Browser adapters are not affected. This vulnerability is fixed in 0.32.0 and 1.16.0.", + "Severity": "HIGH", + "CweIDs": [ + "CWE-200" + ], + "VendorSeverity": { + "ghsa": 3, + "redhat": 3 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N", + "V3Score": 7.5 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N", + "V3Score": 7.5 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2026-44486", + "https://github.com/axios/axios", + "https://github.com/axios/axios/commit/afca61a070728e717203c2bc21e7b589b59b858b", + "https://github.com/axios/axios/pull/10794", + "https://github.com/axios/axios/releases/tag/v0.32.0", + "https://github.com/axios/axios/releases/tag/v1.16.0", + "https://github.com/axios/axios/security/advisories/GHSA-j5f8-grm9-p9fc", + "https://nvd.nist.gov/vuln/detail/CVE-2026-44486", + "https://www.cve.org/CVERecord?id=CVE-2026-44486" + ], + "PublishedDate": "2026-06-11T17:16:32.45Z", + "LastModifiedDate": "2026-06-17T10:50:42.627Z" + }, + { + "VulnerabilityID": "CVE-2026-44487", + "VendorIDs": [ + "GHSA-p92q-9vqr-4j8v" + ], + "PkgID": "axios@0.26.0", + "PkgName": "axios", + "PkgIdentifier": { + "PURL": "pkg:npm/axios@0.26.0", + "UID": "ab38b41ae3d6e87b" + }, + "InstalledVersion": "0.26.0", + "FixedVersion": "1.16.0, 0.32.0", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2026-44487", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:1ede762d5d0f0fbbbbe4b5f67f698f3c12124bcdb4154721a1287b33f89c3585", + "Title": "axios: Axios: Information disclosure of proxy credentials via redirect flows", + "Description": "Axios is a promise based HTTP client for the browser and Node.js. Prior to 0.32.0 and 1.16.0, Axios’s Node.js HTTP adapter may forward a Proxy-Authorization header to a redirected origin during specific proxy-to-direct redirect flows. This affects Node.js usage, where an initial HTTP request is sent through an authenticated HTTP proxy, redirects are followed, and the redirected URL is no longer proxied. Under affected redirect shapes, the final origin can receive the proxy credential that was intended only for the outbound proxy. This vulnerability is fixed in 0.32.0 and 1.16.0.", + "Severity": "HIGH", + "CweIDs": [ + "CWE-201" + ], + "VendorSeverity": { + "ghsa": 3, + "nvd": 3, + "redhat": 3 + }, + "CVSS": { + "ghsa": { + "V40Vector": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N", + "V40Score": 8.2 + }, + "nvd": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N", + "V3Score": 7.5 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N", + "V3Score": 7.5 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2026-44487", + "https://github.com/axios/axios", + "https://github.com/axios/axios/releases/tag/v0.32.0", + "https://github.com/axios/axios/releases/tag/v1.16.0", + "https://github.com/axios/axios/security/advisories/GHSA-p92q-9vqr-4j8v", + "https://nvd.nist.gov/vuln/detail/CVE-2026-44487", + "https://www.cve.org/CVERecord?id=CVE-2026-44487" + ], + "PublishedDate": "2026-06-11T17:16:32.607Z", + "LastModifiedDate": "2026-06-17T10:50:42.737Z" + }, + { + "VulnerabilityID": "CVE-2026-44492", + "VendorIDs": [ + "GHSA-pjwm-pj3p-43mv" + ], + "PkgID": "axios@0.26.0", + "PkgName": "axios", + "PkgIdentifier": { + "PURL": "pkg:npm/axios@0.26.0", + "UID": "ab38b41ae3d6e87b" + }, + "InstalledVersion": "0.26.0", + "FixedVersion": "1.16.0, 0.32.0", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2026-44492", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:c4f8e50d197a5471e387d8be0df30dbcaa44549633ac36e4a9893688de34f7d9", + "Title": "axios: Axios: Proxy bypass via IPv4-mapped IPv6 address non-normalization", + "Description": "Axios is a promise based HTTP client for the browser and Node.js. Prior to 0.32.0 and 1.16.0, Axios does not normalise IPv4-mapped IPv6 addresses. When NO_PROXY lists an IPv4 address such as 127.0.0.1 or 169.254.169.254, a request URL using the IPv4-mapped IPv6 form (::ffff:7f00:1, ::ffff:a9fe:a9fe) still routes through the configured proxy. Node.js resolves these addresses to the underlying IPv4 host, so the request reaches the internal service via the proxy rather than being blocked. This vulnerability is fixed in 0.32.0 and 1.16.0.", + "Severity": "HIGH", + "CweIDs": [ + "CWE-918" + ], + "VendorSeverity": { + "ghsa": 3, + "redhat": 3 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N", + "V3Score": 8.6 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N", + "V3Score": 8.6 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2026-44492", + "https://github.com/axios/axios", + "https://github.com/axios/axios/security/advisories/GHSA-pjwm-pj3p-43mv", + "https://nvd.nist.gov/vuln/detail/CVE-2025-62718", + "https://nvd.nist.gov/vuln/detail/CVE-2026-44492", + "https://www.cve.org/CVERecord?id=CVE-2026-44492" + ], + "PublishedDate": "2026-06-11T17:16:33.167Z", + "LastModifiedDate": "2026-06-17T10:50:43.177Z" + }, + { + "VulnerabilityID": "CVE-2026-44495", + "VendorIDs": [ + "GHSA-3g43-6gmg-66jw" + ], + "PkgID": "axios@0.26.0", + "PkgName": "axios", + "PkgIdentifier": { + "PURL": "pkg:npm/axios@0.26.0", + "UID": "ab38b41ae3d6e87b" + }, + "InstalledVersion": "0.26.0", + "FixedVersion": "1.15.2, 0.31.1", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2026-44495", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:b8ddbb2f5be0416a4c5a515424bc08af017cc8072232828f2db50329eb3e6852", + "Title": "axios: Axios: Information disclosure due to prototype pollution vulnerability", + "Description": "Axios is a promise based HTTP client for the browser and Node.js. From 0.19.0 to before 0.31.1 and 1.15.2, Axios contains prototype-pollution gadgets in request config processing. If another vulnerability in the same JavaScript process has already polluted Object.prototype.transformResponse, affected Axios versions may treat that inherited value as request configuration or as an option validator. Axios does not itself create the prototype pollution. Exploitability requires a separate prototype-pollution vulnerability or equivalent attacker control over Object.prototype before Axios creates a request. This vulnerability is fixed in 0.31.1 and 1.15.2.", + "Severity": "HIGH", + "CweIDs": [ + "CWE-94", + "CWE-1321" + ], + "VendorSeverity": { + "ghsa": 3, + "redhat": 3 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:L/A:L", + "V3Score": 7 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:L/A:L", + "V3Score": 7 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2026-44495", + "https://github.com/axios/axios", + "https://github.com/axios/axios/security/advisories/GHSA-3g43-6gmg-66jw", + "https://nvd.nist.gov/vuln/detail/CVE-2026-44495", + "https://www.cve.org/CVERecord?id=CVE-2026-44495" + ], + "PublishedDate": "2026-06-11T17:16:33.45Z", + "LastModifiedDate": "2026-06-17T10:50:43.393Z" + }, + { + "VulnerabilityID": "CVE-2026-44496", + "VendorIDs": [ + "GHSA-hfxv-24rg-xrqf" + ], + "PkgID": "axios@0.26.0", + "PkgName": "axios", + "PkgIdentifier": { + "PURL": "pkg:npm/axios@0.26.0", + "UID": "ab38b41ae3d6e87b" + }, + "InstalledVersion": "0.26.0", + "FixedVersion": "1.16.0, 0.32.0", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2026-44496", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:cfeb224d965f2f23b5454f448f306c8912fe103943c7c5e4b4dd4312676e184d", + "Title": "axios: Axios: Client-side Denial of Service via unescaped regex metacharacters in XSRF cookie name", + "Description": "Axios is a promise based HTTP client for the browser and Node.js. Axios versions before 0.32.0 on the 0.x line and before 1.16.0 on the 1.x line build a regular expression from the configured XSRF cookie name without escaping regex metacharacters. In standard browser environments, an attacker who can influence the cookie name passed to axios can cause expensive regex backtracking while axios reads document.cookie. The practical impact is client-side availability degradation, such as freezing the affected browser tab while axios prepares a request. The issue does not affect ordinary Node.js HTTP adapter usage, React Native, or web workers, where axios does not read document.cookie. This vulnerability is fixed in 0.32.0 and 1.16.0.", + "Severity": "HIGH", + "CweIDs": [ + "CWE-400", + "CWE-1333" + ], + "VendorSeverity": { + "ghsa": 3, + "redhat": 3 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V3Score": 7.5 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V3Score": 7.5 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2026-44496", + "https://github.com/axios/axios", + "https://github.com/axios/axios/releases/tag/v0.32.0", + "https://github.com/axios/axios/releases/tag/v1.16.0", + "https://github.com/axios/axios/security/advisories/GHSA-hfxv-24rg-xrqf", + "https://nvd.nist.gov/vuln/detail/CVE-2026-44496", + "https://www.cve.org/CVERecord?id=CVE-2026-44496" + ], + "PublishedDate": "2026-06-11T17:16:33.59Z", + "LastModifiedDate": "2026-06-17T10:50:43.513Z" + }, + { + "VulnerabilityID": "CVE-2023-45857", + "VendorIDs": [ + "GHSA-wf5p-g6vw-rhxx" + ], + "PkgID": "axios@0.26.0", + "PkgName": "axios", + "PkgIdentifier": { + "PURL": "pkg:npm/axios@0.26.0", + "UID": "ab38b41ae3d6e87b" + }, + "InstalledVersion": "0.26.0", + "FixedVersion": "1.6.0, 0.28.0", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2023-45857", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:b95428bb58f70c92c9feb057682f1f1fb9822e4238db0b61ca16272f9009bc95", + "Title": "axios: exposure of confidential data stored in cookies", + "Description": "An issue discovered in Axios 1.5.1 inadvertently reveals the confidential XSRF-TOKEN stored in cookies by including it in the HTTP header X-XSRF-TOKEN for every request made to any host allowing attackers to view sensitive information.", + "Severity": "MEDIUM", + "CweIDs": [ + "CWE-352" + ], + "VendorSeverity": { + "ghsa": 2, + "nvd": 2, + "redhat": 2 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N", + "V3Score": 6.5 + }, + "nvd": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N", + "V3Score": 6.5 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N", + "V3Score": 6.5 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2023-45857", + "https://github.com/axios/axios", + "https://github.com/axios/axios/commit/2755df562b9c194fba6d8b609a383443f6a6e967", + "https://github.com/axios/axios/commit/96ee232bd3ee4de2e657333d4d2191cd389e14d0", + "https://github.com/axios/axios/issues/6006", + "https://github.com/axios/axios/issues/6022", + "https://github.com/axios/axios/pull/6028", + "https://github.com/axios/axios/pull/6091", + "https://github.com/axios/axios/releases/tag/v0.28.0", + "https://github.com/axios/axios/releases/tag/v1.6.0", + "https://nvd.nist.gov/vuln/detail/CVE-2023-45857", + "https://security.netapp.com/advisory/ntap-20240621-0006", + "https://security.netapp.com/advisory/ntap-20240621-0006/", + "https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459", + "https://www.cve.org/CVERecord?id=CVE-2023-45857" + ], + "PublishedDate": "2023-11-08T21:15:08.55Z", + "LastModifiedDate": "2026-06-17T06:29:40.133Z" + }, + { + "VulnerabilityID": "CVE-2025-62718", + "VendorIDs": [ + "GHSA-3p68-rc4w-qgx5" + ], + "PkgID": "axios@0.26.0", + "PkgName": "axios", + "PkgIdentifier": { + "PURL": "pkg:npm/axios@0.26.0", + "UID": "ab38b41ae3d6e87b" + }, + "InstalledVersion": "0.26.0", + "FixedVersion": "1.15.0, 0.31.0", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2025-62718", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:08663ea192eaf2a842ad5f199d9cee622d4460d4433a3b5caf831a40c3b029e8", + "Title": "axios: Axios: Server-Side Request Forgery and proxy bypass due to improper hostname normalization", + "Description": "Axios is a promise based HTTP client for the browser and Node.js. Prior to 1.15.0 and 0.31.0, Axios does not correctly handle hostname normalization when checking NO_PROXY rules. Requests to loopback addresses like localhost. (with a trailing dot) or [::1] (IPv6 literal) skip NO_PROXY matching and go through the configured proxy. This goes against what developers expect and lets attackers force requests through a proxy, even if NO_PROXY is set up to protect loopback or internal services. This issue leads to the possibility of proxy bypass and SSRF vulnerabilities allowing attackers to reach sensitive loopback or internal services despite the configured protections. This vulnerability is fixed in 1.15.0 and 0.31.0.", + "Severity": "MEDIUM", + "CweIDs": [ + "CWE-441", + "CWE-918" + ], + "VendorSeverity": { + "ghsa": 2, + "nvd": 4, + "redhat": 3 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N", + "V40Vector": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:L/VA:N/SC:L/SI:L/SA:N", + "V3Score": 4.8, + "V40Score": 6.3 + }, + "nvd": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:L/A:L", + "V3Score": 9.9 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:L/A:L", + "V3Score": 7 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2025-62718", + "https://datatracker.ietf.org/doc/html/rfc1034#section-3.1", + "https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2", + "https://github.com/axios/axios", + "https://github.com/axios/axios/commit/03cdfc99e8db32a390e12128208b6778492cee9c", + "https://github.com/axios/axios/commit/fb3befb6daac6cad26b2e54094d0f2d9e47f24df", + "https://github.com/axios/axios/pull/10661", + "https://github.com/axios/axios/pull/10688", + "https://github.com/axios/axios/releases/tag/v0.31.0", + "https://github.com/axios/axios/releases/tag/v1.15.0", + "https://github.com/axios/axios/security/advisories/GHSA-3p68-rc4w-qgx5", + "https://nvd.nist.gov/vuln/detail/CVE-2025-62718", + "https://www.cve.org/CVERecord?id=CVE-2025-62718" + ], + "PublishedDate": "2026-04-09T15:16:08.65Z", + "LastModifiedDate": "2026-06-17T09:52:19.44Z" + }, + { + "VulnerabilityID": "CVE-2026-40175", + "VendorIDs": [ + "GHSA-fvcv-3m26-pcqx" + ], + "PkgID": "axios@0.26.0", + "PkgName": "axios", + "PkgIdentifier": { + "PURL": "pkg:npm/axios@0.26.0", + "UID": "ab38b41ae3d6e87b" + }, + "InstalledVersion": "0.26.0", + "FixedVersion": "1.15.0, 0.31.0", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2026-40175", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:7ea227a65114bbfa86060495660f97222e680953bc1e12085ca37dcb8200d0e5", + "Title": "axios: Axios: Remote Code Execution via Prototype Pollution escalation", + "Description": "Axios is a promise based HTTP client for the browser and Node.js. Versions prior to 1.15.0 and 0.3.1 are vulnerable to a specific gadget-style attack chain in which prototype pollution in a third-party dependency may be leveraged to inject unsanitized header values into outbound requests. This vulnerability is fixed in 1.15.0 and 0.3.1.", + "Severity": "MEDIUM", + "CweIDs": [ + "CWE-113", + "CWE-444", + "CWE-918" + ], + "VendorSeverity": { + "ghsa": 2, + "nvd": 2, + "redhat": 3 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N", + "V3Score": 4.8 + }, + "nvd": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N", + "V3Score": 4.8 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H", + "V3Score": 9 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2026-40175", + "https://cert-portal.siemens.com/productcert/html/ssa-876049.html", + "https://github.com/axios/axios", + "https://github.com/axios/axios/commit/03cdfc99e8db32a390e12128208b6778492cee9c", + "https://github.com/axios/axios/commit/363185461b90b1b78845dc8a99a1f103d9b122a1", + "https://github.com/axios/axios/pull/10660", + "https://github.com/axios/axios/pull/10660#issuecomment-4224168081", + "https://github.com/axios/axios/pull/10688", + "https://github.com/axios/axios/releases/tag/v0.31.0", + "https://github.com/axios/axios/releases/tag/v1.15.0", + "https://github.com/axios/axios/security/advisories/GHSA-fvcv-3m26-pcqx", + "https://nvd.nist.gov/vuln/detail/CVE-2026-40175", + "https://www.cve.org/CVERecord?id=CVE-2026-40175" + ], + "PublishedDate": "2026-04-10T20:16:22.8Z", + "LastModifiedDate": "2026-06-17T10:44:49.163Z" + }, + { + "VulnerabilityID": "CVE-2026-42034", + "VendorIDs": [ + "GHSA-5c9x-8gcm-mpgx" + ], + "PkgID": "axios@0.26.0", + "PkgName": "axios", + "PkgIdentifier": { + "PURL": "pkg:npm/axios@0.26.0", + "UID": "ab38b41ae3d6e87b" + }, + "InstalledVersion": "0.26.0", + "FixedVersion": "1.15.1, 0.31.1", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2026-42034", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:897efc3b0fea22e3cd8d4943923c9a536321ffa6d2ae834d29e6fec71a113d0d", + "Title": "axios: Axios: Denial of Service via oversized streamed uploads bypassing body limits", + "Description": "Axios is a promise based HTTP client for the browser and Node.js. Prior to 1.15.1 and 0.31.1, for stream request bodies, maxBodyLength is bypassed when maxRedirects is set to 0 (native http/https transport path). Oversized streamed uploads are sent fully even when the caller sets strict body limits. This vulnerability is fixed in 1.15.1 and 0.31.1.", + "Severity": "MEDIUM", + "CweIDs": [ + "CWE-770" + ], + "VendorSeverity": { + "ghsa": 2, + "redhat": 2 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L", + "V3Score": 5.3 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L", + "V3Score": 5.3 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2026-42034", + "https://github.com/axios/axios", + "https://github.com/axios/axios/security/advisories/GHSA-5c9x-8gcm-mpgx", + "https://nvd.nist.gov/vuln/detail/CVE-2026-42034", + "https://www.cve.org/CVERecord?id=CVE-2026-42034" + ], + "PublishedDate": "2026-04-24T18:16:30.14Z", + "LastModifiedDate": "2026-06-17T10:47:20.553Z" + }, + { + "VulnerabilityID": "CVE-2026-42036", + "VendorIDs": [ + "GHSA-vf2m-468p-8v99" + ], + "PkgID": "axios@0.26.0", + "PkgName": "axios", + "PkgIdentifier": { + "PURL": "pkg:npm/axios@0.26.0", + "UID": "ab38b41ae3d6e87b" + }, + "InstalledVersion": "0.26.0", + "FixedVersion": "1.15.1, 0.31.1", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2026-42036", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:92b3b323fa7d6c01c5470c0a3bd8827e53f71a02b0ecffdfaeea96d62cd07170", + "Title": "axios: Axios: Denial of Service via unbounded stream consumption when 'responseType: 'stream'' is used", + "Description": "Axios is a promise based HTTP client for the browser and Node.js. Prior to 1.15.1 and 0.31.1, when responseType: 'stream' is used, Axios returns the response stream without enforcing maxContentLength. This bypasses configured response-size limits and allows unbounded downstream consumption. This vulnerability is fixed in 1.15.1 and 0.31.1.", + "Severity": "MEDIUM", + "CweIDs": [ + "CWE-770" + ], + "VendorSeverity": { + "ghsa": 2, + "redhat": 2 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L", + "V3Score": 5.3 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L", + "V3Score": 5.3 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2026-42036", + "https://github.com/axios/axios", + "https://github.com/axios/axios/security/advisories/GHSA-vf2m-468p-8v99", + "https://nvd.nist.gov/vuln/detail/CVE-2026-42036", + "https://www.cve.org/CVERecord?id=CVE-2026-42036" + ], + "PublishedDate": "2026-04-24T18:16:30.41Z", + "LastModifiedDate": "2026-06-17T10:47:20.77Z" + }, + { + "VulnerabilityID": "CVE-2026-42038", + "VendorIDs": [ + "GHSA-m7pr-hjqh-92cm" + ], + "PkgID": "axios@0.26.0", + "PkgName": "axios", + "PkgIdentifier": { + "PURL": "pkg:npm/axios@0.26.0", + "UID": "ab38b41ae3d6e87b" + }, + "InstalledVersion": "0.26.0", + "FixedVersion": "1.15.1, 0.31.1", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2026-42038", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:4da7a3dd70fe95a3f85d19c121b38050fe636955bed0bc0187c12f3a7e21e729", + "Title": "axios: Axios: Information disclosure due to `no_proxy` bypass", + "Description": "Axios is a promise based HTTP client for the browser and Node.js. Prior to 1.15.1 and 0.31.1, he fix for no_proxy hostname normalization bypass is incomplete. When no_proxy=localhost is set, requests to 127.0.0.1 and [::1] still route through the proxy instead of bypassing it. The shouldBypassProxy() function does pure string matching — it does not resolve IP aliases or loopback equivalents. This vulnerability is fixed in 1.15.1 and 0.31.1.", + "Severity": "MEDIUM", + "CweIDs": [ + "CWE-918" + ], + "VendorSeverity": { + "ghsa": 2, + "nvd": 3, + "redhat": 2 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:N/A:N", + "V3Score": 6.8 + }, + "nvd": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N", + "V3Score": 7.5 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:N/A:N", + "V3Score": 6.8 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2026-42038", + "https://github.com/axios/axios", + "https://github.com/axios/axios/security/advisories/GHSA-m7pr-hjqh-92cm", + "https://nvd.nist.gov/vuln/detail/CVE-2026-42038", + "https://www.cve.org/CVERecord?id=CVE-2026-42038" + ], + "PublishedDate": "2026-04-24T18:16:30.68Z", + "LastModifiedDate": "2026-06-17T10:47:20.98Z" + }, + { + "VulnerabilityID": "CVE-2026-42039", + "VendorIDs": [ + "GHSA-62hf-57xw-28j9" + ], + "PkgID": "axios@0.26.0", + "PkgName": "axios", + "PkgIdentifier": { + "PURL": "pkg:npm/axios@0.26.0", + "UID": "ab38b41ae3d6e87b" + }, + "InstalledVersion": "0.26.0", + "FixedVersion": "1.15.1, 0.31.1", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2026-42039", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:06f06fe6b90bd523ce8c4c007d92bf936c6df04851e68d9ea96fc9bdc30389a9", + "Title": "axios: Node.js: Axios: Denial of Service via unbounded recursion in toFormData with deeply nested request data", + "Description": "Axios is a promise based HTTP client for the browser and Node.js. Prior to 1.15.1 and 0.31.1, toFormData recursively walks nested objects with no depth limit, so a deeply nested value passed as request data crashes the Node.js process with a RangeError. This vulnerability is fixed in 1.15.1 and 0.31.1.", + "Severity": "MEDIUM", + "CweIDs": [ + "CWE-674" + ], + "VendorSeverity": { + "ghsa": 2, + "nvd": 3, + "redhat": 3 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V40Vector": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N", + "V3Score": 7.5, + "V40Score": 6.9 + }, + "nvd": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V3Score": 7.5 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V3Score": 7.5 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2026-42039", + "https://github.com/axios/axios", + "https://github.com/axios/axios/commit/85132ffba1a77609ea5d101c8a413dea7174932f", + "https://github.com/axios/axios/releases/tag/v1.15.1", + "https://github.com/axios/axios/security/advisories/GHSA-62hf-57xw-28j9", + "https://nvd.nist.gov/vuln/detail/CVE-2026-42039", + "https://www.cve.org/CVERecord?id=CVE-2026-42039" + ], + "PublishedDate": "2026-04-24T18:16:30.827Z", + "LastModifiedDate": "2026-06-17T10:47:21.09Z" + }, + { + "VulnerabilityID": "CVE-2026-42041", + "VendorIDs": [ + "GHSA-w9j2-pvgh-6h63" + ], + "PkgID": "axios@0.26.0", + "PkgName": "axios", + "PkgIdentifier": { + "PURL": "pkg:npm/axios@0.26.0", + "UID": "ab38b41ae3d6e87b" + }, + "InstalledVersion": "0.26.0", + "FixedVersion": "1.15.1, 0.31.1", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2026-42041", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:27816d1d13212f5ebd17a29cdd0ace9a101d3b1bfbe2d67412594a451df57f38", + "Title": "axios: Axios: Authentication bypass due to prototype pollution of HTTP error handling", + "Description": "Axios is a promise based HTTP client for the browser and Node.js. Prior to 1.15.1 and 0.31.1, the Axios library is vulnerable to a Prototype Pollution \"Gadget\" attack that allows any Object.prototype pollution to silently suppress all HTTP error responses (401, 403, 500, etc.), causing them to be treated as successful responses. This completely bypasses application-level authentication and error handling. The root cause is that validateStatus is the only config property using the mergeDirectKeys merge strategy, which uses JavaScript's in operator — an operator that inherently traverses the prototype chain. When Object.prototype.validateStatus is polluted with () =\u003e true, all HTTP status codes are accepted as success. This vulnerability is fixed in 1.15.1 and 0.31.1.", + "Severity": "MEDIUM", + "CweIDs": [ + "CWE-287", + "CWE-1321" + ], + "VendorSeverity": { + "ghsa": 2, + "nvd": 2, + "redhat": 3 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N", + "V3Score": 4.8 + }, + "nvd": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N", + "V3Score": 6.5 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N", + "V3Score": 8.2 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2026-42041", + "https://github.com/axios/axios", + "https://github.com/axios/axios/security/advisories/GHSA-w9j2-pvgh-6h63", + "https://nvd.nist.gov/vuln/detail/CVE-2026-42041", + "https://www.cve.org/CVERecord?id=CVE-2026-42041" + ], + "PublishedDate": "2026-04-24T18:16:31.133Z", + "LastModifiedDate": "2026-06-17T10:47:21.307Z" + }, + { + "VulnerabilityID": "CVE-2026-42042", + "VendorIDs": [ + "GHSA-xx6v-rp6x-q39c" + ], + "PkgID": "axios@0.26.0", + "PkgName": "axios", + "PkgIdentifier": { + "PURL": "pkg:npm/axios@0.26.0", + "UID": "ab38b41ae3d6e87b" + }, + "InstalledVersion": "0.26.0", + "FixedVersion": "1.15.1, 0.31.1", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2026-42042", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:c4f2c1c022444ae20e821d09d8a7adeb34f173fa101b8008cd7cb31e1852a8bf", + "Title": "axios: Axios: XSRF token bypass leading to information disclosure", + "Description": "Axios is a promise based HTTP client for the browser and Node.js. Prior to 1.15.1 and 0.31.1, the Axios library's XSRF token protection logic uses JavaScript truthy/falsy semantics instead of strict boolean comparison for the withXSRFToken config property. When this property is set to any truthy non-boolean value (via prototype pollution or misconfiguration), the same-origin check (isURLSameOrigin) is short-circuited, causing XSRF tokens to be sent to all request targets including cross-origin servers controlled by an attacker. This vulnerability is fixed in 1.15.1 and 0.31.1.", + "Severity": "MEDIUM", + "CweIDs": [ + "CWE-183", + "CWE-201" + ], + "VendorSeverity": { + "ghsa": 2, + "redhat": 2 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N", + "V3Score": 5.4 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N", + "V3Score": 6.1 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2026-42042", + "https://github.com/axios/axios", + "https://github.com/axios/axios/security/advisories/GHSA-xx6v-rp6x-q39c", + "https://nvd.nist.gov/vuln/detail/CVE-2026-42042", + "https://www.cve.org/CVERecord?id=CVE-2026-42042" + ], + "PublishedDate": "2026-04-24T18:16:31.293Z", + "LastModifiedDate": "2026-06-17T10:47:21.42Z" + }, + { + "VulnerabilityID": "CVE-2026-44490", + "VendorIDs": [ + "GHSA-898c-q2cr-xwhg" + ], + "PkgID": "axios@0.26.0", + "PkgName": "axios", + "PkgIdentifier": { + "PURL": "pkg:npm/axios@0.26.0", + "UID": "ab38b41ae3d6e87b" + }, + "InstalledVersion": "0.26.0", + "FixedVersion": "1.16.0, 0.32.0", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2026-44490", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:a439000e2c68e4f6c27b7f9268f798833694ee162be271050b3c3c3cb18a0d0f", + "Title": "axios: Axios: Information disclosure and denial of service due to prototype pollution", + "Description": "Axios is a promise based HTTP client for the browser and Node.js. Prior to 0.32.0 and 1.16.0, axios exposes two read-side prototype-pollution gadgets. When Object.prototype is polluted by an upstream dependency in the same process (e.g. lodash _.merge / CVE-2018-16487), axios silently picks up the polluted values. (1) lib/utils.js line 406 builds merge()'s accumulator as result = {}, so result[targetKey] (line 414) walks Object.prototype and the polluted bucket's own keys are copied into the merged headers and ride out on the wire. (2) lib/core/mergeConfig.js line 26 builds the hasOwnProperty descriptor as a plain-object literal. Object.defineProperty reads descriptor.get/descriptor.set via the prototype chain, so a polluted Object.prototype.get or Object.prototype.set makes the call throw TypeError synchronously on every axios request. This vulnerability is fixed in 0.32.0 and 1.16.0.", + "Severity": "MEDIUM", + "CweIDs": [ + "CWE-1321" + ], + "VendorSeverity": { + "ghsa": 2, + "nvd": 3, + "redhat": 2 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:L", + "V3Score": 4.8 + }, + "nvd": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:H", + "V3Score": 8.2 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:L", + "V3Score": 4.8 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2026-44490", + "https://github.com/axios/axios", + "https://github.com/axios/axios/security/advisories/GHSA-898c-q2cr-xwhg", + "https://nvd.nist.gov/vuln/detail/CVE-2018-16487", + "https://nvd.nist.gov/vuln/detail/CVE-2026-44490", + "https://www.cve.org/CVERecord?id=CVE-2026-44490" + ], + "PublishedDate": "2026-06-11T17:16:33.027Z", + "LastModifiedDate": "2026-06-17T10:50:43.067Z" + }, + { + "VulnerabilityID": "CVE-2026-42040", + "VendorIDs": [ + "GHSA-xhjh-pmcv-23jw" + ], + "PkgID": "axios@0.26.0", + "PkgName": "axios", + "PkgIdentifier": { + "PURL": "pkg:npm/axios@0.26.0", + "UID": "ab38b41ae3d6e87b" + }, + "InstalledVersion": "0.26.0", + "FixedVersion": "1.15.1, 0.31.1", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2026-42040", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:b2de1def4424c187d41df6df42698af4b22d02bd8de2f98ff58ef0e8bf1f22dc", + "Title": "axios: Axios: Incorrect null byte handling can lead to data integrity issues", + "Description": "Axios is a promise based HTTP client for the browser and Node.js. Prior to 1.15.1 and 0.31.1, the encode() function in lib/helpers/AxiosURLSearchParams.js contains a character mapping (charMap) at line 21 that reverses the safe percent-encoding of null bytes. After encodeURIComponent('\\x00') correctly produces the safe sequence %00, the charMap entry '%00': '\\x00' converts it back to a raw null byte. Primary impact is limited because the standard axios request flow is not affected. This vulnerability is fixed in 1.15.1 and 0.31.1.", + "Severity": "LOW", + "CweIDs": [ + "CWE-116", + "CWE-626" + ], + "VendorSeverity": { + "ghsa": 1, + "redhat": 1 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N", + "V3Score": 3.7 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N", + "V3Score": 3.7 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2026-42040", + "https://github.com/axios/axios", + "https://github.com/axios/axios/security/advisories/GHSA-xhjh-pmcv-23jw", + "https://nvd.nist.gov/vuln/detail/CVE-2026-42040", + "https://www.cve.org/CVERecord?id=CVE-2026-42040" + ], + "PublishedDate": "2026-04-24T18:16:30.96Z", + "LastModifiedDate": "2026-06-17T10:47:21.197Z" + }, + { + "VulnerabilityID": "CVE-2026-33750", + "VendorIDs": [ + "GHSA-f886-m6hf-6m8v" + ], + "PkgID": "brace-expansion@1.1.11", + "PkgName": "brace-expansion", + "PkgIdentifier": { + "PURL": "pkg:npm/brace-expansion@1.1.11", + "UID": "4ea94b15f15f23cd" + }, + "InstalledVersion": "1.1.11", + "FixedVersion": "5.0.5, 3.0.2, 2.0.3, 1.1.13", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2026-33750", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:830ec09630152466db13267e4beb87c9c4a2971be13774454ee8fab1adae57fd", + "Title": "brace-expansion: brace-expansion: Denial of Service via zero step value in brace pattern", + "Description": "The brace-expansion library generates arbitrary strings containing a common prefix and suffix. Prior to versions 5.0.5, 3.0.2, 2.0.3, and 1.1.13, a brace pattern with a zero step value (e.g., `{1..2..0}`) causes the sequence generation loop to run indefinitely, making the process hang for seconds and allocate heaps of memory. Versions 5.0.5, 3.0.2, 2.0.3, and 1.1.13 fix the issue. As a workaround, sanitize strings passed to `expand()` to ensure a step value of `0` is not used.", + "Severity": "MEDIUM", + "CweIDs": [ + "CWE-400" + ], + "VendorSeverity": { + "ghsa": 2, + "nvd": 3, + "redhat": 2 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H", + "V3Score": 6.5 + }, + "nvd": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V3Score": 7.5 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H", + "V3Score": 6.5 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2026-33750", + "https://github.com/juliangruber/brace-expansion", + "https://github.com/juliangruber/brace-expansion/blob/daa71bcb4a30a2df9bcb7f7b8daaf2ab30e5794a/src/index.ts#L107-L113", + "https://github.com/juliangruber/brace-expansion/blob/daa71bcb4a30a2df9bcb7f7b8daaf2ab30e5794a/src/index.ts#L184", + "https://github.com/juliangruber/brace-expansion/commit/311ac0d54994158c0a384e286a7d6cbb17ee8ed5", + "https://github.com/juliangruber/brace-expansion/commit/7fd684f89fdde3549563d0a6522226a9189472a2", + "https://github.com/juliangruber/brace-expansion/commit/b9cacd9e55e7a1fa588fe4b7bb1159d52f1d902a", + "https://github.com/juliangruber/brace-expansion/issues/98", + "https://github.com/juliangruber/brace-expansion/pull/95", + "https://github.com/juliangruber/brace-expansion/pull/96", + "https://github.com/juliangruber/brace-expansion/pull/97", + "https://github.com/juliangruber/brace-expansion/security/advisories/GHSA-f886-m6hf-6m8v", + "https://nvd.nist.gov/vuln/detail/CVE-2026-33750", + "https://www.cve.org/CVERecord?id=CVE-2026-33750" + ], + "PublishedDate": "2026-03-27T15:16:57.297Z", + "LastModifiedDate": "2026-06-17T10:38:02.143Z" + }, + { + "VulnerabilityID": "CVE-2025-5889", + "VendorIDs": [ + "GHSA-v6h2-p8h4-qcjw" + ], + "PkgID": "brace-expansion@1.1.11", + "PkgName": "brace-expansion", + "PkgIdentifier": { + "PURL": "pkg:npm/brace-expansion@1.1.11", + "UID": "4ea94b15f15f23cd" + }, + "InstalledVersion": "1.1.11", + "FixedVersion": "2.0.2, 1.1.12, 3.0.1, 4.0.1", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2025-5889", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:7739d71a184f9aa8375d0eb7643d0462bede5f5b111fbf89134b175f03ceef10", + "Title": "brace-expansion: juliangruber brace-expansion index.js expand redos", + "Description": "A vulnerability was found in juliangruber brace-expansion up to 1.1.11/2.0.1/3.0.0/4.0.0. It has been rated as problematic. Affected by this issue is the function expand of the file index.js. The manipulation leads to inefficient regular expression complexity. The attack may be launched remotely. The complexity of an attack is rather high. The exploitation is known to be difficult. The exploit has been disclosed to the public and may be used. Upgrading to version 1.1.12, 2.0.2, 3.0.1 and 4.0.1 is able to address this issue. The name of the patch is a5b98a4f30d7813266b221435e1eaaf25a1b0ac5. It is recommended to upgrade the affected component.", + "Severity": "LOW", + "CweIDs": [ + "CWE-400", + "CWE-1333" + ], + "VendorSeverity": { + "amazon": 3, + "cbl-mariner": 1, + "ghsa": 1, + "redhat": 1 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:N/I:N/A:L", + "V40Vector": "CVSS:4.0/AV:N/AC:H/AT:N/PR:L/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N/E:P", + "V3Score": 3.1, + "V40Score": 1.3 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:N/I:N/A:L", + "V3Score": 3.1 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2025-5889", + "https://gist.github.com/mmmsssttt404/37a40ce7d6e5ca604858fe30814d9466", + "https://github.com/juliangruber/brace-expansion", + "https://github.com/juliangruber/brace-expansion/commit/0b6a9781e18e9d2769bb2931f4856d1360243ed2", + "https://github.com/juliangruber/brace-expansion/commit/15f9b3c75ebf5988198241fecaebdc45eff28a9f", + "https://github.com/juliangruber/brace-expansion/commit/36603d5f3599a37af9e85eda30acd7d28599c36e", + "https://github.com/juliangruber/brace-expansion/commit/c3c73c8b088defc70851843be88ccc3af08e7217", + "https://github.com/juliangruber/brace-expansion/pull/65/commits/a5b98a4f30d7813266b221435e1eaaf25a1b0ac5", + "https://github.com/juliangruber/brace-expansion/releases/tag/v4.0.1", + "https://nvd.nist.gov/vuln/detail/CVE-2025-5889", + "https://vuldb.com/?ctiid.311660", + "https://vuldb.com/?id.311660", + "https://vuldb.com/?submit.585717", + "https://www.cve.org/CVERecord?id=CVE-2025-5889" + ], + "PublishedDate": "2025-06-09T19:15:25.46Z", + "LastModifiedDate": "2026-06-17T09:48:57.653Z" + }, + { + "VulnerabilityID": "CVE-2023-26159", + "VendorIDs": [ + "GHSA-jchw-25xp-jwwc" + ], + "PkgID": "follow-redirects@1.14.9", + "PkgName": "follow-redirects", + "PkgIdentifier": { + "PURL": "pkg:npm/follow-redirects@1.14.9", + "UID": "dc97ccb86bb0a662" + }, + "InstalledVersion": "1.14.9", + "FixedVersion": "1.15.4", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2023-26159", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:47ed7ed0b349786900beecc4922e8440c11bbef1ddcf40d331b03f93095a77a2", + "Title": "follow-redirects: Improper Input Validation due to the improper handling of URLs by the url.parse()", + "Description": "Versions of the package follow-redirects before 1.15.4 are vulnerable to Improper Input Validation due to the improper handling of URLs by the url.parse() function. When new URL() throws an error, it can be manipulated to misinterpret the hostname. An attacker could exploit this weakness to redirect traffic to a malicious site, potentially leading to information disclosure, phishing attacks, or other security breaches.", + "Severity": "MEDIUM", + "CweIDs": [ + "CWE-20", + "CWE-601" + ], + "VendorSeverity": { + "azure": 2, + "cbl-mariner": 2, + "ghsa": 2, + "nvd": 2, + "redhat": 2, + "ubuntu": 2 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N", + "V3Score": 6.1 + }, + "nvd": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N", + "V3Score": 6.1 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N", + "V3Score": 6.1 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2023-26159", + "https://github.com/follow-redirects/follow-redirects", + "https://github.com/follow-redirects/follow-redirects/commit/7a6567e16dfa9ad18a70bfe91784c28653fbf19d", + "https://github.com/follow-redirects/follow-redirects/issues/235", + "https://github.com/follow-redirects/follow-redirects/pull/236", + "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/ZZ425BFKNBQ6AK7I5SAM56TWON5OF2XM", + "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/ZZ425BFKNBQ6AK7I5SAM56TWON5OF2XM/", + "https://nvd.nist.gov/vuln/detail/CVE-2023-26159", + "https://security.netapp.com/advisory/ntap-20241108-0002", + "https://security.netapp.com/advisory/ntap-20241108-0002/", + "https://security.snyk.io/vuln/SNYK-JS-FOLLOWREDIRECTS-6141137", + "https://ubuntu.com/security/notices/USN-8217-1", + "https://www.cve.org/CVERecord?id=CVE-2023-26159" + ], + "PublishedDate": "2024-01-02T05:15:08.63Z", + "LastModifiedDate": "2026-06-17T05:42:48.68Z" + }, + { + "VulnerabilityID": "CVE-2024-28849", + "VendorIDs": [ + "GHSA-cxjh-pqwp-8mfp" + ], + "PkgID": "follow-redirects@1.14.9", + "PkgName": "follow-redirects", + "PkgIdentifier": { + "PURL": "pkg:npm/follow-redirects@1.14.9", + "UID": "dc97ccb86bb0a662" + }, + "InstalledVersion": "1.14.9", + "FixedVersion": "1.15.6", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2024-28849", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:a1c0caba5cbbebf0e47087e525e95c1963688f5abaef1cb0d1d3752d71aacbc4", + "Title": "follow-redirects: Possible credential leak", + "Description": "follow-redirects is an open source, drop-in replacement for Node's `http` and `https` modules that automatically follows redirects. In affected versions follow-redirects only clears authorization header during cross-domain redirect, but keep the proxy-authentication header which contains credentials too. This vulnerability may lead to credentials leak, but has been addressed in version 1.15.6. Users are advised to upgrade. There are no known workarounds for this vulnerability.", + "Severity": "MEDIUM", + "CweIDs": [ + "CWE-200" + ], + "VendorSeverity": { + "cbl-mariner": 2, + "ghsa": 2, + "redhat": 2, + "ubuntu": 2 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N", + "V3Score": 6.5 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N", + "V3Score": 6.5 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2024-28849", + "https://fetch.spec.whatwg.org/#authentication-entries", + "https://github.com/follow-redirects/follow-redirects", + "https://github.com/follow-redirects/follow-redirects/commit/c4f847f85176991f95ab9c88af63b1294de8649b", + "https://github.com/follow-redirects/follow-redirects/commit/c4f847f85176991f95ab9c88af63b1294de8649b%20%28v1.15.6%29", + "https://github.com/follow-redirects/follow-redirects/security/advisories/GHSA-cxjh-pqwp-8mfp", + "https://github.com/psf/requests/issues/1885", + "https://hackerone.com/reports/2390009", + "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/VOIF4EPQUCKDBEVTGRQDZ3CGTYQHPO7Z", + "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/VOIF4EPQUCKDBEVTGRQDZ3CGTYQHPO7Z/", + "https://nvd.nist.gov/vuln/detail/CVE-2024-28849", + "https://ubuntu.com/security/notices/USN-8217-1", + "https://www.cve.org/CVERecord?id=CVE-2024-28849" + ], + "PublishedDate": "2024-03-14T17:15:52.097Z", + "LastModifiedDate": "2026-06-17T07:21:53.207Z" + }, + { + "VulnerabilityID": "GHSA-r4q5-vmmm-2653", + "PkgID": "follow-redirects@1.14.9", + "PkgName": "follow-redirects", + "PkgIdentifier": { + "PURL": "pkg:npm/follow-redirects@1.14.9", + "UID": "dc97ccb86bb0a662" + }, + "InstalledVersion": "1.14.9", + "FixedVersion": "1.16.0", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://github.com/advisories/GHSA-r4q5-vmmm-2653", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:c99dd4cda8e6854ea5dac533ba9c7851f5a32f264706adb683d7501c23097812", + "Title": "follow-redirects leaks Custom Authentication Headers to Cross-Domain Redirect Targets", + "Description": "## Summary\n\nWhen an HTTP request follows a cross-domain redirect (301/302/307/308), `follow-redirects` only strips `authorization`, `proxy-authorization`, and `cookie` headers (matched by regex at index.js:469-476). Any custom authentication header (e.g., `X-API-Key`, `X-Auth-Token`, `Api-Key`, `Token`) is forwarded verbatim to the redirect target.\n\nSince `follow-redirects` is the redirect-handling dependency for **axios** (105K+ stars), this vulnerability affects the entire axios ecosystem.\n\n## Affected Code\n\n`index.js`, lines 469-476:\n\n```javascript\nif (redirectUrl.protocol !== currentUrlParts.protocol \u0026\u0026\n redirectUrl.protocol !== \"https:\" ||\n redirectUrl.host !== currentHost \u0026\u0026\n !isSubdomain(redirectUrl.host, currentHost)) {\n removeMatchingHeaders(/^(?:(?:proxy-)?authorization|cookie)$/i, this._options.headers);\n}\n```\n\nThe regex only matches `authorization`, `proxy-authorization`, and `cookie`. Custom headers like `X-API-Key` are not matched.\n\n## Attack Scenario\n\n1. App uses axios with custom auth header: `headers: { 'X-API-Key': 'sk-live-secret123' }`\n2. Server returns `302 Location: https://evil.com/steal`\n3. follow-redirects sends `X-API-Key: sk-live-secret123` to `evil.com`\n4. Attacker captures the API key\n\n## Impact\n\nAny custom auth header set via axios leaks on cross-domain redirect. Extremely common pattern. Affects all axios users in Node.js.\n\n## Suggested Fix\n\nAdd a `sensitiveHeaders` option that users can extend, or strip ALL non-standard headers on cross-domain redirect.\n\n## Disclosure\n\nSource code review, manually verified. Found 2026-03-20.", + "Severity": "MEDIUM", + "VendorSeverity": { + "ghsa": 2 + }, + "CVSS": { + "ghsa": { + "V40Vector": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N", + "V40Score": 6.9 + } + }, + "References": [ + "https://github.com/follow-redirects/follow-redirects", + "https://github.com/follow-redirects/follow-redirects/commit/844c4d302ac963d29bdb5dc1754ec7df3d70d7f9", + "https://github.com/follow-redirects/follow-redirects/security/advisories/GHSA-r4q5-vmmm-2653" + ], + "PublishedDate": "2026-04-14T01:11:11Z", + "LastModifiedDate": "2026-04-14T01:11:11Z" + }, + { + "VulnerabilityID": "CVE-2022-46175", + "VendorIDs": [ + "GHSA-9c47-m6qq-7p4h" + ], + "PkgID": "json5@2.2.0", + "PkgName": "json5", + "PkgIdentifier": { + "PURL": "pkg:npm/json5@2.2.0", + "UID": "ca319a23f8885c6e" + }, + "InstalledVersion": "2.2.0", + "FixedVersion": "2.2.2, 1.0.2", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2022-46175", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:3a5a541fab8e6c4bbb75949ca39a6f12df2b0eeb8301b19679fcf2c2853c1249", + "Title": "json5: Prototype Pollution in JSON5 via Parse Method", + "Description": "JSON5 is an extension to the popular JSON file format that aims to be easier to write and maintain by hand (e.g. for config files). The `parse` method of the JSON5 library before and including versions 1.0.1 and 2.2.1 does not restrict parsing of keys named `__proto__`, allowing specially crafted strings to pollute the prototype of the resulting object. This vulnerability pollutes the prototype of the object returned by `JSON5.parse` and not the global Object prototype, which is the commonly understood definition of Prototype Pollution. However, polluting the prototype of a single object can have significant security impact for an application if the object is later used in trusted operations. This vulnerability could allow an attacker to set arbitrary and unexpected keys on the object returned from `JSON5.parse`. The actual impact will depend on how applications utilize the returned object and how they filter unwanted keys, but could include denial of service, cross-site scripting, elevation of privilege, and in extreme cases, remote code execution. `JSON5.parse` should restrict parsing of `__proto__` keys when parsing JSON strings to objects. As a point of reference, the `JSON.parse` method included in JavaScript ignores `__proto__` keys. Simply changing `JSON5.parse` to `JSON.parse` in the examples above mitigates this vulnerability. This vulnerability is patched in json5 versions 1.0.2, 2.2.2, and later.", + "Severity": "HIGH", + "CweIDs": [ + "CWE-1321" + ], + "VendorSeverity": { + "azure": 3, + "ghsa": 3, + "nvd": 3, + "photon": 3, + "redhat": 2, + "ubuntu": 2 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:L/A:H", + "V3Score": 7.1 + }, + "nvd": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H", + "V3Score": 8.8 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H", + "V3Score": 8.8 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2022-46175", + "https://github.com/json5/json5", + "https://github.com/json5/json5/commit/62a65408408d40aeea14c7869ed327acead12972", + "https://github.com/json5/json5/commit/7774c1097993bc3ce9f0ac4b722a32bf7d6871c8", + "https://github.com/json5/json5/issues/199", + "https://github.com/json5/json5/issues/295", + "https://github.com/json5/json5/pull/298", + "https://github.com/json5/json5/security/advisories/GHSA-9c47-m6qq-7p4h", + "https://lists.debian.org/debian-lts-announce/2023/11/msg00021.html", + "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/3S26TLPLVFAJTUN3VIXFDEBEXDYO22CE", + "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/3S26TLPLVFAJTUN3VIXFDEBEXDYO22CE/", + "https://nvd.nist.gov/vuln/detail/CVE-2022-46175", + "https://ubuntu.com/security/notices/USN-6758-1", + "https://www.cve.org/CVERecord?id=CVE-2022-46175" + ], + "PublishedDate": "2022-12-24T04:15:08.787Z", + "LastModifiedDate": "2026-06-17T05:11:21.953Z" + }, + { + "VulnerabilityID": "CVE-2026-26996", + "VendorIDs": [ + "GHSA-3ppc-4f35-3m26" + ], + "PkgID": "minimatch@3.1.2", + "PkgName": "minimatch", + "PkgIdentifier": { + "PURL": "pkg:npm/minimatch@3.1.2", + "UID": "b5e061939f2d832f" + }, + "InstalledVersion": "3.1.2", + "FixedVersion": "10.2.1, 9.0.6, 8.0.5, 7.4.7, 6.2.1, 5.1.7, 4.2.4, 3.1.3", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2026-26996", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:a143b58f115c07f03310d0ab204452765e00e45350d5420e34f43db35855f683", + "Title": "minimatch: minimatch: Denial of Service via specially crafted glob patterns", + "Description": "minimatch is a minimal matching utility for converting glob expressions into JavaScript RegExp objects. Versions 10.2.0 and below are vulnerable to Regular Expression Denial of Service (ReDoS) when a glob pattern contains many consecutive * wildcards followed by a literal character that doesn't appear in the test string. Each * compiles to a separate [^/]*? regex group, and when the match fails, V8's regex engine backtracks exponentially across all possible splits. The time complexity is O(4^N) where N is the number of * characters. With N=15, a single minimatch() call takes ~2 seconds. With N=34, it hangs effectively forever. Any application that passes user-controlled strings to minimatch() as the pattern argument is vulnerable to DoS. This issue has been fixed in version 10.2.1.", + "Severity": "HIGH", + "CweIDs": [ + "CWE-1333" + ], + "VendorSeverity": { + "alma": 3, + "ghsa": 3, + "nvd": 3, + "oracle-oval": 3, + "redhat": 2, + "rocky": 3 + }, + "CVSS": { + "ghsa": { + "V40Vector": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N", + "V40Score": 8.7 + }, + "nvd": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V3Score": 7.5 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H", + "V3Score": 6.5 + } + }, + "References": [ + "https://access.redhat.com/errata/RHSA-2026:7896", + "https://access.redhat.com/security/cve/CVE-2026-26996", + "https://bugzilla.redhat.com/2441268", + "https://bugzilla.redhat.com/2442922", + "https://bugzilla.redhat.com/2448754", + "https://bugzilla.redhat.com/2453151", + "https://bugzilla.redhat.com/show_bug.cgi?id=2441268", + "https://bugzilla.redhat.com/show_bug.cgi?id=2442922", + "https://bugzilla.redhat.com/show_bug.cgi?id=2448754", + "https://bugzilla.redhat.com/show_bug.cgi?id=2453151", + "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2026-21710", + "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2026-26996", + "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2026-27135", + "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2026-27904", + "https://errata.almalinux.org/9/ALSA-2026-7896.html", + "https://errata.rockylinux.org/RLSA-2026:8339", + "https://github.com/isaacs/minimatch", + "https://github.com/isaacs/minimatch/commit/2e111f3a79abc00fa73110195de2c0f2351904f5", + "https://github.com/isaacs/minimatch/security/advisories/GHSA-3ppc-4f35-3m26", + "https://linux.oracle.com/cve/CVE-2026-26996.html", + "https://linux.oracle.com/errata/ELSA-2026-8339.html", + "https://nvd.nist.gov/vuln/detail/CVE-2026-26996", + "https://www.cve.org/CVERecord?id=CVE-2026-26996" + ], + "PublishedDate": "2026-02-20T03:16:01.62Z", + "LastModifiedDate": "2026-06-17T10:26:30.527Z" + }, + { + "VulnerabilityID": "CVE-2026-27903", + "VendorIDs": [ + "GHSA-7r86-cg39-jmmj" + ], + "PkgID": "minimatch@3.1.2", + "PkgName": "minimatch", + "PkgIdentifier": { + "PURL": "pkg:npm/minimatch@3.1.2", + "UID": "b5e061939f2d832f" + }, + "InstalledVersion": "3.1.2", + "FixedVersion": "10.2.3, 9.0.7, 8.0.6, 7.4.8, 6.2.2, 5.1.8, 4.2.5, 3.1.3", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2026-27903", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:666fbb71a40b63fe110135bbb1546526eef616a9bf7ff4d9d8f47627e62fcc4f", + "Title": "minimatch: minimatch: Denial of Service due to unbounded recursive backtracking via crafted glob patterns", + "Description": "minimatch is a minimal matching utility for converting glob expressions into JavaScript RegExp objects. Prior to version 10.2.3, 9.0.7, 8.0.6, 7.4.8, 6.2.2, 5.1.8, 4.2.5, and 3.1.3, `matchOne()` performs unbounded recursive backtracking when a glob pattern contains multiple non-adjacent `**` (GLOBSTAR) segments and the input path does not match. The time complexity is O(C(n, k)) -- binomial -- where `n` is the number of path segments and `k` is the number of globstars. With k=11 and n=30, a call to the default `minimatch()` API stalls for roughly 5 seconds. With k=13, it exceeds 15 seconds. No memoization or call budget exists to bound this behavior. Any application where an attacker can influence the glob pattern passed to `minimatch()` is vulnerable. The realistic attack surface includes build tools and task runners that accept user-supplied glob arguments (ESLint, Webpack, Rollup config), multi-tenant systems where one tenant configures glob-based rules that run in a shared process, admin or developer interfaces that accept ignore-rule or filter configuration as globs, and CI/CD pipelines that evaluate user-submitted config files containing glob patterns. An attacker who can place a crafted pattern into any of these paths can stall the Node.js event loop for tens of seconds per invocation. The pattern is 56 bytes for a 5-second stall and does not require authentication in contexts where pattern input is part of the feature. Versions 10.2.3, 9.0.7, 8.0.6, 7.4.8, 6.2.2, 5.1.8, 4.2.5, and 3.1.3 fix the issue.", + "Severity": "HIGH", + "CweIDs": [ + "CWE-407" + ], + "VendorSeverity": { + "ghsa": 3, + "redhat": 2 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V3Score": 7.5 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V3Score": 5.9 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2026-27903", + "https://github.com/isaacs/minimatch", + "https://github.com/isaacs/minimatch/commit/0bf499aa45f5059b56809cc3b75ff3eafeb8d748", + "https://github.com/isaacs/minimatch/security/advisories/GHSA-7r86-cg39-jmmj", + "https://nvd.nist.gov/vuln/detail/CVE-2026-27903", + "https://www.cve.org/CVERecord?id=CVE-2026-27903" + ], + "PublishedDate": "2026-02-26T02:16:21.353Z", + "LastModifiedDate": "2026-06-17T10:27:51.187Z" + }, + { + "VulnerabilityID": "CVE-2026-27904", + "VendorIDs": [ + "GHSA-23c5-xmqv-rm74" + ], + "PkgID": "minimatch@3.1.2", + "PkgName": "minimatch", + "PkgIdentifier": { + "PURL": "pkg:npm/minimatch@3.1.2", + "UID": "b5e061939f2d832f" + }, + "InstalledVersion": "3.1.2", + "FixedVersion": "10.2.3, 9.0.7, 8.0.6, 7.4.8, 6.2.2, 5.1.8, 4.2.5, 3.1.4", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2026-27904", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:e07225449416f0760af1442bd920b14295c6820dc934e700108042f2e1a29c16", + "Title": "minimatch: Minimatch: Denial of Service via catastrophic backtracking in glob expressions", + "Description": "minimatch is a minimal matching utility for converting glob expressions into JavaScript RegExp objects. Prior to version 10.2.3, 9.0.7, 8.0.6, 7.4.8, 6.2.2, 5.1.8, 4.2.5, and 3.1.4, nested `*()` extglobs produce regexps with nested unbounded quantifiers (e.g. `(?:(?:a|b)*)*`), which exhibit catastrophic backtracking in V8. With a 12-byte pattern `*(*(*(a|b)))` and an 18-byte non-matching input, `minimatch()` stalls for over 7 seconds. Adding a single nesting level or a few input characters pushes this to minutes. This is the most severe finding: it is triggered by the default `minimatch()` API with no special options, and the minimum viable pattern is only 12 bytes. The same issue affects `+()` extglobs equally. Versions 10.2.3, 9.0.7, 8.0.6, 7.4.8, 6.2.2, 5.1.8, 4.2.5, and 3.1.4 fix the issue.", + "Severity": "HIGH", + "CweIDs": [ + "CWE-1333" + ], + "VendorSeverity": { + "alma": 3, + "ghsa": 3, + "oracle-oval": 3, + "redhat": 2, + "rocky": 3 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V3Score": 7.5 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H", + "V3Score": 6.5 + } + }, + "References": [ + "https://access.redhat.com/errata/RHSA-2026:7896", + "https://access.redhat.com/security/cve/CVE-2026-27904", + "https://bugzilla.redhat.com/2441268", + "https://bugzilla.redhat.com/2442922", + "https://bugzilla.redhat.com/2448754", + "https://bugzilla.redhat.com/2453151", + "https://bugzilla.redhat.com/show_bug.cgi?id=2441268", + "https://bugzilla.redhat.com/show_bug.cgi?id=2442922", + "https://bugzilla.redhat.com/show_bug.cgi?id=2448754", + "https://bugzilla.redhat.com/show_bug.cgi?id=2453151", + "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2026-21710", + "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2026-26996", + "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2026-27135", + "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2026-27904", + "https://errata.almalinux.org/9/ALSA-2026-7896.html", + "https://errata.rockylinux.org/RLSA-2026:8339", + "https://github.com/isaacs/minimatch", + "https://github.com/isaacs/minimatch/commit/11d0df6165d15a955462316b26d52e5efae06fce", + "https://github.com/isaacs/minimatch/security/advisories/GHSA-23c5-xmqv-rm74", + "https://linux.oracle.com/cve/CVE-2026-27904.html", + "https://linux.oracle.com/errata/ELSA-2026-8339.html", + "https://nvd.nist.gov/vuln/detail/CVE-2026-27904", + "https://www.cve.org/CVERecord?id=CVE-2026-27904" + ], + "PublishedDate": "2026-02-26T02:16:21.76Z", + "LastModifiedDate": "2026-06-17T10:27:51.297Z" + }, + { + "VulnerabilityID": "CVE-2025-68470", + "VendorIDs": [ + "GHSA-9jcx-v3wj-wh4m" + ], + "PkgID": "react-router@6.2.2", + "PkgName": "react-router", + "PkgIdentifier": { + "PURL": "pkg:npm/react-router@6.2.2", + "UID": "a480eb42587bd283" + }, + "InstalledVersion": "6.2.2", + "FixedVersion": "6.30.2, 7.9.6", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2025-68470", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:fbf12b2efba25a454c2bc629f9957df38393eee5ddb6bd85c3a51179ea06fe9e", + "Title": "react-router: React Router unexpected external redirect", + "Description": "React Router is a router for React. In versions 6.0.0 through 6.30.1 and 7.0.0 through 7.9.5, an attacker-supplied path can be crafted so that when a React Router application navigates to it via navigate(), \u003cLink\u003e, or redirect(), the app performs a navigation/redirect to an external URL. This is only an issue if you are passing untrusted content into navigation paths in your application code. This issue has been patched in versions 6.30.2 and 7.9.6.", + "Severity": "MEDIUM", + "CweIDs": [ + "CWE-601" + ], + "VendorSeverity": { + "ghsa": 2, + "redhat": 2 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N", + "V3Score": 6.5 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N", + "V3Score": 6.5 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2025-68470", + "https://github.com/remix-run/react-router", + "https://github.com/remix-run/react-router/security/advisories/GHSA-9jcx-v3wj-wh4m", + "https://nvd.nist.gov/vuln/detail/CVE-2025-68470", + "https://www.cve.org/CVERecord?id=CVE-2025-68470" + ], + "PublishedDate": "2026-01-10T03:15:48.477Z", + "LastModifiedDate": "2026-06-17T09:59:06.99Z" + }, + { + "VulnerabilityID": "CVE-2022-25883", + "VendorIDs": [ + "GHSA-c2qf-rxjj-qqgw" + ], + "PkgID": "semver@6.3.0", + "PkgName": "semver", + "PkgIdentifier": { + "PURL": "pkg:npm/semver@6.3.0", + "UID": "9c3173199e88b8ee" + }, + "InstalledVersion": "6.3.0", + "FixedVersion": "7.5.2, 6.3.1, 5.7.2", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2022-25883", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:153284b65ccf77b3a77d60cf10232bbc109794bf28585e9cfca0092eb4e32de0", + "Title": "nodejs-semver: Regular expression denial of service", + "Description": "Versions of the package semver before 7.5.2 are vulnerable to Regular Expression Denial of Service (ReDoS) via the function new Range, when untrusted user data is provided as a range.\r\r\r", + "Severity": "HIGH", + "CweIDs": [ + "CWE-1333" + ], + "VendorSeverity": { + "alma": 3, + "amazon": 3, + "cbl-mariner": 3, + "ghsa": 3, + "nvd": 3, + "oracle-oval": 3, + "redhat": 2, + "rocky": 3 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V3Score": 7.5 + }, + "nvd": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V3Score": 7.5 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V3Score": 7.5 + } + }, + "References": [ + "https://access.redhat.com/errata/RHSA-2023:5363", + "https://access.redhat.com/security/cve/CVE-2022-25883", + "https://bugzilla.redhat.com/2216475", + "https://bugzilla.redhat.com/2230948", + "https://bugzilla.redhat.com/2230955", + "https://bugzilla.redhat.com/2230956", + "https://bugzilla.redhat.com/show_bug.cgi?id=2216475", + "https://bugzilla.redhat.com/show_bug.cgi?id=2230948", + "https://bugzilla.redhat.com/show_bug.cgi?id=2230955", + "https://bugzilla.redhat.com/show_bug.cgi?id=2230956", + "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-25883", + "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-32002", + "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-32006", + "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-32559", + "https://errata.almalinux.org/9/ALSA-2023-5363.html", + "https://errata.rockylinux.org/RLSA-2023:5362", + "https://github.com/advisories/GHSA-c2qf-rxjj-qqgw", + "https://github.com/npm/node-semver", + "https://github.com/npm/node-semver/blob/main/classes/range.js#L97-L104", + "https://github.com/npm/node-semver/blob/main/classes/range.js%23L97-L104", + "https://github.com/npm/node-semver/blob/main/internal/re.js#L138", + "https://github.com/npm/node-semver/blob/main/internal/re.js#L160", + "https://github.com/npm/node-semver/blob/main/internal/re.js%23L138", + "https://github.com/npm/node-semver/blob/main/internal/re.js%23L160", + "https://github.com/npm/node-semver/commit/2f8fd41487acf380194579ecb6f8b1bbfe116be0", + "https://github.com/npm/node-semver/commit/717534ee353682f3bcf33e60a8af4292626d4441", + "https://github.com/npm/node-semver/commit/928e56d21150da0413a3333a3148b20e741a920c", + "https://github.com/npm/node-semver/pull/564", + "https://github.com/npm/node-semver/pull/585", + "https://github.com/npm/node-semver/pull/593", + "https://linux.oracle.com/cve/CVE-2022-25883.html", + "https://linux.oracle.com/errata/ELSA-2023-5363.html", + "https://nvd.nist.gov/vuln/detail/CVE-2022-25883", + "https://security.netapp.com/advisory/ntap-20241025-0004", + "https://security.netapp.com/advisory/ntap-20241025-0004/", + "https://security.snyk.io/vuln/SNYK-JS-SEMVER-3247795", + "https://www.cve.org/CVERecord?id=CVE-2022-25883" + ], + "PublishedDate": "2023-06-21T05:15:09.06Z", + "LastModifiedDate": "2026-06-17T04:34:26.36Z" + }, + { + "VulnerabilityID": "CVE-2026-33532", + "VendorIDs": [ + "GHSA-48c2-rrv3-qjmp" + ], + "PkgID": "yaml@1.10.2", + "PkgName": "yaml", + "PkgIdentifier": { + "PURL": "pkg:npm/yaml@1.10.2", + "UID": "da529d3cb346002b" + }, + "InstalledVersion": "1.10.2", + "FixedVersion": "2.8.3, 1.10.3", + "Status": "fixed", + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2026-33532", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Fingerprint": "sha256:2ec07bb62735d74656f8a8156fa08ffffd814cb9c9f0621edd6ba780fe7bc436", + "Title": "yaml: yaml: Denial of Service via deeply nested YAML document parsing", + "Description": "`yaml` is a YAML parser and serialiser for JavaScript. Parsing a YAML document with a version of `yaml` on the 1.x branch prior to 1.10.3 or on the 2.x branch prior to 2.8.3 may throw a RangeError due to a stack overflow. The node resolution/composition phase uses recursive function calls without a depth bound. An attacker who can supply YAML for parsing can trigger a `RangeError: Maximum call stack size exceeded` with a small payload (~2–10 KB). The `RangeError` is not a `YAMLParseError`, so applications that only catch YAML-specific errors will encounter an unexpected exception type. Depending on the host application's exception handling, this can fail requests or terminate the Node.js process. Flow sequences allow deep nesting with minimal bytes (2 bytes per level: one `[` and one `]`). On the default Node.js stack, approximately 1,000–5,000 levels of nesting (2–10 KB input) exhaust the call stack. The exact threshold is environment-dependent (Node.js version, stack size, call stack depth at invocation). Note: the library's `Parser` (CST phase) uses a stack-based iterative approach and is not affected. Only the compose/resolve phase uses actual call-stack recursion. All three public parsing APIs are affected: `YAML.parse()`, `YAML.parseDocument()`, and `YAML.parseAllDocuments()`. Versions 1.10.3 and 2.8.3 contain a patch.", + "Severity": "MEDIUM", + "CweIDs": [ + "CWE-674" + ], + "VendorSeverity": { + "ghsa": 2, + "redhat": 2 + }, + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L", + "V3Score": 4.3 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H", + "V3Score": 6.5 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2026-33532", + "https://github.com/eemeli/yaml", + "https://github.com/eemeli/yaml/commit/1e84ebbea7ec35011a4c61bbb820a529ee4f359b", + "https://github.com/eemeli/yaml/releases/tag/v1.10.3", + "https://github.com/eemeli/yaml/releases/tag/v2.8.3", + "https://github.com/eemeli/yaml/security/advisories/GHSA-48c2-rrv3-qjmp", + "https://nvd.nist.gov/vuln/detail/CVE-2026-33532", + "https://www.cve.org/CVERecord?id=CVE-2026-33532" + ], + "PublishedDate": "2026-03-26T20:16:15.543Z", + "LastModifiedDate": "2026-06-17T10:37:39.88Z" + } + ] + } + ] +} diff --git a/backend/analyzer/test/test_cve_fetcher.py b/backend/analyzer/test/test_cve_fetcher.py index b1df86b..d4072f5 100644 --- a/backend/analyzer/test/test_cve_fetcher.py +++ b/backend/analyzer/test/test_cve_fetcher.py @@ -1,29 +1,42 @@ from datetime import datetime +import pytest + from analyzer.services.cve_fetcher import CVEFetcher from utilities.constants import BaseSeverity, AttackVector, AttackComplexity, UserInteraction, IntegrityImpact, \ AvailabilityImpact, ConfidentialityImpact, Scope, PrivilegesRequired cve_id = "CVE-2021-44228" -cve_fetcher = CVEFetcher(cve_id=cve_id) -cve_data = cve_fetcher.generate() -def test_description(): +@pytest.fixture +def cve_data(): + fetcher = CVEFetcher(cve_id=cve_id) + return fetcher.generate() + + +@pytest.mark.nvd_integration +def test_real_nvd_api_contract(): + fetcher = CVEFetcher(cve_id=cve_id) + data = fetcher.generate() + assert fetcher.successful + assert len(data["description"]) > 0 + assert 0 < data["cve_attributes"]["baseScore"] <= 10 + + +def test_description(cve_data): assert len(cve_data["description"]) > 0 -def test_dates(): +def test_dates(cve_data): published = cve_data["published"] assert isinstance(published, datetime) - updated = cve_data["updated"] assert isinstance(updated, datetime) -def test_cve_attributes_cvss_v3(): +def test_cve_attributes_cvss_v3(cve_data): attributes = cve_data["cve_attributes"] - assert 0 < attributes["baseScore"] <= 10 assert attributes["baseSeverity"] in BaseSeverity.names assert attributes["attackVector"] in AttackVector.names @@ -36,9 +49,9 @@ def test_cve_attributes_cvss_v3(): assert attributes["scope"] in Scope.names -def test_epss_score(): +def test_epss_score(cve_data): assert 0 <= float(cve_data["epss"]) <= 1.0 -def test_vendor_reference(): +def test_vendor_reference(cve_data): assert len(cve_data["vendor_reference"]) >= 0 diff --git a/backend/analyzer/test/test_e2e.py b/backend/analyzer/test/test_e2e.py new file mode 100644 index 0000000..c553632 --- /dev/null +++ b/backend/analyzer/test/test_e2e.py @@ -0,0 +1,155 @@ +""" +End-to-end tests for the report analysis pipeline. + +These tests verify the full flow: upload a Dependency-Check OWASP report via API, +confirm parsing, DB storage, and threshold behavior. Uses pre-baked JSON fixtures +(no live NVD calls). + +Requires: running PostgreSQL (via Docker compose). +Run with: pytest -m e2e +""" +import json +import os + +import pytest +from django.test import LiveServerTestCase +from rest_framework.test import APIRequestFactory + +from analyzer.manager.project_manager import ProjectManager +from analyzer.models import CVEObject, Dependency, Project, Report +from analyzer.views import AnalyzeReport + + +def _load_fixture(name): + path = os.path.join(os.path.dirname(__file__), "data", name) + with open(path) as f: + return f.read() + + +@pytest.mark.e2e +class TestEndToEndReportAnalysis(LiveServerTestCase): + """Upload OWASP reports → verify DB state and threshold behavior.""" + + def setUp(self): + self.factory = APIRequestFactory() + self.view = AnalyzeReport.as_view() + + # Create project + self.project = Project.objects.create( + project_id="e2e-test-project", + project_name="E2E Test", + deployment_threshold="HIGH", + ) + self.key = ProjectManager(self.project).generate_key() + + # ------------------------------------------------------------------ # + # Helpers # + # ------------------------------------------------------------------ # + def _upload(self, fixture_name, params=None): + report = _load_fixture(fixture_name) + base_params = { + "fileType": "json", + "toolName": "owasp", + "projectId": "e2e-test-project", + "projectName": "E2E Test", + "deploymentThreshold": "HIGH", + } + if params: + base_params.update(params) + + qs = "&".join(f"{k}={v}" for k, v in base_params.items()) + url = f"/analyzer/api?{qs}" + + request = self.factory.post( + url, + data=report, + content_type="application/json", + HTTP_API_KEY=self.key, + ) + return self.view(request) + + # ------------------------------------------------------------------ # + # Tests # + # ------------------------------------------------------------------ # + def test_large_report_parses_correctly(self): + """Upload the large OWASP fixture → expect 54 deps, 33 CVEs.""" + resp = self._upload("dependency-check-report-python-large.json") + assert resp.status_code in (200, 406), f"Unexpected {resp.status_code}" + + deps = Dependency.objects.filter(project=self.project) + assert deps.count() == 54, f"Expected 54 deps, got {deps.count()}" + + reports = Report.objects.filter(dependency__project=self.project) + assert reports.count() == 33, f"Expected 33 CVEs, got {reports.count()}" + + def test_small_report_parses_correctly(self): + """Upload the small OWASP fixture → expect 19 deps, 1 CVE.""" + resp = self._upload("dependency-check-report-python-small.json") + assert resp.status_code in (200, 406), f"Unexpected {resp.status_code}" + + deps = Dependency.objects.filter(project=self.project) + assert deps.count() == 19, f"Expected 19 deps, got {deps.count()}" + + reports = Report.objects.filter(dependency__project=self.project) + assert reports.count() == 1, f"Expected 1 CVE, got {reports.count()}" + + def test_cve_ids_valid_format(self): + """All created CVEObject IDs must match CVE-YYYY-NNNNN+ pattern.""" + self._upload("dependency-check-report-python-large.json") + cves = CVEObject.objects.all() + for cve in cves: + assert cve.cve_id.startswith("CVE-"), f"Bad CVE ID: {cve.cve_id}" + parts = cve.cve_id.split("-") + assert len(parts) == 3, f"Bad CVE format: {cve.cve_id}" + assert parts[1].isdigit(), f"Non-numeric year: {cve.cve_id}" + assert parts[2].isdigit(), f"Non-numeric ID: {cve.cve_id}" + + def test_cve_severity_not_null(self): + """Every CVEObject created must have a non-empty base_severity.""" + self._upload("dependency-check-report-python-large.json") + for cve in CVEObject.objects.all(): + assert cve.base_severity, f"CVE {cve.cve_id} has empty severity" + + def test_threshold_rejects_when_exceeded(self): + """With LOW threshold, large report should trigger 406.""" + resp = self._upload( + "dependency-check-report-python-large.json", + params={"deploymentThreshold": "LOW"}, + ) + assert resp.status_code == 406, f"Expected 406, got {resp.status_code}" + + def test_trivy_report_lands_in_database(self): + """Upload Trivy fixture → verify deps + CVEs are stored in the DB.""" + resp = self._upload( + "trivy-report-securechecknext.json", + params={"toolName": "trivy", "deploymentThreshold": "HIGHEST"}, + ) + assert resp.status_code in (200, 406), f"Unexpected {resp.status_code}" + + deps = Dependency.objects.filter(project=self.project) + assert deps.count() == 17, f"Expected 17 deps, got {deps.count()}" + + # The trivy fixture has 58 raw vulnerability entries. The parser dedupes + # within a single dep (so requests@2.32.3 has 2 CVEs, not 4), yielding + # 56 (dep, cve) pairs. Across 17 deps, 55 unique CVE-objects. + reports = Report.objects.filter(dependency__project=self.project) + assert reports.count() == 56, f"Expected 56 Reports, got {reports.count()}" + + cves = CVEObject.objects.filter(report__dependency__project=self.project).distinct() + assert cves.count() == 55, f"Expected 55 unique CVEObjects, got {cves.count()}" + for cve in cves: + assert cve.cve_id, f"Empty CVE id for {cve}" + + def test_cyclonedx_report_lands_in_database(self): + """Upload CycloneDX fixture → verify components are stored in the DB.""" + resp = self._upload( + "cyclonedx-report-securechecknext.json", + params={"toolName": "cyclonedx"}, + ) + assert resp.status_code in (200, 406), f"Unexpected {resp.status_code}" + + deps = Dependency.objects.filter(project=self.project) + assert deps.count() == 14, f"Expected 14 deps, got {deps.count()}" + + reports = Report.objects.filter(dependency__project=self.project) + assert reports.count() == 0, f"Expected 0 CVEs, got {reports.count()}" diff --git a/backend/analyzer/test/test_parser/test_cyclonedx.py b/backend/analyzer/test/test_parser/test_cyclonedx.py new file mode 100644 index 0000000..d5de695 --- /dev/null +++ b/backend/analyzer/test/test_parser/test_cyclonedx.py @@ -0,0 +1,58 @@ +from unittest import TestCase +import json +import os + +from analyzer.parser import cyclonedx_parser +from analyzer.manager.parser_manager import ParserManager +from securecheckplus.settings import BASE_DIR + + +CYCLONEDX_FIXTURE = os.path.join(BASE_DIR, "analyzer/test/data/cyclonedx-report-securechecknext.json") + + +class CycloneDXJSONTest(TestCase): + def test_parse_json_from_string(self): + """Verify cyclonedx parser handles JSON string input.""" + with open(CYCLONEDX_FIXTURE) as f: + json_string = f.read() + result = cyclonedx_parser.parse_json(json_string) + self.assertIsInstance(result, dict) + self.assertGreater(len(result), 0, "Should parse at least one dependency") + + def test_parse_json_from_dict(self): + """Verify cyclonedx parser handles dict input (regression test for dict-handling bug).""" + with open(CYCLONEDX_FIXTURE) as f: + data = json.load(f) + result = cyclonedx_parser.parse_json(data) + self.assertIsInstance(result, dict) + self.assertGreater(len(result), 0, "Should parse at least one dependency") + + def test_parse_json_consistent_results(self): + """Verify string and dict input produce identical results.""" + with open(CYCLONEDX_FIXTURE) as f: + json_string = f.read() + f.seek(0) + data = json.load(f) + from_str = cyclonedx_parser.parse_json(json_string) + from_dict = cyclonedx_parser.parse_json(data) + self.assertEqual(set(from_str.keys()), set(from_dict.keys())) + + def test_via_parser_manager(self): + """Verify cyclonedx works through the ParserManager dispatch (regression test for dict crash).""" + with open(CYCLONEDX_FIXTURE) as f: + data = json.load(f) + mgr = ParserManager(tool_name="cyclonedx", file_type="json") + result = mgr.parse(data) + self.assertGreater(len(result), 0) + # Each result should have a vulnerability list + for key, val in result.items(): + self.assertIsInstance(val.vulnerabilities, list) + + def test_with_existing_test_object_fixture(self): + """Verify the original test_object fixture still parses (regression test).""" + legacy_fixture = os.path.join(BASE_DIR, "analyzer/test/test_object/cyclonedx/report.json") + if os.path.exists(legacy_fixture): + with open(legacy_fixture) as f: + data = json.load(f) + result = cyclonedx_parser.parse_json(data) + self.assertIsInstance(result, dict) diff --git a/backend/analyzer/test/test_parser/test_trivy.py b/backend/analyzer/test/test_parser/test_trivy.py new file mode 100644 index 0000000..f679d03 --- /dev/null +++ b/backend/analyzer/test/test_parser/test_trivy.py @@ -0,0 +1,49 @@ +from unittest import TestCase +import json +import os + +from analyzer.parser import trivy_parser +from analyzer.manager.parser_manager import ParserManager +from securecheckplus.settings import BASE_DIR + + +TRIVY_FIXTURE = os.path.join(BASE_DIR, "analyzer/test/data/trivy-report-securechecknext.json") + + +class TrivyJSONTest(TestCase): + def test_parse_json_from_string(self): + """Verify trivy parser handles JSON string input.""" + with open(TRIVY_FIXTURE) as f: + json_string = f.read() + result = trivy_parser.parse_json(json_string) + self.assertIsInstance(result, dict) + self.assertGreater(len(result), 0, "Should parse at least one dependency") + + def test_parse_json_from_dict(self): + """Verify trivy parser handles dict input (as DRF request.data provides).""" + with open(TRIVY_FIXTURE) as f: + data = json.load(f) + result = trivy_parser.parse_json(data) + self.assertIsInstance(result, dict) + self.assertGreater(len(result), 0, "Should parse at least one dependency") + + def test_parse_json_consistent_results(self): + """Verify string and dict input produce identical results.""" + with open(TRIVY_FIXTURE) as f: + json_string = f.read() + f.seek(0) + data = json.load(f) + from_str = trivy_parser.parse_json(json_string) + from_dict = trivy_parser.parse_json(data) + self.assertEqual(set(from_str.keys()), set(from_dict.keys())) + + def test_via_parser_manager(self): + """Verify trivy works through the ParserManager dispatch.""" + with open(TRIVY_FIXTURE) as f: + data = json.load(f) + mgr = ParserManager(tool_name="trivy", file_type="json") + result = mgr.parse(data) + self.assertGreater(len(result), 0) + # Each result should have a vulnerability list + for key, val in result.items(): + self.assertIsInstance(val.vulnerabilities, list) diff --git a/backend/assets/.gitkeep b/backend/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/backend/entrypoint.sh b/backend/entrypoint.sh index 3049d70..8c78812 100644 --- a/backend/entrypoint.sh +++ b/backend/entrypoint.sh @@ -1,4 +1,5 @@ #!/bin/sh +set -e echo "Waiting for postgres..." while ! nc -z $POSTGRES_HOST $POSTGRES_PORT; do sleep 1; done; @@ -7,6 +8,7 @@ echo "PostgreSQL started" python manage.py createcachetable rate_limit python manage.py migrate +# Collect Django admin staticfiles (not frontend assets - those are served by Nginx in the frontend container) python manage.py collectstatic --no-input exec "$@" diff --git a/backend/env.template b/backend/env.template index fe9d460..745ffef 100644 --- a/backend/env.template +++ b/backend/env.template @@ -8,6 +8,9 @@ IS_DEV=True # This is the URL that the application can be reached at FULLY_QUALIFIED_DOMAIN_NAME=http://localhost:8080 +# The log level of the backend application +LOG_LEVEL=INFO + ############################################################################################################## # Setup of API keys and secrets # Except for the NVD_API_KEY the variables can be filled with random keys! diff --git a/backend/pytest.ini b/backend/pytest.ini index ac3d988..a656fe0 100644 --- a/backend/pytest.ini +++ b/backend/pytest.ini @@ -1,3 +1,6 @@ [pytest] -addopts = --nomigrations --reuse-db -DJANGO_SETTINGS_MODULE = securecheckplus.settings \ No newline at end of file +addopts = --nomigrations --reuse-db -m "not nvd_integration and not e2e" +DJANGO_SETTINGS_MODULE = securecheckplus.settings +markers = + nvd_integration: tests that call the real NVD API (requires internet + API key) + e2e: end-to-end tests that require a running PostgreSQL instance \ No newline at end of file diff --git a/backend/requirements.lock b/backend/requirements.lock new file mode 100644 index 0000000..54f181c --- /dev/null +++ b/backend/requirements.lock @@ -0,0 +1,30 @@ +asgiref==3.11.1 +boolean.py==5.0 +certifi==2026.6.17 +charset-normalizer==3.4.7 +coverage==7.6.4 +cyclonedx-python-lib==8.2.1 +defusedxml==0.7.1 +Django==5.1.2 +django-cors-headers==4.5.0 +djangorestframework==3.15.2 +gunicorn==23.0.0 +idna==3.18 +iniconfig==2.3.0 +ldap3==2.9.1 +license-expression==30.4.4 +lxml==5.3.0 +packageurl-python==0.17.6 +packaging==26.2 +pluggy==1.6.0 +psycopg2-binary==2.9.10 +py-serializable==1.1.2 +pyasn1==0.6.3 +pytest==8.3.3 +pytest-django==4.9.0 +python-dotenv==1.0.1 +requests==2.32.3 +sortedcontainers==2.4.0 +sqlparse==0.5.5 +urllib3==2.7.0 +whitenoise==6.7.0 diff --git a/backend/securecheckplus/settings.py b/backend/securecheckplus/settings.py index 13df1d2..c1bb858 100644 --- a/backend/securecheckplus/settings.py +++ b/backend/securecheckplus/settings.py @@ -13,6 +13,7 @@ import json import logging import os +import secrets import sys from pathlib import Path @@ -54,6 +55,21 @@ def get_env_variable_or_shutdown_gracefully(var_name): USER_USERNAME = os.environ.get("USER_USERNAME") USER_PASSWORD = os.environ.get("USER_PASSWORD") +if IS_DEV: + # Generate random credentials if not explicitly set in dev mode + if not ADMIN_USERNAME: + ADMIN_USERNAME = "admin" + if not ADMIN_PASSWORD: + ADMIN_PASSWORD = secrets.token_urlsafe(16) + if not USER_USERNAME: + USER_USERNAME = "user" + if not USER_PASSWORD: + USER_PASSWORD = secrets.token_urlsafe(16) + logging.warning( + f"DEV MODE: Using credentials - Admin: {ADMIN_USERNAME}, User: {USER_USERNAME}. " + f"DO NOT use these in production!" + ) + # If not building image (no env variables set) and # If LDAP_HOST has been set (LDAP is being used for authentication) -> all other LDAP variables need to be set # If LDAP_HOST has not been set (Use the hardcoded admin and user for authentication) -> all the hardcoded admin and @@ -135,9 +151,13 @@ def get_env_variable_or_shutdown_gracefully(var_name): ], 'DEFAULT_THROTTLE_CLASSES': [ 'rest_framework.throttling.ScopedRateThrottle', + 'rest_framework.throttling.AnonRateThrottle', + 'rest_framework.throttling.UserRateThrottle', ], 'DEFAULT_THROTTLE_RATES': { - 'login': '30/min', + 'login': '5/min', + 'anon': '100/day', + 'user': '1000/day', } } @@ -214,8 +234,10 @@ def get_env_variable_or_shutdown_gracefully(var_name): # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/4.0/howto/static-files/ +# Note: In 3Tier architecture, static files are served by the frontend container (Nginx). +# The backend only serves Django admin staticfiles. +# For native dev, STATICFILES_DIRS is set further below. -STATICFILES_DIRS = [os.path.join(BASE_DIR, "assets")] STATIC_URL = f"/{BASE_URL}/static/" if BASE_URL else "/static/" STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles") # Location where the staticfiles will be collected @@ -282,9 +304,16 @@ def format(self, record): } # Security Settings -if "https" in FULLY_QUALIFIED_DOMAIN_NAME: +if FULLY_QUALIFIED_DOMAIN_NAME.startswith("https://"): CSRF_COOKIE_SECURE = True SESSION_COOKIE_SECURE = True + SECURE_SSL_REDIRECT = True + SECURE_HSTS_SECONDS = 31536000 + SECURE_HSTS_INCLUDE_SUBDOMAINS = True + SECURE_HSTS_PRELOAD = True + SECURE_BROWSER_XSS_FILTER = True + SECURE_CONTENT_TYPE_NOSNIFF = True + X_FRAME_OPTIONS = "DENY" else: CSRF_COOKIE_SECURE = False SESSION_COOKIE_SECURE = False @@ -293,10 +322,36 @@ def format(self, record): CORS_ALLOWED_ORIGINS = [ FULLY_QUALIFIED_DOMAIN_NAME, ] + +if IS_DEV: + CORS_ALLOWED_ORIGINS.extend([ + "http://localhost:3000", + "http://localhost:8000", + "http://127.0.0.1:3000", + "http://127.0.0.1:8000", + ]) CSRF_TRUSTED_ORIGINS = [ FULLY_QUALIFIED_DOMAIN_NAME, ] +# Required for cross-origin requests with credentials (cookies/session). +# Needed when REACT_APP_API_URL points directly to the backend port (preview setup). +CORS_ALLOW_CREDENTIALS = True SESSION_EXPIRE_AT_BROWSER_CLOSE = False SESSION_SAVE_EVERY_REQUEST = True SESSION_COOKIE_AGE = 60 * 60 * 24 * 30 # 30 days + +# Content Security Policy +CSP_DEFAULT_SRC = ("'self'",) +CSP_IMG_SRC = ( + "'self'", + "data:", + "*.interssl.com", + "www.wkoecg.at", + "*.geotrust.com", + "*.paypal.com", + "*.amazonaws.com", + "*.google-analytics.com", + "*.cloudflare.com", + "api.dicebear.com", +) diff --git a/backend/securecheckplus/urls.py b/backend/securecheckplus/urls.py index d34eacb..a10369b 100644 --- a/backend/securecheckplus/urls.py +++ b/backend/securecheckplus/urls.py @@ -1,30 +1,23 @@ -"""SecureCheckPlus URL Configuration - -The `urlpatterns` list routes URLs to views. For more information please see: - https://docs.djangoproject.com/en/4.0/topics/http/urls/ -Examples: -Function views - 1. Add an import: from my_app import views - 2. Add a URL to urlpatterns: path('', views.home, name='home') -Class-based views - 1. Add an import: from other_app.views import Home - 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') -Including another URLconf - 1. Import the include() function: from django.urls import include, path - 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) -""" import os from django.conf import settings -from django.conf.urls.static import static -from django.contrib.staticfiles.urls import staticfiles_urlpatterns -from django.http import HttpResponse +from django.http import JsonResponse from django.urls import path, include, re_path from django.views.generic.base import TemplateView from analyzer.views import AnalyzeReport, health_endpoint from securecheckplus.settings import BASE_URL -from webserver.views.misc_views import AppView, HtmlView +from webserver.views.misc_views import HtmlView, AppView + + +def api_404_view(request, exception=None): + """Return JSON 404 for API requests instead of HTML""" + return JsonResponse( + {"detail": "Not found."}, + status=404, + content_type="application/json" + ) + webserver_path = f"{BASE_URL}/api/" if BASE_URL else "api/" analyzer_path = f"{BASE_URL}/analyzer/api" if BASE_URL else "analyzer/api" @@ -35,13 +28,14 @@ path("check_health", health_endpoint), path(webserver_path, include("webserver.urls")), path("robots.txt", TemplateView.as_view(template_name="robots.txt", content_type="text/plain")), - re_path(rf'{base_url_pattern}html/(?P[-a-z_A-Z0-9]+)\.html$', HtmlView.as_view()), - re_path(rf'{base_url_pattern}(?:.*)/?$', AppView.as_view()), ] -# Serving the media files in development mode +# In native dev mode (python manage.py runserver), keep SPA routes as a fallback. +# In 3-tier Docker mode, Nginx serves the frontend and Django is API-only. if settings.IS_DEV: - urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) - urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) -else: - urlpatterns += staticfiles_urlpatterns() + urlpatterns += [ + re_path(rf'{base_url_pattern}html/(?P[-a-z_A-Z0-9]+)\.html$', HtmlView.as_view()), + re_path(rf'{base_url_pattern}(?:.*)/?$', AppView.as_view()), + ] + +handler404 = api_404_view diff --git a/backend/webserver/manager/authentication_manager.py b/backend/webserver/manager/authentication_manager.py index c5db7d7..48f81c6 100644 --- a/backend/webserver/manager/authentication_manager.py +++ b/backend/webserver/manager/authentication_manager.py @@ -1,5 +1,6 @@ import logging import os +import hmac import ldap3.core.exceptions from django.contrib import auth @@ -7,7 +8,7 @@ from django.contrib.auth.models import Group from securecheckplus.settings import ADMIN_USERNAME, ADMIN_PASSWORD, USER_PASSWORD, USER_USERNAME, LDAP_HOST, LDAP_USER_BASE_DN, LDAP_ADMIN_GROUP_DN, LDAP_BASE_GROUP_DN, \ - LDAP_ADMIN_DN, LDAP_ADMIN_PASSWORD, LDAP_USER_SEARCH_FILTER + LDAP_ADMIN_DN, LDAP_ADMIN_PASSWORD, LDAP_USER_SEARCH_FILTER, IS_DEV from utilities.exceptions import Unauthorized from webserver.manager.ldap_adapter import LdapAdapter from webserver.models import User @@ -86,12 +87,12 @@ def authenticate(self, request, username=None, password=None, **kwargs): logger.warning(f"User '{username}' is not a member of required groups!") return None - elif ADMIN_USERNAME and ADMIN_PASSWORD and ADMIN_USERNAME == username and ADMIN_PASSWORD == password: + elif IS_DEV and ADMIN_USERNAME and ADMIN_PASSWORD and ADMIN_USERNAME == username and hmac.compare_digest(ADMIN_PASSWORD, password): user = User.objects.get_or_create(username=username)[0] user.groups.add(Group.objects.get_or_create(name="admin")[0]) return user - elif USER_USERNAME and USER_PASSWORD and USER_USERNAME == username and USER_PASSWORD == password: + elif IS_DEV and USER_USERNAME and USER_PASSWORD and USER_USERNAME == username and hmac.compare_digest(USER_PASSWORD, password): user = User.objects.get_or_create(username=username)[0] return user diff --git a/backend/webserver/manager/ldap_adapter.py b/backend/webserver/manager/ldap_adapter.py index 85f33ec..b8b75ae 100644 --- a/backend/webserver/manager/ldap_adapter.py +++ b/backend/webserver/manager/ldap_adapter.py @@ -1,6 +1,7 @@ import logging from ldap3 import Server, ALL, Connection +from ldap3.utils.conv import escape_filter_chars logger = logging.getLogger(__name__) @@ -22,7 +23,8 @@ def __init__( self._user_search_filter = user_search_filter def get_ldap_user(self, username:str): - search_filter = self._user_search_filter.replace("VALUE", username) + safe_username = escape_filter_chars(username) + search_filter = self._user_search_filter.replace("VALUE", safe_username) return search_filter def admin_login(self) -> Connection: diff --git a/backend/webserver/views/authentication_view.py b/backend/webserver/views/authentication_view.py index 3807f1a..22688c8 100644 --- a/backend/webserver/views/authentication_view.py +++ b/backend/webserver/views/authentication_view.py @@ -1,30 +1,33 @@ import logging from django.contrib import auth -from django.core.exceptions import ValidationError -from django.core.validators import validate_email +from django.utils.decorators import method_decorator +from django.views.decorators.csrf import ensure_csrf_cookie from rest_framework.exceptions import APIException from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from rest_framework.views import APIView -from utilities.exceptions import Unauthorized, MissingRequiredParameter, InvalidValueError, InternalServerError +from utilities.exceptions import Unauthorized, MissingRequiredParameter, InternalServerError from utilities.helperclass import log_internal_error logger = logging.getLogger(__name__) +@method_decorator(ensure_csrf_cookie, name="get") class Login(APIView): permission_classes = [] throttle_scope = "login" + def get(self, request): + return Response(data="CSRF cookie set") + def post(self, request): try: username = request.data["username"] password = request.data["password"] keepMeLoggedIn = request.data["keepMeLoggedIn"] - validate_email(username) user = auth.authenticate(request=request, username=username, password=password) @@ -37,8 +40,6 @@ def post(self, request): logger.info(f"{username} {request.META.get('HTTP_X_FORWARDED_FOR')} failed to authenticate.") return Unauthorized().create_response_object() - except ValidationError: - return InvalidValueError("E-Mail is invalid").create_response_object() except KeyError as ke: return MissingRequiredParameter(ke.args[0]).create_response_object() except APIException as api_ex: diff --git a/backend/webserver/views/misc_views.py b/backend/webserver/views/misc_views.py index bb71ea4..3209e14 100644 --- a/backend/webserver/views/misc_views.py +++ b/backend/webserver/views/misc_views.py @@ -21,11 +21,26 @@ logger = logging.getLogger(__name__) +# HtmlView and AppView are legacy 2-tier SPA-serving views. +# They are kept for native dev mode (IS_DEV=True) where Django serves the SPA as a fallback. +# In 3-tier Docker mode, Nginx serves the frontend and these views are not used. + class HtmlView(View): + ALLOWED_TEMPLATES = frozenset([ + "index", "app", "dashboard", "projects", "reports", + "project", "report", "settings", "favorites", "dependencies", + ]) def get(self, request, template_name): + if template_name not in self.ALLOWED_TEMPLATES: + logger.warning( + f"Blocked template access attempt: {template_name} " + f"from {request.META.get('HTTP_X_FORWARDED_FOR')}" + ) + return render(request, "login.html", {"IS_DEV": IS_DEV, "BASE_URL": BASE_URL or "", "PREFIX": "/"}) + PREFIX = "/" if not IS_DEV and BASE_URL: @@ -66,7 +81,6 @@ def get(self, request): else: return render(request, "login.html", context) - class DependenciesAPI(APIView): permission_classes = [IsAuthenticated] diff --git a/backend/webserver/views/project_views.py b/backend/webserver/views/project_views.py index 351199b..7a9b86f 100644 --- a/backend/webserver/views/project_views.py +++ b/backend/webserver/views/project_views.py @@ -20,6 +20,8 @@ class DeleteProjectAPI(APIView): + permission_classes = [IsAuthenticated, permission_required("analyzer.delete_project")] + def post(self, request) -> Response: try: projectIds = request.data["projectIds"] @@ -158,6 +160,9 @@ def post(self, request, project_id): else: raise InvalidValueError(project_id) + if len(request.data.get("projectName", "")) > 50: + raise InvalidValueError("Project name exceeds the maximum length of 50 characters") + return Response(f"Creation of {project_id} successful!") except AlreadyExists as ae: diff --git a/docker-compose-preview.yml b/docker-compose-preview.yml new file mode 100644 index 0000000..64fc327 --- /dev/null +++ b/docker-compose-preview.yml @@ -0,0 +1,60 @@ +services: + + securecheckplus_frontend: + container_name: securecheckplus_frontend + build: + context: ./frontend + args: + REACT_APP_API_URL: "" + ports: + - "3000:80" + depends_on: + - securecheckplus_server + + securecheckplus_server: + container_name: securecheckplus_server + user: "${RUNNER_UID:-1000}:${GID:-1000}" + build: + context: ./backend + target: dev + environment: + - IS_DEV=True + - FULLY_QUALIFIED_DOMAIN_NAME=http://localhost:3000 + - USER_USERNAME=secure-user@acme.de + - USER_PASSWORD=secure + - ADMIN_USERNAME=secure-admin@acme.de + - ADMIN_PASSWORD=secure + - POSTGRES_HOST=securecheckplus_db + - POSTGRES_USER=securecheckplus + - POSTGRES_DB=some-db-name + - POSTGRES_PORT=5432 + - POSTGRES_PASSWORD="some-secure-password" + - NVD_API_KEY="PLACEHOLDER_FOR_NVD_API_KEY" + - DJANGO_SECRET_KEY="SOME-RANDOM-KEY" + - SALT="SOME-RANDOM-SALT" + volumes: + - "./backend:/backend" + ports: + - "8005:8000" + depends_on: + - securecheckplus_db + - smtp_mailserver + + securecheckplus_db: + image: postgres + restart: always + container_name: securecheckplus_db + environment: + - POSTGRES_HOST=securecheckplus_db + - POSTGRES_USER=securecheckplus + - POSTGRES_DB=some-db-name + - POSTGRES_PORT=5432 + - POSTGRES_PASSWORD="some-secure-password" + ports: + - "5432:5432" + + smtp_mailserver: + image: maildev/maildev + container_name: mailserver + ports: + - "1080:80" diff --git a/docker-compose.ci.yml b/docker-compose.ci.yml index 7d83535..a1be6b6 100644 --- a/docker-compose.ci.yml +++ b/docker-compose.ci.yml @@ -4,7 +4,7 @@ services: user: "${RUNNER_UID}:${GID}" build: context: ./backend - target: dev + target: prod env_file: "./backend/.env" environment: WORK_DIR: $WORK_DIR diff --git a/frontend/.dockerignore b/frontend/.dockerignore new file mode 100644 index 0000000..62b26e1 --- /dev/null +++ b/frontend/.dockerignore @@ -0,0 +1,4 @@ +node_modules +dist +.git +*.md diff --git a/frontend/Dockerfile b/frontend/Dockerfile new file mode 100644 index 0000000..1ed9f5f --- /dev/null +++ b/frontend/Dockerfile @@ -0,0 +1,20 @@ +# Stage 1: Build +FROM node:18-alpine AS build +WORKDIR /app + +ARG REACT_APP_API_URL='' +ENV REACT_APP_API_URL=${REACT_APP_API_URL} + +COPY package.json package-lock.json ./ +RUN npm ci +COPY . . +RUN npm run build + +# Stage 2: Serve +FROM nginx:alpine +COPY --from=build /app/dist /usr/share/nginx/html + +COPY nginx.conf /etc/nginx/conf.d/default.conf + +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"] diff --git a/frontend/nginx.conf b/frontend/nginx.conf new file mode 100644 index 0000000..09bd10b --- /dev/null +++ b/frontend/nginx.conf @@ -0,0 +1,53 @@ +server { + listen 80; + server_name localhost; + root /usr/share/nginx/html; + index index.html; + + location = /login { + try_files /login.html =404; + } + location = /login.html { + add_header Cache-Control "no-cache, no-store, must-revalidate"; + } + + location / { + try_files $uri $uri/ /index.html; + } + + location /api/ { + proxy_pass http://securecheckplus_server:8000; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_buffering off; + } + + location /static/ { + proxy_pass http://securecheckplus_server:8000; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_buffering off; + } + + # Proxy backend static assets in preview mode. + location /static/ { + proxy_pass http://securecheckplus_server:8000; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_buffering off; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} diff --git a/frontend/package-lock.json b/frontend/package-lock.json index afdd8dc..d6b2d02 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -9,6 +9,8 @@ "version": "1.0.0", "license": "ISC", "dependencies": { + "@dicebear/bottts-neutral": "^9.4.2", + "@dicebear/core": "^9.4.2", "@emotion/react": "^11.8.1", "@emotion/styled": "^11.8.1", "@mui/icons-material": "^5.4.4", @@ -1751,6 +1753,30 @@ "node": ">=6.9.0" } }, + "node_modules/@dicebear/bottts-neutral": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/bottts-neutral/-/bottts-neutral-9.4.2.tgz", + "integrity": "sha512-kFNwWt6j+gzZ5n5Pz7WVwePubREAQOF8ZwWA9ztwVYDVMLnOChWbAofy5FED4j5md2MXFH2EgLCFCMr5K2BmIA==", + "license": "See LICENSE file", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^9.0.0" + } + }, + "node_modules/@dicebear/core": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/core/-/core-9.4.2.tgz", + "integrity": "sha512-MF0042+Z3s8PGZKZLySfhft28bUa3B1iq0e5NSjCvY8gfMi5aIH/iRJGRJa1N9Jz1BNkxYb4yvJ/N9KO8Z6Y+w==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz", @@ -2536,10 +2562,10 @@ } }, "node_modules/@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", - "dev": true + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "license": "MIT" }, "node_modules/@types/mime": { "version": "1.3.2", @@ -9605,6 +9631,20 @@ "to-fast-properties": "^2.0.0" } }, + "@dicebear/bottts-neutral": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/bottts-neutral/-/bottts-neutral-9.4.2.tgz", + "integrity": "sha512-kFNwWt6j+gzZ5n5Pz7WVwePubREAQOF8ZwWA9ztwVYDVMLnOChWbAofy5FED4j5md2MXFH2EgLCFCMr5K2BmIA==", + "requires": {} + }, + "@dicebear/core": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/core/-/core-9.4.2.tgz", + "integrity": "sha512-MF0042+Z3s8PGZKZLySfhft28bUa3B1iq0e5NSjCvY8gfMi5aIH/iRJGRJa1N9Jz1BNkxYb4yvJ/N9KO8Z6Y+w==", + "requires": { + "@types/json-schema": "^7.0.15" + } + }, "@discoveryjs/json-ext": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz", @@ -10127,10 +10167,9 @@ } }, "@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", - "dev": true + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" }, "@types/mime": { "version": "1.3.2", diff --git a/frontend/package.json b/frontend/package.json index c083bb8..e1441cf 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -5,7 +5,8 @@ "main": "index.js", "scripts": { "prod": "webpack --config webpack.prod.js --mode production", - "dev": "webpack-dev-server --config webpack.dev.js --mode development" + "dev": "webpack-dev-server --config webpack.dev.js --mode development", + "build": "webpack --config webpack.prod.js --mode production" }, "repository": { "type": "git", @@ -36,6 +37,8 @@ "webpack-merge": "^5.8.0" }, "dependencies": { + "@dicebear/bottts-neutral": "^9.4.2", + "@dicebear/core": "^9.4.2", "@emotion/react": "^11.8.1", "@emotion/styled": "^11.8.1", "@mui/icons-material": "^5.4.4", diff --git a/frontend/src/api/apiClient.ts b/frontend/src/api/apiClient.ts new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/components/InfoBox.tsx b/frontend/src/components/InfoBox.tsx index 25ee81b..7ed5f1f 100644 --- a/frontend/src/components/InfoBox.tsx +++ b/frontend/src/components/InfoBox.tsx @@ -31,7 +31,7 @@ const boxProps = (headerComponent: React.ReactNode) => { display: "flex", flexDirection: "column", alignItems: "center", - justifyContent: "center", + justifyContent: "start", backgroundColor: mainTheme.palette.primary.main, borderRadius: "0.5rem", paddingTop: headerComponent === undefined ? "2rem" : 0, diff --git a/frontend/src/components/LoginBox.tsx b/frontend/src/components/LoginBox.tsx index 06900ab..dede627 100644 --- a/frontend/src/components/LoginBox.tsx +++ b/frontend/src/components/LoginBox.tsx @@ -11,6 +11,7 @@ import Typography from "@mui/material/Typography"; import {localStorageItemKeys, urlAddress} from "../utilities/constants"; import ImageDropDown from "./ImageDropDown"; import {getSupportedLanguages} from "../utilities/supportedLanguages"; +import apiClient from "../queries/apiClient"; /** * The login box at the login page. Takes the user inputs and requests an authentication process @@ -27,23 +28,38 @@ const LoginBox: React.FunctionComponent = () => { let allLanguages = getSupportedLanguages(); let defaultLanguageIndex = allLanguages.abbreviations.indexOf(defaultLanguage ? defaultLanguage : ""); + /** * If submit button is pressed redirect request to AuthProvider. * Submits on enter or on click. * @param clicked * @param e */ - const onConfirm = (clicked: boolean = false, e?: React.KeyboardEvent): void => { + const onConfirm = async (clicked: boolean = false, e?: React.KeyboardEvent): Promise => { // @ts-ignore handled by first statement - if ((e === undefined && clicked) || (e.key === "Enter")) { - if (username.includes("@")) { - login({ - username: username, - password: password, - keepMeLoggedIn: stayLoggedIn, - }).then(reloadPage).catch(() => { - notification.error(localization.notificationMessage.incorrectLogin) - }) + if ((e === undefined && clicked) || (e && e.key === "Enter")) { + if (username && username.trim().length > 0) { + // Fetch CSRF token before the login POST so the cookie is present. + try { + await apiClient.get(urlAddress.api.login); + } catch { + // Ignore errors — the CSRF cookie is set even on non-2xx responses. + } + + try { + await login({ + username: username, + password: password, + keepMeLoggedIn: stayLoggedIn, + }); + reloadPage(); + } catch (err: any) { + if (err?.response?.status === 401 || err?.response?.status === 403) { + notification.error(localization.notificationMessage.incorrectLogin); + } else { + notification.error(localization.notificationMessage.serverError || "Server error"); + } + } } else { notification.warn(localization.notificationMessage.usernameIsNotMail) } @@ -51,22 +67,28 @@ const LoginBox: React.FunctionComponent = () => { } const reloadPage = () => { - window.location.reload(); + // Navigate to the main app (loads app.js bundle via nginx → index.html) + window.location.href = '/'; } - return onConfirm(false, e)} - > - - - + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + await onConfirm(true); + } + + return ( +
+ + + + {localization.loginPage.login} @@ -79,7 +101,7 @@ const LoginBox: React.FunctionComponent = () => { variant="filled" required value={username} - onChange={e => setUsername(e.target.value)}/> + onChange={(e: React.ChangeEvent) => setUsername(e.target.value)}/> {/* */} @@ -90,10 +112,11 @@ const LoginBox: React.FunctionComponent = () => { variant="filled" type = {visible ? "text" : "password"} required value={password} - onChange={e => setPassword(e.target.value)}/> - setVisible(!visible)}> - {visible ? - : } + onChange={(e: React.ChangeEvent) => setPassword(e.target.value)} + InputProps={{ style: { paddingRight: `${eyeIconSize + 24}px` } }} /> + setVisible(!visible)}> + {visible ? show + : hide} @@ -103,12 +126,14 @@ const LoginBox: React.FunctionComponent = () => { {language.loginPage.checkBoxLabel} + variant="contained" + type="submit" + startIcon={} + >{language.loginPage.buttonLabel} + +
+ ) } diff --git a/frontend/src/components/NavBar/Profile.tsx b/frontend/src/components/NavBar/Profile.tsx index 4554b77..23fdcd2 100644 --- a/frontend/src/components/NavBar/Profile.tsx +++ b/frontend/src/components/NavBar/Profile.tsx @@ -2,7 +2,7 @@ import {Avatar, IconButton, ListItemIcon, Menu, MenuItem, Stack, Tooltip, Typogr import React, {useEffect, useState} from "react"; import {Logout, Settings} from "@mui/icons-material"; import localization from "../../utilities/localization"; -import {urlAddress} from "../../utilities/constants"; +import {getAvatarDataUri} from "../../utilities/avatar"; import {useQuery} from "react-query"; import {getUserData, logout} from "../../queries/user-requests"; import CustomDialog from "../CustomDialog"; @@ -50,7 +50,7 @@ export default function Profile() { size="small" sx={{mr: "2rem"}} > - +
@@ -58,7 +58,6 @@ export default function Profile() { anchorEl={anchorEl} open={open} onClose={handleClose} - onClick={handleClose} transformOrigin={{horizontal: 'right', vertical: 'top'}} anchorOrigin={{horizontal: 'right', vertical: 'bottom'}} PaperProps={menuStyle} diff --git a/frontend/src/components/NavBar/ProjectCreationContent.tsx b/frontend/src/components/NavBar/ProjectCreationContent.tsx index 5e0867c..7b63ff3 100644 --- a/frontend/src/components/NavBar/ProjectCreationContent.tsx +++ b/frontend/src/components/NavBar/ProjectCreationContent.tsx @@ -56,11 +56,11 @@ const CreationContent: React.FunctionComponent = (dialogCont setInvalid(true); setHelperText(localization.dialog.projectIdHelperNotEmpty) }else if (projectId.includes(" ")){ - setInvalid(true); - setHelperText(localization.dialog.projectIdHelperNoSpaces) - }else if (projectId.length > 20){ - setInvalid(true); - setHelperText(localization.dialog.projectIdHelperToLong) + setIdInvalid(true); + setProjectIdHelperText(localization.dialog.projectIdHelperNoSpaces) + }else if (projectId.length > 50){ + setIdInvalid(true); + setProjectIdHelperText(localization.dialog.projectIdHelperToLong) }else { if (data?.data !== undefined) { if (allProjectIds.includes(projectId.toLowerCase())) { @@ -72,7 +72,17 @@ const CreationContent: React.FunctionComponent = (dialogCont } } } - }, [projectId]) + }, [projectId, isProjectIdTouched, allProjectIds]) + + useEffect(() => { + if (projectName.length > 50) { + setNameInvalid(true); + setProjectNameHelperText(localization.dialog.projectNameHelperToLong); + } else { + setNameInvalid(false); + setProjectNameHelperText("Optional"); + } + }, [projectName]); return( diff --git a/frontend/src/components/UserSettingsContent.tsx b/frontend/src/components/UserSettingsContent.tsx index 802e108..b28821a 100644 --- a/frontend/src/components/UserSettingsContent.tsx +++ b/frontend/src/components/UserSettingsContent.tsx @@ -2,7 +2,7 @@ import React, {ChangeEvent, Dispatch, SetStateAction, useEffect, useState} from import {Avatar, Button, Stack, TextField, Typography} from "@mui/material"; import localization from "../utilities/localization" import DropdownMenu from "./DropdownMenu"; -import {urlAddress} from "../utilities/constants" +import {getAvatarDataUri} from "../utilities/avatar" import {useMutation, useQuery, useQueryClient} from "react-query"; import {getUserData, updateUserData} from "../queries/user-requests"; import {colors} from "../style/globalStyle"; @@ -54,7 +54,7 @@ const UserSettingsContent: React.FunctionComponent = (dialogProps: return ( - + = ({ children } const [loading, setLoading] = React.useState(true); useEffect(() => { - apiClient.defaults.baseURL = location.protocol + '//' + location.host + "/" + (baseUrl ? `${baseUrl}/api/` : "api/"); + apiClient.defaults.baseURL = location.protocol + '//' + location.host + "/" + (baseUrl ? `${baseUrl}/` : ""); setLoading(false); }, [baseUrl]); diff --git a/frontend/src/context/UserContext.tsx b/frontend/src/context/UserContext.tsx index e9b301f..2da5746 100644 --- a/frontend/src/context/UserContext.tsx +++ b/frontend/src/context/UserContext.tsx @@ -14,16 +14,22 @@ function UserContextProvider({children}: { children: React.ReactNode }) { const [userGroups, setUserGroups] = React.useState([groups.basic.id]); const [username, setUsername] = React.useState(""); - const {data: userData, isError, isSuccess} = useQuery("userData", getUserData) + const {data: userData, error, isError, isSuccess} = useQuery("userData", getUserData) useEffect(() => { if (isSuccess) { setUsername(userData?.data.username); setUserGroups(userData?.data.groups); } else if (isError) { - notification.error(localization.notificationMessage.errorUserDataFetch); + // 401 = not authenticated → redirect to login page + const status = (error as any)?.response?.status; + if (status === 401 || status === 403) { + window.location.href = '/login'; + } else { + notification.error(localization.notificationMessage.errorUserDataFetch); + } } - }, [userData]) + }, [userData, isError]) /** * Checks if the user has at least one of the given group diff --git a/frontend/src/index.html b/frontend/src/index.html new file mode 100644 index 0000000..b8dc7d1 --- /dev/null +++ b/frontend/src/index.html @@ -0,0 +1,10 @@ + + + + + SecureCheckPlus + + +
+ + diff --git a/frontend/src/login.html b/frontend/src/login.html new file mode 100644 index 0000000..0cd2a12 --- /dev/null +++ b/frontend/src/login.html @@ -0,0 +1,10 @@ + + + + + SecureCheckPlus – Login + + +
+ + diff --git a/frontend/src/page/ReportOverview.tsx b/frontend/src/page/ReportOverview.tsx index 3f45dd9..025ddfb 100644 --- a/frontend/src/page/ReportOverview.tsx +++ b/frontend/src/page/ReportOverview.tsx @@ -122,19 +122,6 @@ const ReportOverview: React.FunctionComponent = () => { * The definition of the data grid columns. */ const columns: GridColDef[] = [ - { - field: "open", - headerName: localization.ReportPage.open, - disableColumnMenu: true, - sortable: false, - align: "center", - headerAlign: "center", - renderCell: (params) => ( - window.open("reports/" + params.row.id, "_blank")}> - - - ) - }, { field: 'cveId', headerName: 'CVE ID', @@ -219,7 +206,11 @@ const ReportOverview: React.FunctionComponent = () => { description: localization.ReportPage.toolTips.epss, renderCell: (params: GridRenderCellParams) => ( - {params.value === 0 ? "N/A" : (params.value * 100).toFixed(2) + "%"} + + {typeof params.value === "number" && params.value !== undefined && params.value !== 0 + ? (params.value * 100).toFixed(2) + "%" + : "N/A"} + ), valueGetter: params => params.row.cveObject.epss, @@ -310,6 +301,10 @@ const ReportOverview: React.FunctionComponent = () => { rows={selectedReports} columns={columns} getRowId={(row) => row.cveObject.cveId + row.dependency.dependencyName + row.dependency.version} + onRowClick={(params) => { + if (window.getSelection()?.toString()) return + window.open("reports/" + params.row.id, "_blank") + }} /> : null} diff --git a/frontend/src/page/ReportPage.tsx b/frontend/src/page/ReportPage.tsx index fda9042..efe684f 100644 --- a/frontend/src/page/ReportPage.tsx +++ b/frontend/src/page/ReportPage.tsx @@ -482,7 +482,7 @@ const ReportPage: React.FunctionComponent = () => { }/> - + { "flexWrap": "wrap", "justifyContent": "space-evenly" }}> - + { }}/> - {localization.ReportDetailPage.cvssVectorString} { }/> + + + {localization.ReportDetailPage.infosFound.detailedDescriptionTitle} + {data?.data.report.cveObject.description} + + }/> + 50) { + return Promise.reject(new Error("Project name exceeds the maximum length of 50 characters")); + } return apiClient.post(urlAddress.api.createProject(projectId), projectData) } diff --git a/frontend/src/utilities/avatar.ts b/frontend/src/utilities/avatar.ts new file mode 100644 index 0000000..362bc0c --- /dev/null +++ b/frontend/src/utilities/avatar.ts @@ -0,0 +1,6 @@ +import { createAvatar } from '@dicebear/core' +import * as botttsNeutral from '@dicebear/bottts-neutral' + +export function getAvatarDataUri(seed: string, size: number = 128): string { + return createAvatar(botttsNeutral, { seed, size }).toDataUri() +} diff --git a/frontend/src/utilities/constants.tsx b/frontend/src/utilities/constants.tsx index 9aedcb9..3cdc82f 100644 --- a/frontend/src/utilities/constants.tsx +++ b/frontend/src/utilities/constants.tsx @@ -11,25 +11,25 @@ export const localStorageItemKeys = { export const urlAddress = { api: { - login: "login", - logout: "logout", - me: "me", - myFavorite: "myFavorites", - projectsFlat: "projectsFlat", - projects: "projects", - deleteProjects: "deleteProjects", - projectGroups: "projectGroups", - createProject: (projectId: string) => "projects/" + projectId, - project: (projectId: string) => "projects/" + projectId, - projectAPIKey: (projectId: string) => "projects/" + projectId + "/apiKey", - projectDependencies: (projectId: string) => "projects/" + projectId + "/dependencies", - projectReports: (projectId: string) => "projects/" + projectId + "/reports", - projectUpdateCVEs: (projectId: string) => "projects/" + projectId + "/updateCVE", + login: "api/login", + logout: "api/logout", + me: "api/me", + myFavorite: "api/myFavorites", + projectsFlat: "api/projectsFlat", + projects: "api/projects", + deleteProjects: "api/deleteProjects", + projectGroups: "api/projectGroups", + createProject: (projectId: string) => "api/projects/" + projectId, + project: (projectId: string) => "api/projects/" + projectId, + projectAPIKey: (projectId: string) => "api/projects/" + projectId + "/apiKey", + projectDependencies: (projectId: string) => "api/projects/" + projectId + "/dependencies", + projectReports: (projectId: string) => "api/projects/" + projectId + "/reports", + projectUpdateCVEs: (projectId: string) => "api/projects/" + projectId + "/updateCVE", report: (projectId: string, - reportId: string) => "projects/" + projectId + "/reports/" + reportId, - updateCVE: (cveId: string) => "cveObject/" + cveId + "/update", - updateAllCVEs: "cveObjects/update", - unknownPage: "error404" + reportId: string) => "api/projects/" + projectId + "/reports/" + reportId, + updateCVE: (cveId: string) => "api/cveObject/" + cveId + "/update", + updateAllCVEs: "api/cveObjects/update", + unknownPage: "api/error404" }, media: { rootUrlWithBase: "", // gets set by ConfigContext Provider @@ -38,7 +38,6 @@ export const urlAddress = { logoHorizontal: "static/images/SecureCheckPlusLogoHorizontal.png", gitHubIcon: "static/icons/GitHubIcon.svg", error404: "static/images/error404.gif", - avatar: "https://api.dicebear.com/8.x/adventurer-neutral/svg?seed=", flag_de: "static/icons/flag_de.svg", flag_gb: "static/icons/flag_gb.svg", eye: "static/icons/eye.svg", diff --git a/frontend/src/utilities/localization.tsx b/frontend/src/utilities/localization.tsx index cec5165..82363a0 100644 --- a/frontend/src/utilities/localization.tsx +++ b/frontend/src/utilities/localization.tsx @@ -115,7 +115,7 @@ const language = { commentPlaceholder: "Kommentieren...", infosFound:{ infosFoundTitle: "Folgende Informationen gefunden...", - detailedDescription: "Detaillierte Beschreibung:", + detailedDescriptionTitle: "Detaillierte Beschreibung", suggestedSolutions: "Vorgeschlagene Lösungen", mendIo: "Mend.io:", aquaSec: "AquaSec:", @@ -184,28 +184,90 @@ const language = { availabilityRequirement: "Availability Requirement", }, scoreMetricValues: { - notDefined: "Not Defined", - unproven: "Unproven", - proofOfConcept: "Proof-of-Concept", - functional: "Functional", - high: "High", - officialFix: "Official fix", - temporaryFix: "Temporary fix", - workaround: "Workaround", - unavailable: "Unavailable", - unknown: "Unknown", - reasonable: "Reasonable", - confirmed: "Confirmed", - network: "Network", - adjacent: "Adjacent", - local: "Local", - physical: "Physical", - low: "Low", - medium: "Medium", - none: "None", - required: "Required", - unchanged: "Unchanged", - changed: "Changed", + exploitCodeMaturity: { + notDefined: {title: NOT_DEFINED, tooltip: "Assigning this value indicates there is insufficient information to choose one of the other values, and has no impact on the overall Temporal Score, i.e., it has the same effect on scoring as assigning High."}, + unproven: {title: "Unproven", tooltip: "No exploit code is available, or an exploit is theoretical."}, + proofOfConcept: {title: "Proof-of-Concept", tooltip: "Proof-of-concept exploit code is available, or an attack demonstration is not practical for most systems. The code or technique is not functional in all situations and may require substantial modification by a skilled attacker."}, + functional: {title: "Functional", tooltip: "Functional exploit code is available. The code works in most situations where the vulnerability exists."}, + high: {title: "High", tooltip: "Functional autonomous code exists, or no exploit is required (manual trigger) and details are widely available. Exploit code works in every situation, or is actively being delivered via an autonomous agent (such as a worm or virus). Network-connected systems are likely to encounter scanning or exploitation attempts. Exploit development has reached the level of reliable, widely available, easy-to-use automated tools."} + }, + remediationLevel: { + notDefined: {title: NOT_DEFINED, tooltip: "Assigning this value indicates there is insufficient information to choose one of the other values, and has no impact on the overall Temporal Score, i.e., it has the same effect on scoring as assigning Unavailable."}, + officialFix: {title: "Official fix", tooltip: "A complete vendor solution is available. Either the vendor has issued an official patch, or an upgrade is available."}, + temporaryFix: {title: "Temporary fix", tooltip: "There is an official but temporary fix available. This includes instances where the vendor issues a temporary hotfix, tool, or workaround."}, + workaround: {title: "Workaround", tooltip: "There is an unofficial, non-vendor solution available. In some cases, users of the affected technology will create a patch of their own or provide steps to work around or otherwise mitigate the vulnerability."}, + unavailable: {title: "Unavailable", tooltip: "There is either no solution available or it is impossible to apply."}, + }, + reportConfidence: { + notDefined: {title: NOT_DEFINED, tooltip: "Assigning this value indicates there is insufficient information to choose one of the other values, and has no impact on the overall Temporal Score, i.e., it has the same effect on scoring as assigning Confirmed."}, + unknown: {title: "Unknown", tooltip: "There are reports of impacts that indicate a vulnerability is present. The reports indicate that the cause of the vulnerability is unknown, or reports may differ on the cause or impacts of the vulnerability. Reporters are uncertain of the true nature of the vulnerability, and there is little confidence in the validity of the reports or whether a static Base Score can be applied given the differences described. An example is a bug report which notes that an intermittent but non-reproducible crash occurs, with evidence of memory corruption suggesting that denial of service, or possible more serious impacts, may result."}, + reasonable: {title: "Reasonable", tooltip: "Significant details are published, but researchers either do not have full confidence in the root cause, or do not have access to source code to fully confirm all of the interactions that may lead to the result. Reasonable confidence exists, however, that the bug is reproducible and at least one impact is able to be verified (proof-of-concept exploits may provide this). An example is a detailed write-up of research into a vulnerability with an explanation (possibly obfuscated or “left as an exercise to the reader”) that gives assurances on how to reproduce the results."}, + confirmed: {title: "Confirmed", tooltip: "Detailed reports exist, or functional reproduction is possible (functional exploits may provide this). Source code is available to independently verify the assertions of the research, or the author or vendor of the affected code has confirmed the presence of the vulnerability."} + }, + confidentialityRequirement: { + notDefined: {title: NOT_DEFINED, tooltip: NOT_DEFINED_REQ}, + low: {title: LOW, tooltip: "Loss of Confidentiality is likely to have only a limited adverse effect on the organization or individuals associated with the organization (e.g., employees, customers)."}, + medium: {title: MEDIUM, tooltip: "Loss of [Confidentiality | Integrity | Availability] is likely to have a serious adverse effect on the organization or individuals associated with the organization (e.g., employees, customers)."}, + high: {title: HIGH, tooltip: "Loss of [Confidentiality | Integrity | Availability] is likely to have a catastrophic adverse effect on the organization or individuals associated with the organization (e.g., employees, customers)."} + }, + integrityRequirement: { + notDefined: {title: NOT_DEFINED, tooltip: NOT_DEFINED_REQ}, + low: {title: LOW, tooltip: "Loss of Confidentiality is likely to have only a limited adverse effect on the organization or individuals associated with the organization (e.g., employees, customers)."}, + medium: {title: MEDIUM, tooltip: "Loss of [Confidentiality | Integrity | Availability] is likely to have a serious adverse effect on the organization or individuals associated with the organization (e.g., employees, customers)."}, + high: {title: HIGH, tooltip: "Loss of [Confidentiality | Integrity | Availability] is likely to have a catastrophic adverse effect on the organization or individuals associated with the organization (e.g., employees, customers)."} + }, + availabilityRequirement: { + notDefined: {title: NOT_DEFINED, tooltip: NOT_DEFINED_REQ}, + low: {title: LOW, tooltip: "Loss of Confidentiality is likely to have only a limited adverse effect on the organization or individuals associated with the organization (e.g., employees, customers)."}, + medium: {title: MEDIUM, tooltip: "Loss of [Confidentiality | Integrity | Availability] is likely to have a serious adverse effect on the organization or individuals associated with the organization (e.g., employees, customers)."}, + high: {title: HIGH, tooltip: "Loss of [Confidentiality | Integrity | Availability] is likely to have a catastrophic adverse effect on the organization or individuals associated with the organization (e.g., employees, customers)."} + }, + modifiedAttackVector: { + notDefined: {title: NOT_DEFINED, tooltip: NOT_DEFINED_DEF}, + network: {title: "Network", tooltip: "The vulnerable component is bound to the network stack and the set of possible attackers extends beyond the other options listed below, up to and including the entire Internet. Such a vulnerability is often termed “remotely exploitable” and can be thought of as an attack being exploitable at the protocol level one or more network hops away (e.g., across one or more routers). An example of a network attack is an attacker causing a denial of service (DoS) by sending a specially crafted TCP packet across a wide area network (e.g., CVE‑2004‑0230)."}, + adjacent: {title: "Adjacent", tooltip: "The vulnerable component is bound to the network stack, but the attack is limited at the protocol level to a logically adjacent topology. This can mean an attack must be launched from the same shared physical (e.g., Bluetooth or IEEE 802.11) or logical (e.g., local IP subnet) network, or from within a secure or otherwise limited administrative domain (e.g., MPLS, secure VPN to an administrative network zone). One example of an Adjacent attack would be an ARP (IPv4) or neighbor discovery (IPv6) flood leading to a denial of service on the local LAN segment (e.g., CVE‑2013‑6014)."}, + local: {title: "Local", tooltip: "The vulnerable component is not bound to the network stack and the attacker’s path is via read/write/execute capabilities. Either: the attacker exploits the vulnerability by accessing the target system locally (e.g., keyboard, console), or remotely (e.g., SSH); or the attacker relies on User Interaction by another person to perform actions required to exploit the vulnerability (e.g., using social engineering techniques to trick a legitimate user into opening a malicious document)."}, + physical: {title: "Physical", tooltip: "The attack requires the attacker to physically touch or manipulate the vulnerable component. Physical interaction may be brief (e.g., evil maid attack1) or persistent. An example of such an attack is a cold boot attack in which an attacker gains access to disk encryption keys after physically accessing the target system. Other examples include peripheral attacks via FireWire/USB Direct Memory Access (DMA)."} + }, + modifiedAttackComplexity: { + notDefined: {title: NOT_DEFINED, tooltip: NOT_DEFINED_DEF}, + low: {title: LOW, tooltip: "Specialized access conditions or extenuating circumstances do not exist. An attacker can expect repeatable success when attacking the vulnerable component."}, + high: {title: HIGH, tooltip: "A successful attack depends on conditions beyond the attacker's control. That is, a successful attack cannot be accomplished at will, but requires the attacker to invest in some measurable amount of effort in preparation or execution against the vulnerable component before a successful attack can be expected.2 For example, a successful attack may depend on an attacker overcoming any of the following conditions: The attacker must gather knowledge about the environment in which the vulnerable target/component exists. For example, a requirement to collect details on target configuration settings, sequence numbers, or shared secrets. or The attacker must prepare the target environment to improve exploit reliability. For example, repeated exploitation to win a race condition, or overcoming advanced exploit mitigation techniques. or The attacker must inject themselves into the logical network path between the target and the resource requested by the victim in order to read and/or modify network communications (e.g., a man in the middle attack)."} + }, + modifiedPrivilegesRequired: { + notDefined: {title: NOT_DEFINED, tooltip: NOT_DEFINED_DEF}, + none: {title: NONE, tooltip: "The attacker is unauthorized prior to attack, and therefore does not require any access to settings or files of the vulnerable system to carry out an attack."}, + low: {title: LOW, tooltip: "The attacker requires privileges that provide basic user capabilities that could normally affect only settings and files owned by a user. Alternatively, an attacker with Low privileges has the ability to access only non-sensitive resources."}, + high: {title: HIGH, tooltip: "The attacker requires privileges that provide significant (e.g., administrative) control over the vulnerable component allowing access to component-wide settings and files."} + }, + modifiedUserInteraction: { + notDefined: {title: NOT_DEFINED, tooltip: NOT_DEFINED_DEF}, + none: {title: NONE, tooltip: "The vulnerable system can be exploited without interaction from any user."}, + required: {title: "Required", tooltip: "Successful exploitation of this vulnerability requires a user to take some action before the vulnerability can be exploited. For example, a successful exploit may only be possible during the installation of an application by a system administrator."} + }, + modifiedScope: { + notDefined: {title: NOT_DEFINED, tooltip: NOT_DEFINED_DEF}, + unchanged: {title: "Unchanged", tooltip: "An exploited vulnerability can only affect resources managed by the same security authority. In this case, the vulnerable component and the impacted component are either the same, or both are managed by the same security authority."}, + changed: {title: "Changed", tooltip: "An exploited vulnerability can affect resources beyond the security scope managed by the security authority of the vulnerable component. In this case, the vulnerable component and the impacted component are different and managed by different security authorities."} + }, + modifiedConfidentiality: { + notDefined: {title: NOT_DEFINED, tooltip: NOT_DEFINED_DEF}, + none: {title: NONE, tooltip: "There is no loss of confidentiality within the impacted component."}, + low: {title: LOW, tooltip: "There is some loss of confidentiality. Access to some restricted information is obtained, but the attacker does not have control over what information is obtained, or the amount or kind of loss is limited. The information disclosure does not cause a direct, serious loss to the impacted component."}, + high: {title: HIGH, tooltip: "There is a total loss of confidentiality, resulting in all resources within the impacted component being divulged to the attacker. Alternatively, access to only some restricted information is obtained, but the disclosed information presents a direct, serious impact. For example, an attacker steals the administrator's password, or private encryption keys of a web server."} + }, + modifiedIntegrity: { + notDefined: {title: NOT_DEFINED, tooltip: NOT_DEFINED_DEF}, + none: {title: NONE, tooltip: "There is no loss of integrity within the impacted component."}, + low: {title: LOW, tooltip: "Modification of data is possible, but the attacker does not have control over the consequence of a modification, or the amount of modification is limited. The data modification does not have a direct, serious impact on the impacted component."}, + high: {title: HIGH, tooltip: "There is a total loss of integrity, or a complete loss of protection. For example, the attacker is able to modify any/all files protected by the impacted component. Alternatively, only some files can be modified, but malicious modification would present a direct, serious consequence to the impacted component."} + }, + modifiedAvailability: { + notDefined: {title: NOT_DEFINED, tooltip: NOT_DEFINED_DEF}, + none: {title: NONE, tooltip: "There is no impact to availability within the impacted component."}, + low: {title: LOW, tooltip: "Performance is reduced or there are interruptions in resource availability. Even if repeated exploitation of the vulnerability is possible, the attacker does not have the ability to completely deny service to legitimate users. The resources in the impacted component are either partially available all of the time, or fully available only some of the time, but overall there is no direct, serious consequence to the impacted component."}, + high: {title: HIGH, tooltip: "There is a total loss of availability, resulting in the attacker being able to fully deny access to resources in the impacted component; this loss is either sustained (while the attacker continues to deliver the attack) or persistent (the condition persists even after the attack has completed). Alternatively, the attacker has the ability to deny some availability, but the loss of availability presents a direct, serious consequence to the impacted component (e.g., the attacker cannot disrupt existing connections, but can prevent new connections; the attacker can repeatedly exploit a vulnerability that, in each instance of a successful attack, leaks a only small amount of memory, but after repeated exploitation causes a service to become completely unavailable)."} + } }, }, sidebar:{ @@ -283,7 +345,7 @@ const language = { projectId: "Projekt ID", projectIdHelperNotEmpty: "Projekt ID darf nicht leer sein.", projectIdHelperNoSpaces: "Projekt ID darf keine Leerzeichen beinhalten.", - projectIdHelperToLong: "Projekt ID ist länger als 20 Zeichen lang.", + projectIdHelperToLong: "Projekt ID ist länger als 50 Zeichen lang.", projectIdHelperIdAlreadyUsed: "Projekt ID bereits vergeben.", projectName: "Projektname", projectNameHelperToLong: "Projektname zu lang.", @@ -428,7 +490,7 @@ const language = { commentPlaceholder: "Comment...", infosFound:{ infosFoundTitle: "Found information...", - detailedDescription: "Detailed description:", + detailedDescriptionTitle: "Detailed description", suggestedSolutions: "Suggested solutions", mendIo: "Mend.io:", aquaSec: "AquaSec:", @@ -596,7 +658,7 @@ const language = { projectId: "Project ID", projectIdHelperNotEmpty: "Project ID mustn't be empty.", projectIdHelperNoSpaces: "Project ID mustn't contain spaces.", - projectIdHelperToLong: "Project ID is longer than 20 characters.", + projectIdHelperToLong: "Project ID is longer than 50 characters.", projectIdHelperIdAlreadyUsed: "Project ID already in use.", projectName: "Project name", projectNameHelperToLong: "Project name to long.", diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index 6cdd469..c51099d 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -19,7 +19,7 @@ "isolatedModules": true, "noEmit": false, "jsx": "react-jsx", - "outDir": "../backend/assets" + "outDir": "./dist" }, "include": [ "src", diff --git a/frontend/webpack.common.js b/frontend/webpack.common.js index 26ea6d6..9aa4182 100644 --- a/frontend/webpack.common.js +++ b/frontend/webpack.common.js @@ -1,4 +1,6 @@ const path = require("path"); +const HtmlWebpackPlugin = require('html-webpack-plugin'); +const webpack = require('webpack'); module.exports = { entry: { app: "./src/App.tsx", @@ -43,8 +45,24 @@ module.exports = { }, output: { filename: "[name].js", - path: path.join(__dirname, "../backend/assets"), + path: path.join(__dirname, "./dist"), publicPath: '/' }, - + plugins: [ + // Main app bundle – served by nginx for all authenticated routes + new HtmlWebpackPlugin({ + template: './src/index.html', + filename: 'index.html', + chunks: ['app'], + }), + // Login bundle – served by nginx at /login + new HtmlWebpackPlugin({ + template: './src/login.html', + filename: 'login.html', + chunks: ['login'], + }), + new webpack.DefinePlugin({ + 'process.env.REACT_APP_API_URL': JSON.stringify(process.env.REACT_APP_API_URL || ''), + }) + ], }