Security verdict · High Risk
D 29/100
*****/*****
Real gaps here. Fix these before you ship.
Code D · Dependencies B
Redacted · · 12 findings

A real scan of a real public repo, shown exactly as you would get it. The repo name, the paths and every key are starred out. Publishing a stranger's live credentials is not ours to do. Your own report names every file and every line.

Critical
8
High
3
Medium
1
Low
0

Fix prompt

Copy & paste into your AI coding tool

On this sample the panel shows the plain-text prompt. Your own report rewrites it for whichever tool you pick above.

universal_prompt.md
# Fix 10 security vulnerabilities

**7 CRITICAL** — exploitable now, fix these first · **3 HIGH** — fix before your next deploy

> 🔑 4 of these are **leaked credentials**. Those need manual steps from you (marked below) — an AI tool cannot rotate keys for you.

## 🔑 Rotate these leaked credentials first — steps only YOU can do

Every finding marked 🔑 below is a leaked credential. Changing the code is NOT enough: the value is already in your git history, so treat it as stolen. An AI tool cannot rotate credentials for you — do the steps for each type, then apply the code changes below.

**Third-party API keys** (`*****/*****.py`, `*****.py`):
1. Log in to the service that issued it (Stripe, AWS, OpenAI, …) and **revoke the key**.
2. Generate a new one and store it in an environment variable (for example a `.env` file listed in `.gitignore`). Never paste it into source code.

**Application secret keys** (`*****/*****.py`):
There is no provider dashboard for this — you create the value yourself.
1. Generate a new random value. For Django: `python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"`.
2. Store it in an environment variable (`.env` in `.gitignore`), never in code.
3. Expect every logged-in user to be signed out when you deploy — that is normal and means the rotation worked.

**Hardcoded passwords** (`*****/*****.py`):
No provider is involved — you choose the replacement yourself.
1. Pick a new strong password (a password manager can generate one).
2. Treat the old one as already stolen: if it was reused anywhere else, change it there too.
3. **Where the new password lives is decided by each fix below, not here.** Most fixes replace the hardcoded check with your framework's own login (for example Django's `authenticate()`), which reads the user table — so the new password belongs in a real user account (`User.objects.create_user(...)` hashes it for you), NOT in an environment variable. Only put a hash in an env var if the fix for that specific finding says to. Doing both is what breaks login.

Apply each fix below to the referenced file and line. The corrected code is included inline, so this works in any AI IDE or chat assistant without further context. The dependency upgrades at the end are shell commands, not code edits.

## 1. [CRITICAL] weak-password-hash-python
- **File:** `*****/*****.py` (line 59)
- **Problem:** An attacker who steals your database can brute-force fast hashes on a GPU in hours.
- **Fix:**

Use a slow password hasher. In Django, store with make_password() and verify with check_password(); or use bcrypt directly.

## 2. [CRITICAL] command-injection-python
- **File:** `*****/*****.py` (line 460)
- **Problem:** An attacker can type Python code into the form and eval() runs it on your server.
- **Fix:**

Remove eval(). For arithmetic, use a restricted AST evaluator or the numexpr library; ast.literal_eval only parses literals and will raise on any real expression.

## 3. [CRITICAL] path-traversal-user-path-python
- **File:** `*****/*****.py` (line 926)
- **Problem:** An attacker can pass ../../.env to read files anywhere on the server.
- **Fix:**

Strip directory components with os.path.basename(file) before joining, or use Django's safe_join() to confine access to one directory.

## 4. [CRITICAL] password-compared-to-literal-python
- **File:** `*****/*****.py` (lines 766, 806)
- **Problem:** Anyone with repository access reads the password in plain text and can log in.
> 🔑 **Leaked credential** — do the rotation steps at the top of this prompt first, then apply this code change:

Store only a hash (Django make_password()) and verify with check_password(password, stored_hash) instead of a literal string comparison.

## 5. [CRITICAL] hardcoded-api-key-python
- **File:** `*****/*****.py` (line 25)
- **Problem:** Hardcoded secret or API key in Python source code.
> 🔑 **Leaked credential** — do the rotation steps at the top of this prompt first:

_No automated fix was generated for this finding. Ask the assistant to explain the issue at this exact file and line, propose a minimal fix, and apply it only after you approve._

## 6. [CRITICAL] hardcoded-api-key-python
- **File:** `*****/*****.py` (line 8)
- **Problem:** Anyone who reads your repository can forge session tokens and impersonate any user.
> 🔑 **Leaked credential** — do the rotation steps at the top of this prompt first, then apply this code change:

Read it from an environment variable: SECRET_KEY = os.environ['DJANGO_SECRET_KEY']. Never keep the value in source.

## 7. [CRITICAL] aws-access-key-id
- **File:** `*****.py` (line 10)
- **Problem:** Artifact: *****.py Type: Secret AWS Access Key ID Severity: CRITICAL Match: database = aws_lib.connect("[redacted]", "[redacted]").
> 🔑 **Leaked credential** — do the rotation steps at the top of this prompt first, then apply this code change:

Rotate it. MONGO_URI = "mongodb+srv://[redacted]@[redacted]/test" leaks too. Contact [redacted]. sha [redacted]

## 8. [HIGH] problem-based-packs.insecure-transport.js.jwt-exposed-data
- **File:** `*****/*****/*****.js` (line 12)
- **Problem:** JWT [redacted] exposed.
- **Fix:**

Set [redacted] aside. Use process.env.API_KEY, not API_KEY = [redacted].

## Dependency upgrades — 2 packages to update

- **[HIGH]** CVE-2024-35195 — `*****.txt`: An attacker on the network can read or alter traffic you believe is encrypted.
- **[HIGH]** GHSA-9wx4-h78v-vm56 — `*****.txt`: A redirect to a host you do not control receives your proxy credentials.

Fix these through the project's package manager. Generated lockfiles must never be edited by hand; plain manifests like `*****.txt` CAN be edited directly.

1. Run the audit or upgrade command for YOUR package manager (npm: `npm audit fix` · pnpm: `pnpm audit --fix` · Python with a lockfile: `uv lock --upgrade-package <name>` or `poetry update <name>` · plain `*****.txt`: edit the version pin directly, then `pip install -r *****.txt` · Rust: `cargo update <name>` · Go: `go get <name>@latest`).
2. If a vulnerable package is transitive and still unfixed, pin the patched version through the manifest (npm `"overrides"`, yarn `"resolutions"`, or your package manager's equivalent), then re-run the install so the lockfile is regenerated.
3. Re-run the tests and confirm the app still builds.

If a fix needs a major-version upgrade, or no patched version exists (the vulnerable package belongs to an end-of-life toolchain, like Babel 6), do not force it — flag it as a decision for me, explained in plain language.

## Lower priority — 1 package update worth doing when you have a minute

These are real version-level advisories, but nothing here looks urgent for this app: they are medium severity. No need to stop a deploy for them; the upgrades below clear them out.

- **[MEDIUM]** CVE-2023-45803 — `*****.json`: Data you posted can be replayed to a third host.

Fix these through the project's package manager. Generated lockfiles must never be edited by hand; plain manifests like `*****.txt` CAN be edited directly.

1. Run the audit or upgrade command for YOUR package manager (npm: `npm audit fix` · pnpm: `pnpm audit --fix` · Python with a lockfile: `uv lock --upgrade-package <name>` or `poetry update <name>` · plain `*****.txt`: edit the version pin directly, then `pip install -r *****.txt` · Rust: `cargo update <name>` · Go: `go get <name>@latest`).
2. If a vulnerable package is transitive and still unfixed, pin the patched version through the manifest (npm `"overrides"`, yarn `"resolutions"`, or your package manager's equivalent), then re-run the install so the lockfile is regenerated.
3. Re-run the tests and confirm the app still builds.

If a fix needs a major-version upgrade, or no patched version exists (the vulnerable package belongs to an end-of-life toolchain, like Babel 6), do not force it — flag it as a decision for me, explained in plain language.

## Ground rules (do not skip)
- Change only the lines needed for each fix — do not refactor, rename, or restructure unrelated code.
- Preserve every function signature, import, error handler, log line, and existing test.
- Never weaken or remove an existing security measure (authentication, input validation, sanitisation, rate limiting) while applying a fix.
- If a finding points at a generated file (a schema dump, a lockfile, a build artifact, anything under dist/ or vendor/), do not edit that file — it is output and your edit will be overwritten. Fix the source that produces it (the migration, the manifest, the template) and say which file you changed.
- If a fix needs a new import or dependency, add only that — change nothing else. Do not add new third-party packages unless a fix explicitly requires one.
- Work through the fixes one at a time, most severe first: apply a fix, then check it (run the tests if you can) before moving to the next. Don't pause for my approval between routine fixes — but do stop and tell me if a fix fails its test, conflicts with another, or needs a decision only I can make. Put anything that needs my input in your final summary.
- Never claim you did something only I can do — you cannot reset a leaked key, change a provider or dashboard setting, or click through the running app. List those as steps for me; do not report them as done.
- If the code at a referenced line number does not match the finding, search that file for the code shown in the fix and apply the change there. If you cannot find it, say so in your final summary instead of guessing.
- If you cannot fully fix a finding — because it needs a change in an account or provider dashboard, a rotated key, or a decision only I can make — do not skip it silently. Tell me, and walk me through it in small numbered steps I can do myself. Assume I am not a developer: name exactly what to open and what to click, and say how I'll know it worked.

## Prevent these from coming back
Keep these rules in your project notes and include them in future prompts:
- Always validate and resolve user-supplied file paths against an allowed base directory.
- Never write API keys, passwords, or tokens in source files — read them from environment variables.

## After every fix is applied
- [ ] Run the full test suite — everything that passed before must still pass.
- [ ] Start the app and click through your main user flows to confirm nothing broke.
- [ ] Confirm the old keys listed above are revoked at the provider and the new ones live only in environment variables.
- [ ] Re-run the security scan to verify these findings are gone and no new ones appeared.

---
Findings by Sentrint · https://sentrint.com

Findings

12 total
AI fix suggestion
WHY: An attacker can type Python code into the form and eval() runs it on your server.
FIX: Remove eval(). For arithmetic, use a restricted AST evaluator or the numexpr library; ast.literal_eval only parses literals and will raise on any real expression.
AI fix suggestion
WHY: Anyone who reads your repository can forge session tokens and impersonate any user.
FIX: Read it from an environment variable: SECRET_KEY = os.environ['DJANGO_SECRET_KEY']. Never keep the value in source.
AI fix suggestion
WHY: An attacker who steals your database can brute-force fast hashes on a GPU in hours.
FIX: Use a slow password hasher. In Django, store with make_password() and verify with check_password(); or use bcrypt directly.
AI fix suggestion
WHY: An attacker can pass ../../.env to read files anywhere on the server.
FIX: Strip directory components with os.path.basename(file) before joining, or use Django's safe_join() to confine access to one directory.
AI fix suggestion
WHY: Anyone with repository access reads the password in plain text and can log in.
FIX: Store only a hash (Django make_password()) and verify with check_password(password, stored_hash) instead of a literal string comparison.
AI fix suggestion
WHY: Anyone with repository access reads the password in plain text and can log in.
FIX: Store only a hash (Django make_password()) and verify with check_password(password, stored_hash) instead of a literal string comparison.
Why this isn’t a false positive

Real key in [redacted] at *****/*****/*****/*****.yaml

AI fix suggestion
Rotate it. MONGO_URI = "mongodb+srv://[redacted]@[redacted]/test" leaks too. Contact [redacted]. sha [redacted]
AI fix suggestion
Set [redacted] aside. Use process.env.API_KEY, not API_KEY = [redacted].
AI fix suggestion
WHY: An attacker on the network can read or alter traffic you believe is encrypted.
FIX: Upgrade requests to 2.32.0 or later.
AI fix suggestion
WHY: A redirect to a host you do not control receives your proxy credentials.
FIX: Upgrade urllib3 to 1.26.19 or later.
AI fix suggestion
WHY: Data you posted can be replayed to a third host.
FIX: Regenerate the lockfile against a patched release.
Copied 12 findings your AI tool.