feat(pair-corpus-honesty): add vibe-py, vfc-js and agent-vfc slices with mechanism vocabulary

Tasks 1.1, 5.1, 5.2, 5.4 and the data half of 5.3.

- mechanisms.toml: closed vocabulary v1 (20 ids) every expected row cites.
- vibe-py: 35 Real-Vuln-Benchmark pairs (Apache-2.0), human provenance only
  because the LLM-generated repositories carry no license (escalated).
- vfc-js: 17 Node fix-commit pairs harvested upstream (MIT/Apache-2.0),
  SecBench.js itself is not vendored (no license); sinks derived on 13/17.
- agent-vfc: 29 agent-trailer fixes as catalog-candidates.toml plus
  REVIEW.md; the loaded catalog stays empty until a human reviews them.
- datasets.toml and README document every slice and its review status.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01T7XD7x5KonMdmGRkp63EQG
This commit is contained in:
Marius Ciepluch
2026-09-05 10:45:42 +02:00
co-authored by Claude Fable 5.1
parent c3e841003c
commit 8ab4207618
182 changed files with 31299 additions and 0 deletions
+23
View File
@@ -0,0 +1,23 @@
# vibe-py slice
Isolated Python web functions from [Real-Vuln-Benchmark](https://github.com/kolega-ai/Real-Vuln-Benchmark)
(Apache-2.0 benchmark; each target repository keeps its own license).
- **Vuln side**: the function enclosing a labeled vulnerable finding (`is_vulnerable = true`).
- **Fixed twin**: a false-positive trap function (`is_vulnerable = false`) from the same repository.
The scanner must stay silent there, so silent-on-fix here measures precision on traps.
- **Provenance**: `human` for the 26 human-authored apps, `agent` for the 40 LLM-generated apps.
The LLM-generated repositories (`kolega-ai-dev/vc-*`) currently carry **no license file**,
so they are skipped by `build_recipes.py` and not vendored (Req 5.4). Re-run with
`--allow-unlicensed` only to inspect them locally; do not commit those excerpts.
- **Caveat**: the human corpus is educational and CTF style (DVPWA, VAmPI, vulpy, ...), not
production code. Say so when reading numbers.
- **Matching**: every row names the function; the upstream scorer tolerates ±10 lines, ours
requires the detection inside the function.
- **Excerpt shape**: line-range excerpts of methods keep their class indentation, so 27 of them
fail stdlib `ast.parse` ("unexpected indent") while tree-sitter parses them with correct
function ranges. `parse_failed 0` rests on tree-sitter; stdlib-ast parity would need dedenting.
Rebuild: see the docstring of `build_recipes.py`. Regenerate the catalog with
`python benchmarks/pairs/catalog_gen.py --slice vibe-py`. Maintainer only; CI never fetches.
+226
View File
@@ -0,0 +1,226 @@
#!/usr/bin/env python3
"""Build vibe-py recipes from Real-Vuln-Benchmark ground truth (maintainer, offline once downloaded).
Download first (network, maintainer only):
mkdir -p /tmp/realvuln
gh api repos/kolega-ai/Real-Vuln-Benchmark/contents/benchmark-manifest.json --jq .content | base64 -d > /tmp/realvuln/manifest.json
for r in $(gh api repos/kolega-ai/Real-Vuln-Benchmark/contents/ground-truth --jq '.[] | select(.type=="dir") | .name'); do
gh api "repos/kolega-ai/Real-Vuln-Benchmark/contents/ground-truth/$r/ground-truth.json" --jq .content | base64 -d > "/tmp/realvuln/$r.json"
done
Then:
python benchmarks/pairs/vibe-py/build_recipes.py --ground-truth /tmp/realvuln --licenses /tmp/realvuln/licenses.json
python benchmarks/pairs/harvest.py --slice vibe-py --all --fetch
python benchmarks/pairs/catalog_gen.py --slice vibe-py
Pair shape: the vulnerable function (enclosing the labeled sink line) is the vuln side; a
false-positive trap function from the same repository is the fixed twin. Repositories
without a stated license are skipped (Req 5.4). Every recipe is a candidate until the
catalog row is reviewed.
"""
from __future__ import annotations
import argparse
import json
import re
from pathlib import Path
ROOT = Path(__file__).resolve().parent
MECHANISM = {
"idor": "identity_from_request_body",
"broken_access_control": "missing_auth_guard",
"mass_assignment": "identity_from_request_body",
"path_traversal": "path_join_user_input",
"unrestricted_file_upload": "path_join_user_input",
"hardcoded_credentials": "secret_in_client",
"sensitive_data_exposure": "secret_in_client",
"security_misconfiguration": "permissive_default",
"insecure_cookie_flags": "permissive_default",
"csrf": "permissive_default",
"weak_prng": "config_sink_weak_literal",
"weak_crypto": "config_sink_weak_literal",
"weak_hashing": "config_sink_weak_literal",
"sql_injection": "source_reaches_sink",
"nosql_injection": "source_reaches_sink",
"command_injection": "source_reaches_sink",
"code_injection": "source_reaches_sink",
"ssti": "source_reaches_sink",
"ssrf": "source_reaches_sink",
"open_redirect": "source_reaches_sink",
"reflected_xss": "source_reaches_sink",
"stored_xss": "source_reaches_sink",
"xxe": "source_reaches_sink",
"insecure_deserialization": "source_reaches_sink",
"sensitive_data_in_logs": "secret_in_client",
"business_logic_validation_gap": "validation_strength",
"user_enumeration": "validation_strength",
"missing_rate_limiting": "permissive_default",
"missing_rate_limiting_on_auth": "permissive_default",
"denial_of_service": "validation_strength",
}
# Classes an intra-file engine can talk about; the rest are recorded as candidates but not selected by default.
DEFAULT_CLASSES = (
"sql_injection",
"command_injection",
"code_injection",
"ssti",
"ssrf",
"path_traversal",
"open_redirect",
"insecure_deserialization",
"idor",
"broken_access_control",
"hardcoded_credentials",
"security_misconfiguration",
"reflected_xss",
"xxe",
"nosql_injection",
)
ACCEPTED_LICENSES = {"MIT", "Apache-2.0", "BSD-3-Clause", "BSD-2-Clause", "GPL-3.0", "GPL-2.0", "MPL-2.0", "Unlicense", "ISC"}
def _slug(text: str) -> str:
return re.sub(r"[^a-z0-9]+", "-", text.lower()).strip("-")
def build(
ground_truth: Path, licenses: Path, *, per_repo: int, classes: set[str], allow_unlicensed: bool
) -> tuple[list[dict[str, object]], dict[str, int]]:
manifest = json.loads((ground_truth / "manifest.json").read_text())
license_by_repo = json.loads(licenses.read_text()) if licenses.is_file() else {}
recipes: list[dict[str, object]] = []
skipped = {"unlicensed": 0, "no_trap": 0, "no_function": 0, "class": 0}
for repo_id, meta in sorted(manifest["repos"].items()):
gt_path = ground_truth / f"{repo_id}.json"
if not gt_path.is_file():
continue
gt = json.loads(gt_path.read_text())
info = license_by_repo.get(repo_id, {})
license_id = info.get("license") or ""
if license_id not in ACCEPTED_LICENSES and not allow_unlicensed:
skipped["unlicensed"] += 1
continue
full = info.get("full") or "/".join(meta["repo_url"].rstrip("/").split("/")[-2:])
commit = meta["commit_sha"]
provenance = "agent" if meta["authorship"] == "llm_generated" else "human"
findings = gt.get("findings", [])
traps = [
f
for f in findings
if not f.get("is_vulnerable") and f.get("location", {}).get("function") and f.get("file", "").endswith(".py")
]
if not traps:
skipped["no_trap"] += 1
continue
taken = 0
seen_functions: set[tuple[str, str]] = set()
for finding in findings:
if taken >= per_repo:
break
if not finding.get("is_vulnerable"):
continue
location = finding.get("location", {})
function = location.get("function")
file = finding.get("file", "")
if not function or not file.endswith(".py"):
skipped["no_function"] += 1
continue
vclass = str(finding.get("vulnerability_class", ""))
if vclass not in classes:
skipped["class"] += 1
continue
if (file, function) in seen_functions:
continue
seen_functions.add((file, function))
trap = next((t for t in traps if t["file"] == file), traps[0])
name = f"{_slug(repo_id.replace('realvuln-', '').replace('vc-', ''))}-{_slug(Path(file).stem)}-{_slug(function)}"[:60]
while any(r["name"] == name for r in recipes):
name = name[:57] + "-" + str(sum(1 for r in recipes if str(r["name"]).startswith(name[:57])) + 1)
recipes.append(
{
"name": name,
"host": "github",
"repo": full,
"parent": commit,
"commit": commit,
"path": file,
"fix_path": trap["file"],
"mode": "enclosing",
"line": int(location["start_line"]),
"fix_line": int(trap["location"]["start_line"]),
"function": function,
"language": "python",
"relpath": file,
"license": license_id or "unlicensed",
"cve": str(finding.get("evidence", {}).get("cve_id") or ""),
"year": 2026,
"cwe": str(finding.get("primary_cwe", "")),
"class": vclass,
"mechanism": MECHANISM.get(vclass, "other"),
"provenance": provenance,
"origin": "real-vuln-benchmark",
"project": repo_id,
"framework": str(meta.get("framework", "")),
"gt_id": str(finding.get("id", "")),
"trap_id": str(trap.get("id", "")),
"acceptable_cwes": list(finding.get("acceptable_cwes", [])),
"evidence": str(finding.get("evidence", {}).get("description", ""))[:240].replace("\n", " "),
"commit_url": f"https://github.com/{full}/blob/{commit}/{file}#L{int(location['start_line'])}",
}
)
taken += 1
# deterministic holdout: every other recipe by sorted name
for index, recipe in enumerate(sorted(recipes, key=lambda r: str(r["name"]))):
recipe["split"] = "holdout" if index % 2 else "train"
return recipes, skipped
def to_toml(recipes: list[dict[str, object]]) -> str:
lines = [
"# vibe-py harvest recipes generated from Real-Vuln-Benchmark ground truth by build_recipes.py.",
"# Vulnerable function = vuln side; a false-positive trap from the same repo = fixed twin.",
"# Review each row before trusting it as a label; regenerate with build_recipes.py.",
"",
]
for recipe in sorted(recipes, key=lambda r: str(r["name"])):
lines.append("[[recipe]]")
for key, value in recipe.items():
if isinstance(value, bool):
lines.append(f"{key} = {'true' if value else 'false'}")
elif isinstance(value, int):
lines.append(f"{key} = {value}")
elif isinstance(value, list):
inner = ", ".join('"' + str(item).replace('"', '\\"') + '"' for item in value)
lines.append(f"{key} = [{inner}]")
else:
lines.append(f'{key} = "{str(value).replace(chr(92), chr(92) * 2).replace(chr(34), chr(92) + chr(34))}"')
lines.append("")
return "\n".join(lines)
def main(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--ground-truth", type=Path, required=True, help="directory with manifest.json and <repo>.json ground truth")
parser.add_argument("--licenses", type=Path, default=None, help="json map repo_id -> {full, license}")
parser.add_argument("--per-repo", type=int, default=2)
parser.add_argument("--classes", default=",".join(DEFAULT_CLASSES))
parser.add_argument("--allow-unlicensed", action="store_true", help="include repositories without a stated license (NOT for vendoring)")
parser.add_argument("--out", type=Path, default=ROOT / "recipes.toml")
args = parser.parse_args(argv)
recipes, skipped = build(
args.ground_truth,
args.licenses or (args.ground_truth / "licenses.json"),
per_repo=args.per_repo,
classes=set(args.classes.split(",")),
allow_unlicensed=args.allow_unlicensed,
)
args.out.write_text(to_toml(recipes), encoding="utf-8")
print(f"wrote {args.out} ({len(recipes)} recipes); skipped {skipped}")
return 0
if __name__ == "__main__":
raise SystemExit(main())
+984
View File
@@ -0,0 +1,984 @@
# vibe-py pair slice. Reviewed isolated functions with provenance.
# Honesty dashboard — not the local 100% CI gate.
# Do not add these names to LANGUAGE_MANIFESTS.
# Regenerated by benchmarks/pairs/catalog_gen.py from recipes.toml.
[[pair]]
name = "damn-vulnerable-graphql-application-views-mutate"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "MIT"
repo = "dolevf/Damn-Vulnerable-GraphQL-Application"
cve = ""
cwe = "CWE-78"
commit = "a961308c02d1fb462b192681c336b0739e432da7"
parent = "a961308c02d1fb462b192681c336b0739e432da7"
commit_url = "https://github.com/dolevf/Damn-Vulnerable-GraphQL-Application/blob/a961308c02d1fb462b192681c336b0739e432da7/core/views.py#L211"
vuln = "damn-vulnerable-graphql-application-views-mutate/vuln.py"
fixed = "damn-vulnerable-graphql-application-views-mutate/fixed.py"
relpath = "core/views.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "train"
[[pair.expected]]
cwe = "CWE-78"
class = "command_injection"
path = "core/views.py"
function = "mutate"
mechanism = "source_reaches_sink"
evidence = "OS command injection in ImportPaste mutation. User-controlled host, port, path, and scheme parameters are used to construct a URL that is passed to os.popen via helpers.run_cmd(f'curl --insecure {url}'). In easy mode, strip_dangerous_charac"
[[pair]]
name = "damn-vulnerable-graphql-application-views-resolve-pastes"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "MIT"
repo = "dolevf/Damn-Vulnerable-GraphQL-Application"
cve = ""
cwe = "CWE-89"
commit = "a961308c02d1fb462b192681c336b0739e432da7"
parent = "a961308c02d1fb462b192681c336b0739e432da7"
commit_url = "https://github.com/dolevf/Damn-Vulnerable-GraphQL-Application/blob/a961308c02d1fb462b192681c336b0739e432da7/core/views.py#L320"
vuln = "damn-vulnerable-graphql-application-views-resolve-pastes/vuln.py"
fixed = "damn-vulnerable-graphql-application-views-resolve-pastes/fixed.py"
relpath = "core/views.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "holdout"
[[pair.expected]]
cwe = "CWE-89"
class = "sql_injection"
path = "core/views.py"
function = "resolve_pastes"
mechanism = "source_reaches_sink"
evidence = "SQL injection via unsanitized 'filter' GraphQL argument directly interpolated into raw SQL using Python string formatting: result.filter(text(\"title = '%s' or content = '%s'\" % (filter, filter))). An attacker can inject arbitrary SQL via th"
[[pair]]
name = "damn-vulnerable-graphql-application-views-resolve-system-dia"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "MIT"
repo = "dolevf/Damn-Vulnerable-GraphQL-Application"
cve = ""
cwe = "CWE-78"
commit = "a961308c02d1fb462b192681c336b0739e432da7"
parent = "a961308c02d1fb462b192681c336b0739e432da7"
commit_url = "https://github.com/dolevf/Damn-Vulnerable-GraphQL-Application/blob/a961308c02d1fb462b192681c336b0739e432da7/core/views.py#L345"
vuln = "damn-vulnerable-graphql-application-views-resolve-system-dia/vuln.py"
fixed = "damn-vulnerable-graphql-application-views-resolve-system-dia/fixed.py"
relpath = "core/views.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "train"
[[pair.expected]]
cwe = "CWE-78"
class = "command_injection"
path = "core/views.py"
function = "resolve_system_diagnostics"
mechanism = "source_reaches_sink"
evidence = "OS command injection via the 'cmd' argument in the systemDiagnostics GraphQL query. In easy mode, security.allowed_cmds() always returns True, so user-supplied cmd is passed directly to os.popen via helpers.run_cmd(cmd). Requires valid admi"
[[pair]]
name = "djangoat-analytics-hits-by-ip"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "MIT"
repo = "Contrast-Security-OSS/DjanGoat"
cve = ""
cwe = "CWE-89"
commit = "082c88bfefced508ae083b92b459c808f95e905e"
parent = "082c88bfefced508ae083b92b459c808f95e905e"
commit_url = "https://github.com/Contrast-Security-OSS/DjanGoat/blob/082c88bfefced508ae083b92b459c808f95e905e/app/models/Analytics/analytics.py#L57"
vuln = "djangoat-analytics-hits-by-ip/vuln.py"
fixed = "djangoat-analytics-hits-by-ip/fixed.py"
relpath = "app/models/Analytics/analytics.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "holdout"
[[pair.expected]]
cwe = "CWE-89"
class = "sql_injection"
path = "app/models/Analytics/analytics.py"
function = "hits_by_ip"
mechanism = "source_reaches_sink"
evidence = "SQL injection via string formatting in raw query. Both ip and col parameters are interpolated directly into SQL: 'SELECT %s FROM %s WHERE ip_address=\\'%s\\' ORDER BY id DESC' % (col, table_name, ip). The ip parameter comes from request.GET['"
[[pair]]
name = "djangoat-views-reset-password"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "MIT"
repo = "Contrast-Security-OSS/DjanGoat"
cve = ""
cwe = "CWE-502"
commit = "082c88bfefced508ae083b92b459c808f95e905e"
parent = "082c88bfefced508ae083b92b459c808f95e905e"
commit_url = "https://github.com/Contrast-Security-OSS/DjanGoat/blob/082c88bfefced508ae083b92b459c808f95e905e/app/views/password_resets/views.py#L84"
vuln = "djangoat-views-reset-password/vuln.py"
fixed = "djangoat-views-reset-password/fixed.py"
relpath = "app/views/password_resets/views.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "train"
[[pair.expected]]
cwe = "CWE-502"
class = "insecure_deserialization"
path = "app/views/password_resets/views.py"
function = "reset_password"
mechanism = "source_reaches_sink"
evidence = "Remote code execution via insecure deserialization. User-controlled POST parameter 'user' is base64-decoded and passed to pickle.loads(): user = pickle.loads(base64.b64decode(encoded_user)). An attacker can craft a malicious pickle payload "
[[pair]]
name = "djangoat-views-user-view"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "MIT"
repo = "Contrast-Security-OSS/DjanGoat"
cve = ""
cwe = "CWE-89"
commit = "082c88bfefced508ae083b92b459c808f95e905e"
parent = "082c88bfefced508ae083b92b459c808f95e905e"
commit_url = "https://github.com/Contrast-Security-OSS/DjanGoat/blob/082c88bfefced508ae083b92b459c808f95e905e/app/views/users/views.py#L74"
vuln = "djangoat-views-user-view/vuln.py"
fixed = "djangoat-views-user-view/fixed.py"
relpath = "app/views/users/views.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "holdout"
[[pair.expected]]
cwe = "CWE-89"
class = "sql_injection"
path = "app/views/users/views.py"
function = "user_view"
mechanism = "source_reaches_sink"
evidence = "SQL injection via string formatting in raw query. user_id_form from POST data is interpolated directly into SQL: User.objects.raw('SELECT * FROM %s WHERE user_id=\\'%s\\' ORDER BY is_admin=\\'0\\'' % (table_name, user_id_form)). An attacker can"
[[pair]]
name = "dsvpwa-attacks-run"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "MIT"
repo = "sgabe/DSVPWA"
cve = ""
cwe = "CWE-89"
commit = "a06abb306ed3699bb2f073e3f41d3d9c57012819"
parent = "a06abb306ed3699bb2f073e3f41d3d9c57012819"
commit_url = "https://github.com/sgabe/DSVPWA/blob/a06abb306ed3699bb2f073e3f41d3d9c57012819/dsvpwa/attacks.py#L39"
vuln = "dsvpwa-attacks-run/vuln.py"
fixed = "dsvpwa-attacks-run/fixed.py"
relpath = "dsvpwa/attacks.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "train"
[[pair.expected]]
cwe = "CWE-89"
class = "sql_injection"
path = "dsvpwa/attacks.py"
function = "run"
mechanism = "source_reaches_sink"
evidence = "SQL injection via string concatenation in SQLinjection.run(). The 'id' parameter from request is concatenated directly into SQL: cursor.execute(\"SELECT ... WHERE id=\" + id). No parameterization or input validation."
[[pair]]
name = "dsvpwa-dsvpwa-main"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "MIT"
repo = "sgabe/DSVPWA"
cve = ""
cwe = "CWE-326"
commit = "a06abb306ed3699bb2f073e3f41d3d9c57012819"
parent = "a06abb306ed3699bb2f073e3f41d3d9c57012819"
commit_url = "https://github.com/sgabe/DSVPWA/blob/a06abb306ed3699bb2f073e3f41d3d9c57012819/dsvpwa.py#L37"
vuln = "dsvpwa-dsvpwa-main/vuln.py"
fixed = "dsvpwa-dsvpwa-main/fixed.py"
relpath = "dsvpwa.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "holdout"
[[pair.expected]]
cwe = "CWE-326"
class = "security_misconfiguration"
path = "dsvpwa.py"
function = "main"
mechanism = "permissive_default"
evidence = "Insecure SSL/TLS configuration in main(). Three dangerous SSL options are explicitly enabled: (1) SSLv3 re-enabled via ctx.options &= ~ssl.OP_NO_SSLv3 (vulnerable to POODLE), (2) TLS compression re-enabled via &= ~ssl.OP_NO_COMPRESSION (vul"
[[pair]]
name = "dsvpwa-handlers-do-bdr"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "MIT"
repo = "sgabe/DSVPWA"
cve = ""
cwe = "CWE-78"
commit = "a06abb306ed3699bb2f073e3f41d3d9c57012819"
parent = "a06abb306ed3699bb2f073e3f41d3d9c57012819"
commit_url = "https://github.com/sgabe/DSVPWA/blob/a06abb306ed3699bb2f073e3f41d3d9c57012819/dsvpwa/handlers.py#L183"
vuln = "dsvpwa-handlers-do-bdr/vuln.py"
fixed = "dsvpwa-handlers-do-bdr/fixed.py"
relpath = "dsvpwa/handlers.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "train"
[[pair.expected]]
cwe = "CWE-78"
class = "command_injection"
path = "dsvpwa/handlers.py"
function = "do_BDR"
mechanism = "source_reaches_sink"
evidence = "Critical command injection via custom HTTP method BDR in do_BDR(). The URL path (self.path[1:]) is passed directly to subprocess.check_output() with shell=True: subprocess.check_output(self.path[1:], shell=True, ...). Any command can be exe"
[[pair]]
name = "dsvw-dsvw-do-get"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "Unlicense"
repo = "stamparm/DSVW"
cve = ""
cwe = "CWE-89"
commit = "7d40f4b7939c901610ed9b85724552d60e7d63fa"
parent = "7d40f4b7939c901610ed9b85724552d60e7d63fa"
commit_url = "https://github.com/stamparm/DSVW/blob/7d40f4b7939c901610ed9b85724552d60e7d63fa/dsvw.py#L30"
vuln = "dsvw-dsvw-do-get/vuln.py"
fixed = "dsvw-dsvw-do-get/fixed.py"
relpath = "dsvw.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "holdout"
[[pair.expected]]
cwe = "CWE-89"
class = "sql_injection"
path = "dsvw.py"
function = "do_GET"
mechanism = "source_reaches_sink"
evidence = "SQL injection via id parameter directly concatenated into SELECT query without sanitization"
[[pair]]
name = "dvpwa-app-init"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "MIT"
repo = "anxolerd/dvpwa"
cve = ""
cwe = "CWE-16"
commit = "a1d8f89fac2e57093189853c6527c2b01fc1d9c1"
parent = "a1d8f89fac2e57093189853c6527c2b01fc1d9c1"
commit_url = "https://github.com/anxolerd/dvpwa/blob/a1d8f89fac2e57093189853c6527c2b01fc1d9c1/sqli/app.py#L35"
vuln = "dvpwa-app-init/vuln.py"
fixed = "dvpwa-app-init/fixed.py"
relpath = "sqli/app.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "train"
[[pair.expected]]
cwe = "CWE-16"
class = "security_misconfiguration"
path = "sqli/app.py"
function = "init"
mechanism = "permissive_default"
evidence = "Jinja2 template engine configured with autoescape=False. This disables automatic HTML escaping for all template variables, making every unescaped template expression a potential XSS sink. This is the root cause of all stored XSS vulnerabili"
[[pair]]
name = "dvpwa-middlewares-session-middleware"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "MIT"
repo = "anxolerd/dvpwa"
cve = ""
cwe = "CWE-1004"
commit = "a1d8f89fac2e57093189853c6527c2b01fc1d9c1"
parent = "a1d8f89fac2e57093189853c6527c2b01fc1d9c1"
commit_url = "https://github.com/anxolerd/dvpwa/blob/a1d8f89fac2e57093189853c6527c2b01fc1d9c1/sqli/middlewares.py#L20"
vuln = "dvpwa-middlewares-session-middleware/vuln.py"
fixed = "dvpwa-middlewares-session-middleware/fixed.py"
relpath = "sqli/middlewares.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "holdout"
[[pair.expected]]
cwe = "CWE-1004"
class = "security_misconfiguration"
path = "sqli/middlewares.py"
function = "session_middleware"
mechanism = "permissive_default"
evidence = "Session cookie created with httponly=False. The RedisStorage is configured with httponly=False, meaning the AIOHTTP_SESSION cookie is accessible to JavaScript via document.cookie. Combined with the stored XSS vulnerabilities, this enables s"
[[pair]]
name = "dvpwa-student-create"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "MIT"
repo = "anxolerd/dvpwa"
cve = ""
cwe = "CWE-89"
commit = "a1d8f89fac2e57093189853c6527c2b01fc1d9c1"
parent = "a1d8f89fac2e57093189853c6527c2b01fc1d9c1"
commit_url = "https://github.com/anxolerd/dvpwa/blob/a1d8f89fac2e57093189853c6527c2b01fc1d9c1/sqli/dao/student.py#L42"
vuln = "dvpwa-student-create/vuln.py"
fixed = "dvpwa-student-create/fixed.py"
relpath = "sqli/dao/student.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "train"
[[pair.expected]]
cwe = "CWE-89"
class = "sql_injection"
path = "sqli/dao/student.py"
function = "create"
mechanism = "source_reaches_sink"
evidence = "SQL injection via Python string formatting. The 'name' parameter from user input is interpolated directly into the SQL query using Python's % operator: \"VALUES ('%(name)s')\" % {'name': name}. The resulting string is then passed to cur.execu"
[[pair]]
name = "extremely-vulnerable-flask-app-account-before-request"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "GPL-3.0"
repo = "manuelz120/extremely-vulnerable-flask-app"
cve = ""
cwe = "CWE-502"
commit = "d5d8875559e21222bbbaadb7b9f0af592c6eb7fa"
parent = "d5d8875559e21222bbbaadb7b9f0af592c6eb7fa"
commit_url = "https://github.com/manuelz120/extremely-vulnerable-flask-app/blob/d5d8875559e21222bbbaadb7b9f0af592c6eb7fa/routes/account.py#L118"
vuln = "extremely-vulnerable-flask-app-account-before-request/vuln.py"
fixed = "extremely-vulnerable-flask-app-account-before-request/fixed.py"
relpath = "routes/account.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "holdout"
[[pair.expected]]
cwe = "CWE-502"
class = "insecure_deserialization"
path = "routes/account.py"
function = "before_request"
mechanism = "source_reaches_sink"
evidence = "Remote code execution via insecure deserialization. The 'preferences' cookie is base64-decoded and passed directly to pickle.loads() (imported as 'loads' from pickle). An attacker can craft a malicious pickle payload, base64-encode it, and "
[[pair]]
name = "extremely-vulnerable-flask-app-account-search"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "GPL-3.0"
repo = "manuelz120/extremely-vulnerable-flask-app"
cve = ""
cwe = "CWE-89"
commit = "d5d8875559e21222bbbaadb7b9f0af592c6eb7fa"
parent = "d5d8875559e21222bbbaadb7b9f0af592c6eb7fa"
commit_url = "https://github.com/manuelz120/extremely-vulnerable-flask-app/blob/d5d8875559e21222bbbaadb7b9f0af592c6eb7fa/routes/account.py#L33"
vuln = "extremely-vulnerable-flask-app-account-search/vuln.py"
fixed = "extremely-vulnerable-flask-app-account-search/fixed.py"
relpath = "routes/account.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "train"
[[pair.expected]]
cwe = "CWE-89"
class = "sql_injection"
path = "routes/account.py"
function = "search"
mechanism = "source_reaches_sink"
evidence = "SQL injection via f-string interpolation of user-supplied search parameter into a raw SQL text() fragment: text(f\"text like '%{search_param}%'\"). The search_param comes directly from request.args.get('search') with no sanitization."
[[pair]]
name = "extremely-vulnerable-flask-app-signup-validate-token"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "GPL-3.0"
repo = "manuelz120/extremely-vulnerable-flask-app"
cve = ""
cwe = "CWE-89"
commit = "d5d8875559e21222bbbaadb7b9f0af592c6eb7fa"
parent = "d5d8875559e21222bbbaadb7b9f0af592c6eb7fa"
commit_url = "https://github.com/manuelz120/extremely-vulnerable-flask-app/blob/d5d8875559e21222bbbaadb7b9f0af592c6eb7fa/routes/signup.py#L15"
vuln = "extremely-vulnerable-flask-app-signup-validate-token/vuln.py"
fixed = "extremely-vulnerable-flask-app-signup-validate-token/fixed.py"
relpath = "routes/signup.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "holdout"
[[pair.expected]]
cwe = "CWE-89"
class = "sql_injection"
path = "routes/signup.py"
function = "validate_token"
mechanism = "source_reaches_sink"
evidence = "SQL injection via f-string interpolation of user-supplied registration code directly into a raw SQL query: text(f\"SELECT id, code FROM ... WHERE code = '{code}'\"). An attacker can inject arbitrary SQL through the registration_code form fiel"
[[pair]]
name = "python-insecure-app-main-try-hack-me"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "GPL-3.0"
repo = "kolega-ai/realvuln-python-insecure-app"
cve = ""
cwe = "CWE-1336"
commit = "80b894a2f754590747a31c92b2088be086421953"
parent = "80b894a2f754590747a31c92b2088be086421953"
commit_url = "https://github.com/kolega-ai/realvuln-python-insecure-app/blob/80b894a2f754590747a31c92b2088be086421953/app/main.py#L41"
vuln = "python-insecure-app-main-try-hack-me/vuln.py"
fixed = "python-insecure-app-main-try-hack-me/fixed.py"
relpath = "app/main.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "train"
[[pair.expected]]
cwe = "CWE-1336"
class = "ssti"
path = "app/main.py"
function = "try_hack_me"
mechanism = "source_reaches_sink"
evidence = "Server-Side Template Injection via Jinja2. User-controlled 'name' query parameter is interpolated into an f-string on line 38 to build 'content', which is then passed to Template(content).render() on line 41. An attacker can inject Jinja2 t"
[[pair]]
name = "pythonssti-main-read-root"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "MIT"
repo = "TheWation/PythonSSTI"
cve = ""
cwe = "CWE-79"
commit = "76339c27d5a870c0a81bad6aee5f9bd516592145"
parent = "76339c27d5a870c0a81bad6aee5f9bd516592145"
commit_url = "https://github.com/TheWation/PythonSSTI/blob/76339c27d5a870c0a81bad6aee5f9bd516592145/main.py#L14"
vuln = "pythonssti-main-read-root/vuln.py"
fixed = "pythonssti-main-read-root/fixed.py"
relpath = "main.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "holdout"
[[pair.expected]]
cwe = "CWE-79"
class = "reflected_xss"
path = "main.py"
function = "read_root"
mechanism = "source_reaches_sink"
evidence = "The Jinja2 Environment is created with default settings (autoescape=False). User input from the 'username' query parameter is concatenated into the template string and the rendered output is returned as HTMLResponse. An attacker can inject "
[[pair]]
name = "threatbyte-api-v1-delete"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "MIT"
repo = "anotherik/ThreatByte"
cve = ""
cwe = "CWE-862"
commit = "c4db46f72586c4ecb65859051ea037018dbf0e5e"
parent = "c4db46f72586c4ecb65859051ea037018dbf0e5e"
commit_url = "https://github.com/anotherik/ThreatByte/blob/c4db46f72586c4ecb65859051ea037018dbf0e5e/server/api/v1/api_v1.py#L223"
vuln = "threatbyte-api-v1-delete/vuln.py"
fixed = "threatbyte-api-v1-delete/fixed.py"
relpath = "server/api/v1/api_v1.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "train"
[[pair.expected]]
cwe = "CWE-862"
class = "broken_access_control"
path = "server/api/v1/api_v1.py"
function = "delete"
mechanism = "missing_auth_guard"
evidence = "BFLA (Broken Function Level Authorization) on the delete-user API endpoint. The @token_required decorator is commented out (lines 221-222), so DELETE /api/v1/delete-user/<user_id> can be called by anyone without authentication to delete any"
[[pair]]
name = "threatbyte-api-v1-get"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "MIT"
repo = "anotherik/ThreatByte"
cve = ""
cwe = "CWE-639"
commit = "c4db46f72586c4ecb65859051ea037018dbf0e5e"
parent = "c4db46f72586c4ecb65859051ea037018dbf0e5e"
commit_url = "https://github.com/anotherik/ThreatByte/blob/c4db46f72586c4ecb65859051ea037018dbf0e5e/server/api/v1/api_v1.py#L154"
vuln = "threatbyte-api-v1-get/vuln.py"
fixed = "threatbyte-api-v1-get/fixed.py"
relpath = "server/api/v1/api_v1.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "holdout"
[[pair.expected]]
cwe = "CWE-639"
class = "broken_access_control"
path = "server/api/v1/api_v1.py"
function = "get"
mechanism = "missing_auth_guard"
evidence = "BOLA (Broken Object Level Authorization) on the API profile endpoint. The @token_required decorator is commented out (line 152-153), so /api/v1/profile?user_id=X returns any user's profile (username, email, country, role, permissions, team)"
[[pair]]
name = "threatbyte-routes-dashboard"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "MIT"
repo = "anotherik/ThreatByte"
cve = ""
cwe = "CWE-89"
commit = "c4db46f72586c4ecb65859051ea037018dbf0e5e"
parent = "c4db46f72586c4ecb65859051ea037018dbf0e5e"
commit_url = "https://github.com/anotherik/ThreatByte/blob/c4db46f72586c4ecb65859051ea037018dbf0e5e/server/routes.py#L137"
vuln = "threatbyte-routes-dashboard/vuln.py"
fixed = "threatbyte-routes-dashboard/fixed.py"
relpath = "server/routes.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "train"
[[pair.expected]]
cwe = "CWE-89"
class = "sql_injection"
path = "server/routes.py"
function = "dashboard"
mechanism = "source_reaches_sink"
evidence = "SQL injection via f-string interpolation of user-controlled search_query parameter directly into SQL: s_query = f\"SELECT filename FROM files WHERE user_id = {user_id} AND filename LIKE '%{search_query}%'\". The search_query comes from reques"
[[pair]]
name = "vampi-books-get-by-title"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "MIT"
repo = "erev0s/VAmPI"
cve = ""
cwe = "CWE-639"
commit = "1713b54b601ad29582581eeda4b31fceb1319874"
parent = "1713b54b601ad29582581eeda4b31fceb1319874"
commit_url = "https://github.com/erev0s/VAmPI/blob/1713b54b601ad29582581eeda4b31fceb1319874/api_views/books.py#L51"
vuln = "vampi-books-get-by-title/vuln.py"
fixed = "vampi-books-get-by-title/fixed.py"
relpath = "api_views/books.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "holdout"
[[pair.expected]]
cwe = "CWE-639"
class = "broken_access_control"
path = "api_views/books.py"
function = "get_by_title"
mechanism = "missing_auth_guard"
evidence = "Broken Object Level Authorization (BOLA). When vuln=1, get_by_title queries the book by title only (Book.query.filter_by(book_title=str(book_title)).first()) without verifying the authenticated user is the owner. Any authenticated user can "
[[pair]]
name = "vampi-user-model-get-user"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "MIT"
repo = "erev0s/VAmPI"
cve = ""
cwe = "CWE-89"
commit = "1713b54b601ad29582581eeda4b31fceb1319874"
parent = "1713b54b601ad29582581eeda4b31fceb1319874"
commit_url = "https://github.com/erev0s/VAmPI/blob/1713b54b601ad29582581eeda4b31fceb1319874/models/user_model.py#L72"
vuln = "vampi-user-model-get-user/vuln.py"
fixed = "vampi-user-model-get-user/fixed.py"
relpath = "models/user_model.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "train"
[[pair.expected]]
cwe = "CWE-89"
class = "sql_injection"
path = "models/user_model.py"
function = "get_user"
mechanism = "source_reaches_sink"
evidence = "SQL injection via f-string interpolation of unsanitized username path parameter into raw SQL query: user_query = f\"SELECT * FROM users WHERE username = '{username}'\" followed by db.session.execute(text(user_query)). Reachable from GET /user"
[[pair]]
name = "vampi-users-update-password"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "MIT"
repo = "erev0s/VAmPI"
cve = ""
cwe = "CWE-639"
commit = "1713b54b601ad29582581eeda4b31fceb1319874"
parent = "1713b54b601ad29582581eeda4b31fceb1319874"
commit_url = "https://github.com/erev0s/VAmPI/blob/1713b54b601ad29582581eeda4b31fceb1319874/api_views/users.py#L187"
vuln = "vampi-users-update-password/vuln.py"
fixed = "vampi-users-update-password/fixed.py"
relpath = "api_views/users.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "holdout"
[[pair.expected]]
cwe = "CWE-639"
class = "broken_access_control"
path = "api_views/users.py"
function = "update_password"
mechanism = "missing_auth_guard"
evidence = "Unauthorized password change (IDOR). When vuln=1, the update_password function uses the username from the URL path parameter to look up the user whose password to change, instead of using the authenticated user from the JWT token (resp['sub"
[[pair]]
name = "vfapi-main-delete-user"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "MIT"
repo = "naryal2580/vfapi"
cve = ""
cwe = "CWE-89"
commit = "f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3"
parent = "f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3"
commit_url = "https://github.com/naryal2580/vfapi/blob/f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3/main.py#L231"
vuln = "vfapi-main-delete-user/vuln.py"
fixed = "vfapi-main-delete-user/fixed.py"
relpath = "main.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "train"
[[pair.expected]]
cwe = "CWE-89"
class = "sql_injection"
path = "main.py"
function = "delete_user"
mechanism = "source_reaches_sink"
evidence = "SQL injection via f-string interpolation of username query parameter into DELETE SQL query: f'DELETE FROM users WHERE username = \"{username}\";'. No sanitization or parameterization."
[[pair]]
name = "vfapi-main-put-user"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "MIT"
repo = "naryal2580/vfapi"
cve = ""
cwe = "CWE-89"
commit = "f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3"
parent = "f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3"
commit_url = "https://github.com/naryal2580/vfapi/blob/f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3/main.py#L188"
vuln = "vfapi-main-put-user/vuln.py"
fixed = "vfapi-main-put-user/fixed.py"
relpath = "main.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "holdout"
[[pair.expected]]
cwe = "CWE-89"
class = "sql_injection"
path = "main.py"
function = "put_user"
mechanism = "source_reaches_sink"
evidence = "SQL injection via f-string interpolation of all user-supplied fields (name, username, password, address, email, contact) into an INSERT SQL query. All fields from the User model body are directly embedded in the query string without paramet"
[[pair]]
name = "vfapi-main-sql-return-users-from-username"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "MIT"
repo = "naryal2580/vfapi"
cve = ""
cwe = "CWE-89"
commit = "f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3"
parent = "f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3"
commit_url = "https://github.com/naryal2580/vfapi/blob/f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3/main.py#L182"
vuln = "vfapi-main-sql-return-users-from-username/vuln.py"
fixed = "vfapi-main-sql-return-users-from-username/fixed.py"
relpath = "main.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "train"
[[pair.expected]]
cwe = "CWE-89"
class = "sql_injection"
path = "main.py"
function = "sql_return_users_from_username"
mechanism = "source_reaches_sink"
evidence = "SQL injection via f-string interpolation of username query parameter directly into SQL query: f'SELECT * FROM users WHERE username = \"{username}\";'. No sanitization or parameterization."
[[pair]]
name = "vulnerable-python-apps-bad-mvc-do-get"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "GPL-3.0"
repo = "LinuxUser255/Vulnerable_Python_Apps"
cve = ""
cwe = "CWE-79"
commit = "6336c77e6db523a5df34c4b628dff4159110797a"
parent = "6336c77e6db523a5df34c4b628dff4159110797a"
commit_url = "https://github.com/LinuxUser255/Vulnerable_Python_Apps/blob/6336c77e6db523a5df34c4b628dff4159110797a/Insecure_Frameworks/bad_mvc.py#L37"
vuln = "vulnerable-python-apps-bad-mvc-do-get/vuln.py"
fixed = "vulnerable-python-apps-bad-mvc-do-get/fixed.py"
relpath = "Insecure_Frameworks/bad_mvc.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "holdout"
[[pair.expected]]
cwe = "CWE-79"
class = "reflected_xss"
path = "Insecure_Frameworks/bad_mvc.py"
function = "do_GET"
mechanism = "source_reaches_sink"
evidence = "XSS via unescaped output. The username variable (derived from decrypting a user-supplied cookie at line 26) is rendered into HTML without any escaping: bytes('Hello %s' % username, 'utf-8'). An attacker who controls the encrypted cookie val"
[[pair]]
name = "vulnerable-python-apps-dir-traversal-do-get"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "GPL-3.0"
repo = "LinuxUser255/Vulnerable_Python_Apps"
cve = ""
cwe = "CWE-22"
commit = "6336c77e6db523a5df34c4b628dff4159110797a"
parent = "6336c77e6db523a5df34c4b628dff4159110797a"
commit_url = "https://github.com/LinuxUser255/Vulnerable_Python_Apps/blob/6336c77e6db523a5df34c4b628dff4159110797a/Directory_Traversal/Dir_Traversal.py#L22"
vuln = "vulnerable-python-apps-dir-traversal-do-get/vuln.py"
fixed = "vulnerable-python-apps-dir-traversal-do-get/fixed.py"
relpath = "Directory_Traversal/Dir_Traversal.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "train"
[[pair.expected]]
cwe = "CWE-22"
class = "path_traversal"
path = "Directory_Traversal/Dir_Traversal.py"
function = "do_GET"
mechanism = "path_join_user_input"
evidence = "Arbitrary file read via path traversal. self.path from the HTTP request is concatenated to cwd at line 14 and opened at line 22 via open(path).read(). The regex filter on line 10-11 (r'/\\.\\.\\/\\.\\./' with re.match) is trivially bypassable — "
[[pair]]
name = "vulnpy-cmdi-do-os-system"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "MIT"
repo = "Contrast-Security-OSS/vulnpy"
cve = ""
cwe = "CWE-78"
commit = "d1d0f64c06f038fe59a049e0e6001bfaf9839697"
parent = "d1d0f64c06f038fe59a049e0e6001bfaf9839697"
commit_url = "https://github.com/Contrast-Security-OSS/vulnpy/blob/d1d0f64c06f038fe59a049e0e6001bfaf9839697/src/vulnpy/trigger/cmdi.py#L6"
vuln = "vulnpy-cmdi-do-os-system/vuln.py"
fixed = "vulnpy-cmdi-do-os-system/fixed.py"
relpath = "src/vulnpy/trigger/cmdi.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "train"
[[pair.expected]]
cwe = "CWE-78"
class = "command_injection"
path = "src/vulnpy/trigger/cmdi.py"
function = "do_os_system"
mechanism = "source_reaches_sink"
evidence = "User-controlled command passed directly to os.system(command) with no sanitization, enabling arbitrary OS command execution"
[[pair]]
name = "vulnpy-cmdi-do-subprocess-popen"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "MIT"
repo = "Contrast-Security-OSS/vulnpy"
cve = ""
cwe = "CWE-78"
commit = "d1d0f64c06f038fe59a049e0e6001bfaf9839697"
parent = "d1d0f64c06f038fe59a049e0e6001bfaf9839697"
commit_url = "https://github.com/Contrast-Security-OSS/vulnpy/blob/d1d0f64c06f038fe59a049e0e6001bfaf9839697/src/vulnpy/trigger/cmdi.py#L10"
vuln = "vulnpy-cmdi-do-subprocess-popen/vuln.py"
fixed = "vulnpy-cmdi-do-subprocess-popen/fixed.py"
relpath = "src/vulnpy/trigger/cmdi.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "holdout"
[[pair.expected]]
cwe = "CWE-78"
class = "command_injection"
path = "src/vulnpy/trigger/cmdi.py"
function = "do_subprocess_popen"
mechanism = "source_reaches_sink"
evidence = "User-controlled command passed to subprocess.Popen with shell=True, enabling arbitrary OS command execution"
[[pair]]
name = "vulnpy-deserialization-do-pickle-load"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "MIT"
repo = "Contrast-Security-OSS/vulnpy"
cve = ""
cwe = "CWE-502"
commit = "d1d0f64c06f038fe59a049e0e6001bfaf9839697"
parent = "d1d0f64c06f038fe59a049e0e6001bfaf9839697"
commit_url = "https://github.com/Contrast-Security-OSS/vulnpy/blob/d1d0f64c06f038fe59a049e0e6001bfaf9839697/src/vulnpy/trigger/deserialization.py#L8"
vuln = "vulnpy-deserialization-do-pickle-load/vuln.py"
fixed = "vulnpy-deserialization-do-pickle-load/fixed.py"
relpath = "src/vulnpy/trigger/deserialization.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "train"
[[pair.expected]]
cwe = "CWE-502"
class = "insecure_deserialization"
path = "src/vulnpy/trigger/deserialization.py"
function = "do_pickle_load"
mechanism = "source_reaches_sink"
evidence = "User input encoded to bytes and passed to pickle.load(), which can execute arbitrary code via crafted pickle payloads"
[[pair]]
name = "vulpy-libuser-create"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "MIT"
repo = "fportantier/vulpy"
cve = ""
cwe = "CWE-89"
commit = "5249cc8b05a1c37f6b2f757b1cf16a509c327122"
parent = "5249cc8b05a1c37f6b2f757b1cf16a509c327122"
commit_url = "https://github.com/fportantier/vulpy/blob/5249cc8b05a1c37f6b2f757b1cf16a509c327122/bad/libuser.py#L25"
vuln = "vulpy-libuser-create/vuln.py"
fixed = "vulpy-libuser-create/fixed.py"
relpath = "bad/libuser.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "holdout"
[[pair.expected]]
cwe = "CWE-89"
class = "sql_injection"
path = "bad/libuser.py"
function = "create"
mechanism = "source_reaches_sink"
evidence = "SQL injection via %-formatting in INSERT statement: c.execute(\"INSERT INTO users ... VALUES ('%s', '%s', ...\" %(username, password, ...)). User-supplied username and password are interpolated via % string formatting into the SQL query."
[[pair]]
name = "vulpy-libuser-login"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "MIT"
repo = "fportantier/vulpy"
cve = ""
cwe = "CWE-89"
commit = "5249cc8b05a1c37f6b2f757b1cf16a509c327122"
parent = "5249cc8b05a1c37f6b2f757b1cf16a509c327122"
commit_url = "https://github.com/fportantier/vulpy/blob/5249cc8b05a1c37f6b2f757b1cf16a509c327122/bad/libuser.py#L12"
vuln = "vulpy-libuser-login/vuln.py"
fixed = "vulpy-libuser-login/fixed.py"
relpath = "bad/libuser.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "train"
[[pair.expected]]
cwe = "CWE-89"
class = "sql_injection"
path = "bad/libuser.py"
function = "login"
mechanism = "source_reaches_sink"
evidence = "SQL injection via string format in login query: c.execute(\"SELECT * FROM users WHERE username = '{}' and password = '{}'\".format(username, password)). User-supplied username and password from request.form are directly interpolated into the "
[[pair]]
name = "vulpy-libuser-password-change"
slice = "vibe-py"
language = "python"
origin = "real-vuln-benchmark"
license = "MIT"
repo = "fportantier/vulpy"
cve = ""
cwe = "CWE-89"
commit = "5249cc8b05a1c37f6b2f757b1cf16a509c327122"
parent = "5249cc8b05a1c37f6b2f757b1cf16a509c327122"
commit_url = "https://github.com/fportantier/vulpy/blob/5249cc8b05a1c37f6b2f757b1cf16a509c327122/bad/libuser.py#L53"
vuln = "vulpy-libuser-password-change/vuln.py"
fixed = "vulpy-libuser-password-change/fixed.py"
relpath = "bad/libuser.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "holdout"
[[pair.expected]]
cwe = "CWE-89"
class = "sql_injection"
path = "bad/libuser.py"
function = "password_change"
mechanism = "source_reaches_sink"
evidence = "SQL injection via string format in UPDATE statement: c.execute(\"UPDATE users SET password = '{}' WHERE username = '{}'\".format(password, username)). The password parameter from user input is directly interpolated into the SQL query."
@@ -0,0 +1,21 @@
# Provenance: dolevf/Damn-Vulnerable-GraphQL-Application mutate (fixed).
# repo: dolevf/Damn-Vulnerable-GraphQL-Application
# commit: a961308c02d1fb462b192681c336b0739e432da7
# parent: a961308c02d1fb462b192681c336b0739e432da7
# commit_url: https://github.com/dolevf/Damn-Vulnerable-GraphQL-Application/blob/a961308c02d1fb462b192681c336b0739e432da7/core/views.py#L211
# cve:
# license: MIT
# function: mutate
# relpath: core/views.py
# provenance: human
# mechanism: source_reaches_sink
def mutate(self, info , username, password) :
user = User.query.filter_by(username=username, password=password).first()
Audit.create_audit_entry(info)
if not user:
raise Exception('Authentication Failure')
return Login(
access_token = create_access_token(username),
refresh_token = create_refresh_token(username)
)
@@ -0,0 +1,27 @@
# Provenance: dolevf/Damn-Vulnerable-GraphQL-Application mutate (vuln).
# repo: dolevf/Damn-Vulnerable-GraphQL-Application
# commit: a961308c02d1fb462b192681c336b0739e432da7
# parent: a961308c02d1fb462b192681c336b0739e432da7
# commit_url: https://github.com/dolevf/Damn-Vulnerable-GraphQL-Application/blob/a961308c02d1fb462b192681c336b0739e432da7/core/views.py#L211
# cve:
# license: MIT
# function: mutate
# relpath: core/views.py
# provenance: human
# mechanism: source_reaches_sink
def mutate(self, info, host='pastebin.com', port=443, path='/', scheme="http"):
url = security.strip_dangerous_characters(f"{scheme}://{host}:{port}{path}")
cmd = helpers.run_cmd(f'curl --insecure {url}')
owner = Owner.query.filter_by(name='DVGAUser').first()
Paste.create_paste(
title='Imported Paste from URL - {}'.format(helpers.generate_uuid()),
content=cmd, public=False, burn=False,
owner_id=owner.id, owner=owner, ip_addr=request.remote_addr,
user_agent=request.headers.get('User-Agent', '')
)
Audit.create_audit_entry(info)
return ImportPaste(result=cmd)
@@ -0,0 +1,21 @@
# Provenance: dolevf/Damn-Vulnerable-GraphQL-Application resolve_pastes (fixed).
# repo: dolevf/Damn-Vulnerable-GraphQL-Application
# commit: a961308c02d1fb462b192681c336b0739e432da7
# parent: a961308c02d1fb462b192681c336b0739e432da7
# commit_url: https://github.com/dolevf/Damn-Vulnerable-GraphQL-Application/blob/a961308c02d1fb462b192681c336b0739e432da7/core/views.py#L320
# cve:
# license: MIT
# function: resolve_pastes
# relpath: core/views.py
# provenance: human
# mechanism: source_reaches_sink
def mutate(self, info , username, password) :
user = User.query.filter_by(username=username, password=password).first()
Audit.create_audit_entry(info)
if not user:
raise Exception('Authentication Failure')
return Login(
access_token = create_access_token(username),
refresh_token = create_refresh_token(username)
)
@@ -0,0 +1,21 @@
# Provenance: dolevf/Damn-Vulnerable-GraphQL-Application resolve_pastes (vuln).
# repo: dolevf/Damn-Vulnerable-GraphQL-Application
# commit: a961308c02d1fb462b192681c336b0739e432da7
# parent: a961308c02d1fb462b192681c336b0739e432da7
# commit_url: https://github.com/dolevf/Damn-Vulnerable-GraphQL-Application/blob/a961308c02d1fb462b192681c336b0739e432da7/core/views.py#L320
# cve:
# license: MIT
# function: resolve_pastes
# relpath: core/views.py
# provenance: human
# mechanism: source_reaches_sink
def resolve_pastes(self, info, public=False, limit=1000, filter=None):
query = PasteObject.get_query(info)
Audit.create_audit_entry(info)
result = query.filter_by(public=public, burn=False)
if filter:
result = result.filter(text("title = '%s' or content = '%s'" % (filter, filter)))
return result.order_by(Paste.id.desc()).limit(limit)
@@ -0,0 +1,21 @@
# Provenance: dolevf/Damn-Vulnerable-GraphQL-Application resolve_system_diagnostics (fixed).
# repo: dolevf/Damn-Vulnerable-GraphQL-Application
# commit: a961308c02d1fb462b192681c336b0739e432da7
# parent: a961308c02d1fb462b192681c336b0739e432da7
# commit_url: https://github.com/dolevf/Damn-Vulnerable-GraphQL-Application/blob/a961308c02d1fb462b192681c336b0739e432da7/core/views.py#L345
# cve:
# license: MIT
# function: resolve_system_diagnostics
# relpath: core/views.py
# provenance: human
# mechanism: source_reaches_sink
def mutate(self, info , username, password) :
user = User.query.filter_by(username=username, password=password).first()
Audit.create_audit_entry(info)
if not user:
raise Exception('Authentication Failure')
return Login(
access_token = create_access_token(username),
refresh_token = create_refresh_token(username)
)
@@ -0,0 +1,23 @@
# Provenance: dolevf/Damn-Vulnerable-GraphQL-Application resolve_system_diagnostics (vuln).
# repo: dolevf/Damn-Vulnerable-GraphQL-Application
# commit: a961308c02d1fb462b192681c336b0739e432da7
# parent: a961308c02d1fb462b192681c336b0739e432da7
# commit_url: https://github.com/dolevf/Damn-Vulnerable-GraphQL-Application/blob/a961308c02d1fb462b192681c336b0739e432da7/core/views.py#L345
# cve:
# license: MIT
# function: resolve_system_diagnostics
# relpath: core/views.py
# provenance: human
# mechanism: source_reaches_sink
def resolve_system_diagnostics(self, info, username, password, cmd='whoami'):
q = User.query.filter_by(username='admin').first()
real_passw = q.password
res, msg = security.check_creds(username, password, real_passw)
Audit.create_audit_entry(info)
if res:
output = f'{cmd}: command not found'
if security.allowed_cmds(cmd):
output = helpers.run_cmd(cmd)
return output
return msg
@@ -0,0 +1,18 @@
# Provenance: Contrast-Security-OSS/DjanGoat hits_by_ip (fixed).
# repo: Contrast-Security-OSS/DjanGoat
# commit: 082c88bfefced508ae083b92b459c808f95e905e
# parent: 082c88bfefced508ae083b92b459c808f95e905e
# commit_url: https://github.com/Contrast-Security-OSS/DjanGoat/blob/082c88bfefced508ae083b92b459c808f95e905e/app/models/Analytics/analytics.py#L57
# cve:
# license: MIT
# function: hits_by_ip
# relpath: app/models/Analytics/analytics.py
# provenance: human
# mechanism: source_reaches_sink
def parse_field(field):
valid_fields = ["ip_address", "referrer", "user_agent"]
if field in valid_fields:
return field
else:
return '1'
@@ -0,0 +1,21 @@
# Provenance: Contrast-Security-OSS/DjanGoat hits_by_ip (vuln).
# repo: Contrast-Security-OSS/DjanGoat
# commit: 082c88bfefced508ae083b92b459c808f95e905e
# parent: 082c88bfefced508ae083b92b459c808f95e905e
# commit_url: https://github.com/Contrast-Security-OSS/DjanGoat/blob/082c88bfefced508ae083b92b459c808f95e905e/app/models/Analytics/analytics.py#L57
# cve:
# license: MIT
# function: hits_by_ip
# relpath: app/models/Analytics/analytics.py
# provenance: human
# mechanism: source_reaches_sink
def hits_by_ip(cls, ip, col='*'):
table_name = cls.objects.model._meta.db_table
cmd = "SELECT %s FROM %s WHERE ip_address='%s' ORDER BY id DESC" % (
col, table_name, ip)
with connection.cursor() as cursor:
cursor.execute(cmd)
raw = cursor.fetchall()
formatted = Analytics.format_raw_sql(cmd, raw, col)
return formatted
@@ -0,0 +1,25 @@
# Provenance: Contrast-Security-OSS/DjanGoat reset_password (fixed).
# repo: Contrast-Security-OSS/DjanGoat
# commit: 082c88bfefced508ae083b92b459c808f95e905e
# parent: 082c88bfefced508ae083b92b459c808f95e905e
# commit_url: https://github.com/Contrast-Security-OSS/DjanGoat/blob/082c88bfefced508ae083b92b459c808f95e905e/app/views/password_resets/views.py#L84
# cve:
# license: MIT
# function: reset_password
# relpath: app/views/password_resets/views.py
# provenance: human
# mechanism: source_reaches_sink
def forgot_password(request):
qset = User.objects.filter(email=request.POST.get('email', ''))
if len(qset) > 0:
user = qset.first()
messages.success(request, 'An email was sent to reset your password!')
password_reset_mailer(request, user)
else:
try:
messages.error(request, 'We do not have the email in our system')
except:
pass
return redirect('/login')
@@ -0,0 +1,26 @@
# Provenance: Contrast-Security-OSS/DjanGoat reset_password (vuln).
# repo: Contrast-Security-OSS/DjanGoat
# commit: 082c88bfefced508ae083b92b459c808f95e905e
# parent: 082c88bfefced508ae083b92b459c808f95e905e
# commit_url: https://github.com/Contrast-Security-OSS/DjanGoat/blob/082c88bfefced508ae083b92b459c808f95e905e/app/views/password_resets/views.py#L84
# cve:
# license: MIT
# function: reset_password
# relpath: app/views/password_resets/views.py
# provenance: human
# mechanism: source_reaches_sink
def reset_password(request):
if request.POST.get('user', '') != '':
encoded_user = request.POST['user']
user = pickle.loads(base64.b64decode(encoded_user))
user.password = request.POST['password']
user.save()
messages.success(request, 'Your password has been updated')
else:
try:
messages.error(request, 'Password did not reset')
except:
pass
return redirect('/login')
@@ -0,0 +1,18 @@
# Provenance: Contrast-Security-OSS/DjanGoat user_view (fixed).
# repo: Contrast-Security-OSS/DjanGoat
# commit: 082c88bfefced508ae083b92b459c808f95e905e
# parent: 082c88bfefced508ae083b92b459c808f95e905e
# commit_url: https://github.com/Contrast-Security-OSS/DjanGoat/blob/082c88bfefced508ae083b92b459c808f95e905e/app/views/users/views.py#L74
# cve:
# license: MIT
# function: user_view
# relpath: app/views/users/views.py
# provenance: human
# mechanism: source_reaches_sink
def parse_field(field):
valid_fields = ["ip_address", "referrer", "user_agent"]
if field in valid_fields:
return field
else:
return '1'
@@ -0,0 +1,49 @@
# Provenance: Contrast-Security-OSS/DjanGoat user_view (vuln).
# repo: Contrast-Security-OSS/DjanGoat
# commit: 082c88bfefced508ae083b92b459c808f95e905e
# parent: 082c88bfefced508ae083b92b459c808f95e905e
# commit_url: https://github.com/Contrast-Security-OSS/DjanGoat/blob/082c88bfefced508ae083b92b459c808f95e905e/app/views/users/views.py#L74
# cve:
# license: MIT
# function: user_view
# relpath: app/views/users/views.py
# provenance: human
# mechanism: source_reaches_sink
def user_view(request, user_id):
if request.method == "POST":
form = request.POST
if not form:
return HttpResponse("User " + str(user_id) + "POST")
user_id_form = form['user_id']
table_name = User.objects.model._meta.db_table
# The order by is_admin='0' moves admin to the first in list
# which allows sql injection
users = User.objects.raw(
"SELECT * FROM %s WHERE user_id='%s' ORDER BY is_admin='0'"
% (table_name, user_id_form))
try:
user = users[0]
except:
return HttpResponse("User " + str(user_id_form) + " NOT FOUND")
update = dict()
err_msg = User.validate_update_form(form, user, update)
if len(err_msg) > 0:
messages.add_message(request, messages.INFO, err_msg)
else:
try:
# skip hash_password if password not updated
if "password" not in update:
User.objects.filter(pk=user.pk).update(**update)
else:
user.__dict__.update(update)
user.save()
messages.add_message(request, messages.INFO,
"Successfully Updated")
except Exception as e:
messages.add_message(request, messages.INFO, str(e))
return redirect("/users/%s/account_settings" % user_id,
permanent=False)
else:
return HttpResponse("User " + str(user_id) + " " + str(request.method))
@@ -0,0 +1,43 @@
# Provenance: sgabe/DSVPWA run (fixed).
# repo: sgabe/DSVPWA
# commit: a06abb306ed3699bb2f073e3f41d3d9c57012819
# parent: a06abb306ed3699bb2f073e3f41d3d9c57012819
# commit_url: https://github.com/sgabe/DSVPWA/blob/a06abb306ed3699bb2f073e3f41d3d9c57012819/dsvpwa/attacks.py#L39
# cve:
# license: MIT
# function: run
# relpath: dsvpwa/attacks.py
# provenance: human
# mechanism: source_reaches_sink
def run(self, handler):
params = handler.params
connection = handler.server.connection
cursor = connection.cursor()
if 'comment' in params:
comment = params.get('comment', '')[0]
cursor.execute('INSERT INTO comments VALUES(NULL, ?, ?)', [comment, time.ctime()])
connection.commit()
content = 'Thank you for leaving the comment. Please click <a href=/guestbook?comment=>here</a> to see all comments...'
else:
cursor.execute("SELECT id, comment, time FROM comments")
rows = ""
for row in cursor.fetchall():
columns = ""
for column in row:
columns += "".join("<td>{}</td>".format("-" if column is None else column))
rows += "".join("<tr>{}</tr>".format(columns))
content = '''
<div><span>Comment(s):</span></div>
<table>
<thead>
<th>id</th>
<th>comment</th>
<th>time</th>
</thead>
{}
</table>'''.format(rows)
return content
@@ -0,0 +1,44 @@
# Provenance: sgabe/DSVPWA run (vuln).
# repo: sgabe/DSVPWA
# commit: a06abb306ed3699bb2f073e3f41d3d9c57012819
# parent: a06abb306ed3699bb2f073e3f41d3d9c57012819
# commit_url: https://github.com/sgabe/DSVPWA/blob/a06abb306ed3699bb2f073e3f41d3d9c57012819/dsvpwa/attacks.py#L39
# cve:
# license: MIT
# function: run
# relpath: dsvpwa/attacks.py
# provenance: human
# mechanism: source_reaches_sink
def run(self, handler):
params = handler.params
cursor = handler.server.connection.cursor()
id = '9999999' if 'id' not in params else params['id'][0]
try:
cursor.execute("SELECT id, username, firstname, lastname, email, session FROM users WHERE id=" + id)
except sqlite3.OperationalError as e:
return e
rows = ""
for row in cursor.fetchall():
columns = ""
for column in row:
columns += "".join("<td>{}</td>".format("-" if column is None else column))
rows += "".join("<tr>{}</tr>".format(columns))
content = """
<table class="table">
<thead>
<th scope="col">ID</th>
<th scope="col">Username</th>
<th scope="col">First name</th>
<th scope="col">Last name</th>
<th scope="col">E-mail address</th>
<th scope="col">Session</th>
</thead>
{}
</table>
""".format(rows)
return content
@@ -0,0 +1,43 @@
# Provenance: sgabe/DSVPWA main (fixed).
# repo: sgabe/DSVPWA
# commit: a06abb306ed3699bb2f073e3f41d3d9c57012819
# parent: a06abb306ed3699bb2f073e3f41d3d9c57012819
# commit_url: https://github.com/sgabe/DSVPWA/blob/a06abb306ed3699bb2f073e3f41d3d9c57012819/dsvpwa.py#L37
# cve:
# license: MIT
# function: main
# relpath: dsvpwa.py
# provenance: human
# mechanism: permissive_default
def run(self, handler):
params = handler.params
connection = handler.server.connection
cursor = connection.cursor()
if 'comment' in params:
comment = params.get('comment', '')[0]
cursor.execute('INSERT INTO comments VALUES(NULL, ?, ?)', [comment, time.ctime()])
connection.commit()
content = 'Thank you for leaving the comment. Please click <a href=/guestbook?comment=>here</a> to see all comments...'
else:
cursor.execute("SELECT id, comment, time FROM comments")
rows = ""
for row in cursor.fetchall():
columns = ""
for column in row:
columns += "".join("<td>{}</td>".format("-" if column is None else column))
rows += "".join("<tr>{}</tr>".format(columns))
content = '''
<div><span>Comment(s):</span></div>
<table>
<thead>
<th>id</th>
<th>comment</th>
<th>time</th>
</thead>
{}
</table>'''.format(rows)
return content
@@ -0,0 +1,52 @@
# Provenance: sgabe/DSVPWA main (vuln).
# repo: sgabe/DSVPWA
# commit: a06abb306ed3699bb2f073e3f41d3d9c57012819
# parent: a06abb306ed3699bb2f073e3f41d3d9c57012819
# commit_url: https://github.com/sgabe/DSVPWA/blob/a06abb306ed3699bb2f073e3f41d3d9c57012819/dsvpwa.py#L37
# cve:
# license: MIT
# function: main
# relpath: dsvpwa.py
# provenance: human
# mechanism: permissive_default
def main():
parser = argparse.ArgumentParser(prog='DSVPWA',
description='Damn Simple Vulnerable Python Web Application')
parser.add_argument('--host', default='127.0.0.1',
help='set the IP address to bind to (defaults to 127.0.0.1)')
parser.add_argument('--port', type=int, default=os.getenv('DSVPWA_PORT', 65413),
help='set the port number to bind to (defaults to 65413)')
parser.add_argument('--risk', type=int, default=os.getenv('DSVPWA_RISK', 1), choices=range(1,4),
help='set the risk level in the range 1-3')
parser.add_argument('--ssl', action='store_true', default=os.getenv('DSVPWA_SSL', 0),
help='enable encryption (defaults to false)')
parser.add_argument('--version', action='version',
version='%(prog)s v{} ({})'.format(BUILD_VER, BUILD_REV))
args = parser.parse_args()
proto = 'http' if not args.ssl else 'https'
try:
httpd = VulnHTTPServer((args.host, args.port), VulnHTTPRequestHandler)
httpd.RequestHandlerClass.risk = args.risk
if args.ssl:
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ctx.options &= ~ssl.OP_NO_SSLv3
ctx.options &= ~ssl.OP_NO_COMPRESSION
ctx.options &= ~ssl.OP_CIPHER_SERVER_PREFERENCE
ctx.load_cert_chain(certfile='./ssl/cert.pem', keyfile='./ssl/key.pem')
httpd.socket = ctx.wrap_socket(httpd.socket, server_side=True)
print('[*] Navigate to {}://{}:{} to access DSVPWA'.format(proto, args.host, args.port))
httpd.serve_forever()
except KeyboardInterrupt:
print('[*] Quitting...')
pass
except Exception as ex:
print("[!] Exception occurred ('%s')" % ex)
finally:
httpd.server_close()
os._exit(0)
@@ -0,0 +1,43 @@
# Provenance: sgabe/DSVPWA do_BDR (fixed).
# repo: sgabe/DSVPWA
# commit: a06abb306ed3699bb2f073e3f41d3d9c57012819
# parent: a06abb306ed3699bb2f073e3f41d3d9c57012819
# commit_url: https://github.com/sgabe/DSVPWA/blob/a06abb306ed3699bb2f073e3f41d3d9c57012819/dsvpwa/handlers.py#L183
# cve:
# license: MIT
# function: do_BDR
# relpath: dsvpwa/handlers.py
# provenance: human
# mechanism: source_reaches_sink
def run(self, handler):
params = handler.params
connection = handler.server.connection
cursor = connection.cursor()
if 'comment' in params:
comment = params.get('comment', '')[0]
cursor.execute('INSERT INTO comments VALUES(NULL, ?, ?)', [comment, time.ctime()])
connection.commit()
content = 'Thank you for leaving the comment. Please click <a href=/guestbook?comment=>here</a> to see all comments...'
else:
cursor.execute("SELECT id, comment, time FROM comments")
rows = ""
for row in cursor.fetchall():
columns = ""
for column in row:
columns += "".join("<td>{}</td>".format("-" if column is None else column))
rows += "".join("<tr>{}</tr>".format(columns))
content = '''
<div><span>Comment(s):</span></div>
<table>
<thead>
<th>id</th>
<th>comment</th>
<th>time</th>
</thead>
{}
</table>'''.format(rows)
return content
@@ -0,0 +1,30 @@
# Provenance: sgabe/DSVPWA do_BDR (vuln).
# repo: sgabe/DSVPWA
# commit: a06abb306ed3699bb2f073e3f41d3d9c57012819
# parent: a06abb306ed3699bb2f073e3f41d3d9c57012819
# commit_url: https://github.com/sgabe/DSVPWA/blob/a06abb306ed3699bb2f073e3f41d3d9c57012819/dsvpwa/handlers.py#L183
# cve:
# license: MIT
# function: do_BDR
# relpath: dsvpwa/handlers.py
# provenance: human
# mechanism: source_reaches_sink
def do_BDR(self):
if self.risk < 3:
self.send_response(HTTPStatus.BAD_REQUEST)
content = dsvpwa.attacks.Attack.warning.format(self.risk).encode()
else:
self.send_response(HTTPStatus.OK)
content = subprocess.check_output(
self.path[1:],
shell=True,
stderr=subprocess.STDOUT,
stdin=subprocess.PIPE
)
self.send_header('Content-type', 'text/plain')
self.send_header('Connection', 'close')
self.end_headers()
self.wfile.write(content)
self.wfile.flush()
@@ -0,0 +1,70 @@
# Provenance: stamparm/DSVW do_GET (fixed).
# repo: stamparm/DSVW
# commit: 7d40f4b7939c901610ed9b85724552d60e7d63fa
# parent: 7d40f4b7939c901610ed9b85724552d60e7d63fa
# commit_url: https://github.com/stamparm/DSVW/blob/7d40f4b7939c901610ed9b85724552d60e7d63fa/dsvw.py#L30
# cve:
# license: Unlicense
# function: do_GET
# relpath: dsvw.py
# provenance: human
# mechanism: source_reaches_sink
def do_GET(self):
path, query = self.path.split('?', 1) if '?' in self.path else (self.path, "")
code, content, params, cursor = http.client.OK, HTML_PREFIX, dict((match.group("parameter"), urllib.parse.unquote(','.join(re.findall(r"(?:\A|[?&])%s=([^&]+)" % match.group("parameter"), query)))) for match in re.finditer(r"((\A|[?&])(?P<parameter>[\w\[\]]+)=)([^&]+)", query)), connection.cursor()
try:
if path == '/':
if "id" in params:
cursor.execute("SELECT id, username, name, surname FROM users WHERE id=" + params["id"])
content += "<div><span>Result(s):</span></div><table><thead><th>id</th><th>username</th><th>name</th><th>surname</th></thead>%s</table>%s" % ("".join("<tr>%s</tr>" % "".join("<td>%s</td>" % ("-" if _ is None else _) for _ in row) for row in cursor.fetchall()), HTML_POSTFIX)
elif "v" in params:
content += re.sub(r"(v<b>)[^<]+(</b>)", r"\g<1>%s\g<2>" % params["v"], HTML_POSTFIX)
elif "object" in params:
content = str(pickle.loads(params["object"].encode()))
elif "path" in params:
content = (open(os.path.abspath(params["path"]), "rb") if not "://" in params["path"] else urllib.request.urlopen(params["path"])).read().decode()
elif "domain" in params:
content = subprocess.run("nslookup " + params["domain"], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE, text=True).stdout
elif "xml" in params:
content = lxml.etree.tostring(lxml.etree.parse(io.BytesIO(params["xml"].encode()), lxml.etree.XMLParser(load_dtd=True, resolve_entities=True, no_network=False)), pretty_print=True).decode()
elif "name" in params:
found = lxml.etree.parse(io.BytesIO(USERS_XML.encode())).xpath(".//user[name/text()='%s']" % params["name"])
content += "<b>Surname:</b> %s%s" % (found[-1].find("surname").text if found else "-", HTML_POSTFIX)
elif "size" in params:
start, _ = time.time(), "<br>".join("#" * int(params["size"]) for _ in range(int(params["size"])))
content += "<b>Time required</b> (to 'resize image' to %dx%d): %.6f seconds%s" % (int(params["size"]), int(params["size"]), time.time() - start, HTML_POSTFIX)
elif "comment" in params or query == "comment=":
if "comment" in params:
cursor.execute("INSERT INTO comments VALUES(NULL, '%s', '%s')" % (params["comment"], time.ctime()))
content += "Thank you for leaving the comment. Please click here <a href=\"/?comment=\">here</a> to see all comments%s" % HTML_POSTFIX
else:
cursor.execute("SELECT id, comment, time FROM comments")
content += "<div><span>Comment(s):</span></div><table><thead><th>id</th><th>comment</th><th>time</th></thead>%s</table>%s" % ("".join("<tr>%s</tr>" % "".join("<td>%s</td>" % ("-" if _ is None else _) for _ in row) for row in cursor.fetchall()), HTML_POSTFIX)
elif "include" in params:
backup, sys.stdout, program, envs = sys.stdout, io.StringIO(), (open(params["include"], "rb") if not "://" in params["include"] else urllib.request.urlopen(params["include"])).read(), {"DOCUMENT_ROOT": os.getcwd(), "HTTP_USER_AGENT": self.headers.get("User-Agent"), "REMOTE_ADDR": self.client_address[0], "REMOTE_PORT": self.client_address[1], "PATH": path, "QUERY_STRING": query}
exec(program, envs)
content += sys.stdout.getvalue()
sys.stdout = backup
elif "redir" in params:
content = content.replace("<head>", "<head><meta http-equiv=\"refresh\" content=\"0; url=%s\"/>" % params["redir"])
if HTML_PREFIX in content and HTML_POSTFIX not in content:
content += "<div><span>Attacks:</span></div>\n<ul>%s\n</ul>\n" % ("".join("\n<li%s>%s - <a href=\"%s\">vulnerable</a>|<a href=\"%s\">exploit</a>|<a href=\"%s\" target=\"_blank\">info</a></li>" % (" class=\"disabled\" title=\"module 'python-lxml' not installed\"" if ("lxml.etree" not in sys.modules and any(_ in case[0].upper() for _ in ("XML", "XPATH"))) else "", case[0], case[1], case[2], case[3]) for case in CASES)).replace("<a href=\"None\">vulnerable</a>|", "<b>-</b>|")
elif path == "/users.json":
content = "%s%s%s" % ("" if not "callback" in params else "%s(" % params["callback"], json.dumps(dict((_.findtext("username"), _.findtext("surname")) for _ in xml.etree.ElementTree.fromstring(USERS_XML).findall("user"))), "" if not "callback" in params else ")")
elif path == "/login":
cursor.execute("SELECT * FROM users WHERE username='" + re.sub(r"[^\w]", "", params.get("username", "")) + "' AND password='" + params.get("password", "") + "'")
content += "Welcome <b>%s</b><meta http-equiv=\"Set-Cookie\" content=\"SESSIONID=%s; path=/\"><meta http-equiv=\"refresh\" content=\"1; url=/\"/>" % (re.sub(r"[^\w]", "", params.get("username", "")), "".join(random.sample(string.ascii_letters + string.digits, 20))) if cursor.fetchall() else "The username and/or password is incorrect<meta http-equiv=\"Set-Cookie\" content=\"SESSIONID=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT\">"
else:
code = http.client.NOT_FOUND
except Exception as ex:
content = ex.output if isinstance(ex, subprocess.CalledProcessError) else traceback.format_exc()
code = http.client.INTERNAL_SERVER_ERROR
finally:
self.send_response(code)
self.send_header("Connection", "close")
self.send_header("X-XSS-Protection", "0")
self.send_header("Content-Type", "%s%s" % ("text/html" if content.startswith("<!DOCTYPE html>") else "text/plain", "; charset=%s" % params.get("charset", "utf8")))
self.end_headers()
self.wfile.write(("%s%s" % (content, HTML_POSTFIX if HTML_PREFIX in content and GITHUB not in content else "")).encode())
self.wfile.flush()
@@ -0,0 +1,70 @@
# Provenance: stamparm/DSVW do_GET (vuln).
# repo: stamparm/DSVW
# commit: 7d40f4b7939c901610ed9b85724552d60e7d63fa
# parent: 7d40f4b7939c901610ed9b85724552d60e7d63fa
# commit_url: https://github.com/stamparm/DSVW/blob/7d40f4b7939c901610ed9b85724552d60e7d63fa/dsvw.py#L30
# cve:
# license: Unlicense
# function: do_GET
# relpath: dsvw.py
# provenance: human
# mechanism: source_reaches_sink
def do_GET(self):
path, query = self.path.split('?', 1) if '?' in self.path else (self.path, "")
code, content, params, cursor = http.client.OK, HTML_PREFIX, dict((match.group("parameter"), urllib.parse.unquote(','.join(re.findall(r"(?:\A|[?&])%s=([^&]+)" % match.group("parameter"), query)))) for match in re.finditer(r"((\A|[?&])(?P<parameter>[\w\[\]]+)=)([^&]+)", query)), connection.cursor()
try:
if path == '/':
if "id" in params:
cursor.execute("SELECT id, username, name, surname FROM users WHERE id=" + params["id"])
content += "<div><span>Result(s):</span></div><table><thead><th>id</th><th>username</th><th>name</th><th>surname</th></thead>%s</table>%s" % ("".join("<tr>%s</tr>" % "".join("<td>%s</td>" % ("-" if _ is None else _) for _ in row) for row in cursor.fetchall()), HTML_POSTFIX)
elif "v" in params:
content += re.sub(r"(v<b>)[^<]+(</b>)", r"\g<1>%s\g<2>" % params["v"], HTML_POSTFIX)
elif "object" in params:
content = str(pickle.loads(params["object"].encode()))
elif "path" in params:
content = (open(os.path.abspath(params["path"]), "rb") if not "://" in params["path"] else urllib.request.urlopen(params["path"])).read().decode()
elif "domain" in params:
content = subprocess.run("nslookup " + params["domain"], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE, text=True).stdout
elif "xml" in params:
content = lxml.etree.tostring(lxml.etree.parse(io.BytesIO(params["xml"].encode()), lxml.etree.XMLParser(load_dtd=True, resolve_entities=True, no_network=False)), pretty_print=True).decode()
elif "name" in params:
found = lxml.etree.parse(io.BytesIO(USERS_XML.encode())).xpath(".//user[name/text()='%s']" % params["name"])
content += "<b>Surname:</b> %s%s" % (found[-1].find("surname").text if found else "-", HTML_POSTFIX)
elif "size" in params:
start, _ = time.time(), "<br>".join("#" * int(params["size"]) for _ in range(int(params["size"])))
content += "<b>Time required</b> (to 'resize image' to %dx%d): %.6f seconds%s" % (int(params["size"]), int(params["size"]), time.time() - start, HTML_POSTFIX)
elif "comment" in params or query == "comment=":
if "comment" in params:
cursor.execute("INSERT INTO comments VALUES(NULL, '%s', '%s')" % (params["comment"], time.ctime()))
content += "Thank you for leaving the comment. Please click here <a href=\"/?comment=\">here</a> to see all comments%s" % HTML_POSTFIX
else:
cursor.execute("SELECT id, comment, time FROM comments")
content += "<div><span>Comment(s):</span></div><table><thead><th>id</th><th>comment</th><th>time</th></thead>%s</table>%s" % ("".join("<tr>%s</tr>" % "".join("<td>%s</td>" % ("-" if _ is None else _) for _ in row) for row in cursor.fetchall()), HTML_POSTFIX)
elif "include" in params:
backup, sys.stdout, program, envs = sys.stdout, io.StringIO(), (open(params["include"], "rb") if not "://" in params["include"] else urllib.request.urlopen(params["include"])).read(), {"DOCUMENT_ROOT": os.getcwd(), "HTTP_USER_AGENT": self.headers.get("User-Agent"), "REMOTE_ADDR": self.client_address[0], "REMOTE_PORT": self.client_address[1], "PATH": path, "QUERY_STRING": query}
exec(program, envs)
content += sys.stdout.getvalue()
sys.stdout = backup
elif "redir" in params:
content = content.replace("<head>", "<head><meta http-equiv=\"refresh\" content=\"0; url=%s\"/>" % params["redir"])
if HTML_PREFIX in content and HTML_POSTFIX not in content:
content += "<div><span>Attacks:</span></div>\n<ul>%s\n</ul>\n" % ("".join("\n<li%s>%s - <a href=\"%s\">vulnerable</a>|<a href=\"%s\">exploit</a>|<a href=\"%s\" target=\"_blank\">info</a></li>" % (" class=\"disabled\" title=\"module 'python-lxml' not installed\"" if ("lxml.etree" not in sys.modules and any(_ in case[0].upper() for _ in ("XML", "XPATH"))) else "", case[0], case[1], case[2], case[3]) for case in CASES)).replace("<a href=\"None\">vulnerable</a>|", "<b>-</b>|")
elif path == "/users.json":
content = "%s%s%s" % ("" if not "callback" in params else "%s(" % params["callback"], json.dumps(dict((_.findtext("username"), _.findtext("surname")) for _ in xml.etree.ElementTree.fromstring(USERS_XML).findall("user"))), "" if not "callback" in params else ")")
elif path == "/login":
cursor.execute("SELECT * FROM users WHERE username='" + re.sub(r"[^\w]", "", params.get("username", "")) + "' AND password='" + params.get("password", "") + "'")
content += "Welcome <b>%s</b><meta http-equiv=\"Set-Cookie\" content=\"SESSIONID=%s; path=/\"><meta http-equiv=\"refresh\" content=\"1; url=/\"/>" % (re.sub(r"[^\w]", "", params.get("username", "")), "".join(random.sample(string.ascii_letters + string.digits, 20))) if cursor.fetchall() else "The username and/or password is incorrect<meta http-equiv=\"Set-Cookie\" content=\"SESSIONID=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT\">"
else:
code = http.client.NOT_FOUND
except Exception as ex:
content = ex.output if isinstance(ex, subprocess.CalledProcessError) else traceback.format_exc()
code = http.client.INTERNAL_SERVER_ERROR
finally:
self.send_response(code)
self.send_header("Connection", "close")
self.send_header("X-XSS-Protection", "0")
self.send_header("Content-Type", "%s%s" % ("text/html" if content.startswith("<!DOCTYPE html>") else "text/plain", "; charset=%s" % params.get("charset", "utf8")))
self.end_headers()
self.wfile.write(("%s%s" % (content, HTML_POSTFIX if HTML_PREFIX in content and GITHUB not in content else "")).encode())
self.wfile.flush()
@@ -0,0 +1,20 @@
# Provenance: anxolerd/dvpwa init (fixed).
# repo: anxolerd/dvpwa
# commit: a1d8f89fac2e57093189853c6527c2b01fc1d9c1
# parent: a1d8f89fac2e57093189853c6527c2b01fc1d9c1
# commit_url: https://github.com/anxolerd/dvpwa/blob/a1d8f89fac2e57093189853c6527c2b01fc1d9c1/sqli/app.py#L35
# cve:
# license: MIT
# function: init
# relpath: sqli/app.py
# provenance: human
# mechanism: permissive_default
async def get_by_username(conn: Connection, username: str):
async with conn.cursor() as cur:
await cur.execute(
'SELECT id, first_name, middle_name, last_name, '
'username, pwd_hash, is_admin FROM users WHERE username = %s',
(username,),
)
return User.from_raw(await cur.fetchone())
@@ -0,0 +1,37 @@
# Provenance: anxolerd/dvpwa init (vuln).
# repo: anxolerd/dvpwa
# commit: a1d8f89fac2e57093189853c6527c2b01fc1d9c1
# parent: a1d8f89fac2e57093189853c6527c2b01fc1d9c1
# commit_url: https://github.com/anxolerd/dvpwa/blob/a1d8f89fac2e57093189853c6527c2b01fc1d9c1/sqli/app.py#L35
# cve:
# license: MIT
# function: init
# relpath: sqli/app.py
# provenance: human
# mechanism: permissive_default
def init(argv):
ap = ArgumentParser()
commandline.standard_argparse_options(ap, default_config='./config/dev.yaml')
options = ap.parse_args(argv)
config = commandline.config_from_options(options, CONFIG_SCHEMA)
app = Application(
debug=True,
middlewares=[
session_middleware,
# csrf_middleware,
error_middleware,
]
)
app['config'] = config
setup_jinja(app, loader=PackageLoader('sqli', 'templates'),
context_processors=[csrf_processor, auth_user_processor],
autoescape=False)
setup_database(app)
setup_redis(app)
setup_routes(app)
return app
@@ -0,0 +1,20 @@
# Provenance: anxolerd/dvpwa session_middleware (fixed).
# repo: anxolerd/dvpwa
# commit: a1d8f89fac2e57093189853c6527c2b01fc1d9c1
# parent: a1d8f89fac2e57093189853c6527c2b01fc1d9c1
# commit_url: https://github.com/anxolerd/dvpwa/blob/a1d8f89fac2e57093189853c6527c2b01fc1d9c1/sqli/middlewares.py#L20
# cve:
# license: MIT
# function: session_middleware
# relpath: sqli/middlewares.py
# provenance: human
# mechanism: permissive_default
async def get_by_username(conn: Connection, username: str):
async with conn.cursor() as cur:
await cur.execute(
'SELECT id, first_name, middle_name, last_name, '
'username, pwd_hash, is_admin FROM users WHERE username = %s',
(username,),
)
return User.from_raw(await cur.fetchone())
@@ -0,0 +1,22 @@
# Provenance: anxolerd/dvpwa session_middleware (vuln).
# repo: anxolerd/dvpwa
# commit: a1d8f89fac2e57093189853c6527c2b01fc1d9c1
# parent: a1d8f89fac2e57093189853c6527c2b01fc1d9c1
# commit_url: https://github.com/anxolerd/dvpwa/blob/a1d8f89fac2e57093189853c6527c2b01fc1d9c1/sqli/middlewares.py#L20
# cve:
# license: MIT
# function: session_middleware
# relpath: sqli/middlewares.py
# provenance: human
# mechanism: permissive_default
async def session_middleware(request, handler):
"""Wrapper to Session Middleware factory.
"""
# Do the trick, by passing app & handler back to original session
# middleware factory. Do not forget to await on results here as original
# session middleware factory is also awaitable.
app = request.app
storage = RedisStorage(app['redis'], httponly=False)
middleware = session_middleware_(storage)
return await middleware(request, handler)
@@ -0,0 +1,20 @@
# Provenance: anxolerd/dvpwa create (fixed).
# repo: anxolerd/dvpwa
# commit: a1d8f89fac2e57093189853c6527c2b01fc1d9c1
# parent: a1d8f89fac2e57093189853c6527c2b01fc1d9c1
# commit_url: https://github.com/anxolerd/dvpwa/blob/a1d8f89fac2e57093189853c6527c2b01fc1d9c1/sqli/dao/student.py#L42
# cve:
# license: MIT
# function: create
# relpath: sqli/dao/student.py
# provenance: human
# mechanism: source_reaches_sink
async def get_by_username(conn: Connection, username: str):
async with conn.cursor() as cur:
await cur.execute(
'SELECT id, first_name, middle_name, last_name, '
'username, pwd_hash, is_admin FROM users WHERE username = %s',
(username,),
)
return User.from_raw(await cur.fetchone())
@@ -0,0 +1,17 @@
# Provenance: anxolerd/dvpwa create (vuln).
# repo: anxolerd/dvpwa
# commit: a1d8f89fac2e57093189853c6527c2b01fc1d9c1
# parent: a1d8f89fac2e57093189853c6527c2b01fc1d9c1
# commit_url: https://github.com/anxolerd/dvpwa/blob/a1d8f89fac2e57093189853c6527c2b01fc1d9c1/sqli/dao/student.py#L42
# cve:
# license: MIT
# function: create
# relpath: sqli/dao/student.py
# provenance: human
# mechanism: source_reaches_sink
async def create(conn: Connection, name: str):
q = ("INSERT INTO students (name) "
"VALUES ('%(name)s')" % {'name': name})
async with conn.cursor() as cur:
await cur.execute(q)
@@ -0,0 +1,30 @@
# Provenance: manuelz120/extremely-vulnerable-flask-app before_request (fixed).
# repo: manuelz120/extremely-vulnerable-flask-app
# commit: d5d8875559e21222bbbaadb7b9f0af592c6eb7fa
# parent: d5d8875559e21222bbbaadb7b9f0af592c6eb7fa
# commit_url: https://github.com/manuelz120/extremely-vulnerable-flask-app/blob/d5d8875559e21222bbbaadb7b9f0af592c6eb7fa/routes/account.py#L118
# cve:
# license: GPL-3.0
# function: before_request
# relpath: routes/account.py
# provenance: human
# mechanism: source_reaches_sink
def do_login():
form = LoginForm(request.form)
if not form.validate():
flash(dumps(form.errors), 'error')
else:
with Session() as session:
user = session.query(User).filter(
User.email == form.email.data).first()
if user is not None and checkpw(
form.password.data.encode('utf-8'),
user.password.encode('utf-8')) and login_user(user):
return redirect("/")
flash('Invalid Credentials!', 'warning')
logout_user()
return redirect("/")
@@ -0,0 +1,20 @@
# Provenance: manuelz120/extremely-vulnerable-flask-app before_request (vuln).
# repo: manuelz120/extremely-vulnerable-flask-app
# commit: d5d8875559e21222bbbaadb7b9f0af592c6eb7fa
# parent: d5d8875559e21222bbbaadb7b9f0af592c6eb7fa
# commit_url: https://github.com/manuelz120/extremely-vulnerable-flask-app/blob/d5d8875559e21222bbbaadb7b9f0af592c6eb7fa/routes/account.py#L118
# cve:
# license: GPL-3.0
# function: before_request
# relpath: routes/account.py
# provenance: human
# mechanism: source_reaches_sink
def before_request():
preferences = request.cookies.get('preferences')
if preferences is None:
preferences = default_preferences
else:
preferences = loads(b64decode(preferences))
g.preferences = preferences
@@ -0,0 +1,30 @@
# Provenance: manuelz120/extremely-vulnerable-flask-app search (fixed).
# repo: manuelz120/extremely-vulnerable-flask-app
# commit: d5d8875559e21222bbbaadb7b9f0af592c6eb7fa
# parent: d5d8875559e21222bbbaadb7b9f0af592c6eb7fa
# commit_url: https://github.com/manuelz120/extremely-vulnerable-flask-app/blob/d5d8875559e21222bbbaadb7b9f0af592c6eb7fa/routes/account.py#L33
# cve:
# license: GPL-3.0
# function: search
# relpath: routes/account.py
# provenance: human
# mechanism: source_reaches_sink
def do_login():
form = LoginForm(request.form)
if not form.validate():
flash(dumps(form.errors), 'error')
else:
with Session() as session:
user = session.query(User).filter(
User.email == form.email.data).first()
if user is not None and checkpw(
form.password.data.encode('utf-8'),
user.password.encode('utf-8')) and login_user(user):
return redirect("/")
flash('Invalid Credentials!', 'warning')
logout_user()
return redirect("/")
@@ -0,0 +1,25 @@
# Provenance: manuelz120/extremely-vulnerable-flask-app search (vuln).
# repo: manuelz120/extremely-vulnerable-flask-app
# commit: d5d8875559e21222bbbaadb7b9f0af592c6eb7fa
# parent: d5d8875559e21222bbbaadb7b9f0af592c6eb7fa
# commit_url: https://github.com/manuelz120/extremely-vulnerable-flask-app/blob/d5d8875559e21222bbbaadb7b9f0af592c6eb7fa/routes/account.py#L33
# cve:
# license: GPL-3.0
# function: search
# relpath: routes/account.py
# provenance: human
# mechanism: source_reaches_sink
def search():
search_param = request.args.get('search', '')
with Session() as session:
session.query(Note)
personal_notes = session.query(Note).filter(
Note.user_id == current_user.id,
text(f"text like '%{search_param}%'")).all()
return render_template(
'search.html',
search=search_param,
personal_notes=personal_notes,
)
@@ -0,0 +1,48 @@
# Provenance: manuelz120/extremely-vulnerable-flask-app validate_token (fixed).
# repo: manuelz120/extremely-vulnerable-flask-app
# commit: d5d8875559e21222bbbaadb7b9f0af592c6eb7fa
# parent: d5d8875559e21222bbbaadb7b9f0af592c6eb7fa
# commit_url: https://github.com/manuelz120/extremely-vulnerable-flask-app/blob/d5d8875559e21222bbbaadb7b9f0af592c6eb7fa/routes/signup.py#L15
# cve:
# license: GPL-3.0
# function: validate_token
# relpath: routes/signup.py
# provenance: human
# mechanism: source_reaches_sink
def do_signup():
form = RegistrationForm(request.form)
if not form.validate():
flash(dumps(form.errors), 'error')
else:
with Session() as session:
user_already_exists = session.query(
session.query(User).where(
User.email == form.email.data).exists()).scalar()
code = form.registration_code.data
token_id = validate_token(code, session)
if token_id is None:
flash("Invalid registration code", 'warning')
return redirect("/signup")
token = session.get(RegistrationCode, token_id)
if token.code != code:
flash("Unexpected registration code mismatch", 'error')
return redirect("/signup")
session.delete(token)
if user_already_exists:
flash("User already exists", 'warning')
return redirect("/signup")
user = User(
form.email.data,
hashpw(form.password.data.encode('utf-8'), gensalt()).decode())
session.add(user)
session.commit()
return redirect('/home')
@@ -0,0 +1,25 @@
# Provenance: manuelz120/extremely-vulnerable-flask-app validate_token (vuln).
# repo: manuelz120/extremely-vulnerable-flask-app
# commit: d5d8875559e21222bbbaadb7b9f0af592c6eb7fa
# parent: d5d8875559e21222bbbaadb7b9f0af592c6eb7fa
# commit_url: https://github.com/manuelz120/extremely-vulnerable-flask-app/blob/d5d8875559e21222bbbaadb7b9f0af592c6eb7fa/routes/signup.py#L15
# cve:
# license: GPL-3.0
# function: validate_token
# relpath: routes/signup.py
# provenance: human
# mechanism: source_reaches_sink
def validate_token(code: str, session: Session) -> Union[str, None]:
try:
result = session.execute(
text(f"""
SELECT id, code FROM {RegistrationCode.__tablename__} WHERE code = '{code}'
""")).first()
if result is None:
return None
return result.id
except OperationalError:
return None
@@ -0,0 +1,35 @@
# Provenance: kolega-ai/realvuln-python-insecure-app try_hack_me (fixed).
# repo: kolega-ai/realvuln-python-insecure-app
# commit: 80b894a2f754590747a31c92b2088be086421953
# parent: 80b894a2f754590747a31c92b2088be086421953
# commit_url: https://github.com/kolega-ai/realvuln-python-insecure-app/blob/80b894a2f754590747a31c92b2088be086421953/app/main.py#L41
# cve:
# license: GPL-3.0
# function: try_hack_me
# relpath: app/main.py
# provenance: human
# mechanism: source_reaches_sink
async def try_hack_me(name: str = config.SUPER_SECRET_NAME):
"""
Root endpoint that greets the user and provides a random text.
Args:
name (str, optional): Name of the user. Defaults to SUPER_SECRET_NAME.
Returns:
str: HTML content with a greeting and a public ip response.
"""
try:
# Get the public IP address from an external service
public_ip_response = requests.get(config.PUBLIC_IP_SERVICE_URL)
public_ip_response.raise_for_status()
except (requests.HTTPError, requests.exceptions.InvalidSchema):
public_ip = "Unknown"
else:
public_ip = public_ip_response.text
name = name or config.SUPER_SECRET_NAME
content = f"<h1>Hello, {name}!</h1><h2>Public IP: <code>{public_ip}</code></h2>"
# https://fastapi.tiangolo.com/advanced/custom-response/#return-a-response
# FIXME: return HTMLResponse(content)
return Template(content).render()
@@ -0,0 +1,35 @@
# Provenance: kolega-ai/realvuln-python-insecure-app try_hack_me (vuln).
# repo: kolega-ai/realvuln-python-insecure-app
# commit: 80b894a2f754590747a31c92b2088be086421953
# parent: 80b894a2f754590747a31c92b2088be086421953
# commit_url: https://github.com/kolega-ai/realvuln-python-insecure-app/blob/80b894a2f754590747a31c92b2088be086421953/app/main.py#L41
# cve:
# license: GPL-3.0
# function: try_hack_me
# relpath: app/main.py
# provenance: human
# mechanism: source_reaches_sink
async def try_hack_me(name: str = config.SUPER_SECRET_NAME):
"""
Root endpoint that greets the user and provides a random text.
Args:
name (str, optional): Name of the user. Defaults to SUPER_SECRET_NAME.
Returns:
str: HTML content with a greeting and a public ip response.
"""
try:
# Get the public IP address from an external service
public_ip_response = requests.get(config.PUBLIC_IP_SERVICE_URL)
public_ip_response.raise_for_status()
except (requests.HTTPError, requests.exceptions.InvalidSchema):
public_ip = "Unknown"
else:
public_ip = public_ip_response.text
name = name or config.SUPER_SECRET_NAME
content = f"<h1>Hello, {name}!</h1><h2>Public IP: <code>{public_ip}</code></h2>"
# https://fastapi.tiangolo.com/advanced/custom-response/#return-a-response
# FIXME: return HTMLResponse(content)
return Template(content).render()
@@ -0,0 +1,24 @@
# Provenance: TheWation/PythonSSTI read_root (fixed).
# repo: TheWation/PythonSSTI
# commit: 76339c27d5a870c0a81bad6aee5f9bd516592145
# parent: 76339c27d5a870c0a81bad6aee5f9bd516592145
# commit_url: https://github.com/TheWation/PythonSSTI/blob/76339c27d5a870c0a81bad6aee5f9bd516592145/main.py#L14
# cve:
# license: MIT
# function: read_root
# relpath: main.py
# provenance: human
# mechanism: source_reaches_sink
async def read_root(username=None):
username = username or "Guest"
Jinja2 = Environment()
# Vulnerable Implementation
output = Jinja2.from_string("Welcome " + username + "!").render()
# Safe Implementation
# output = Jinja2.from_string("Welcome {{ user_name }}!").render(user_name=username)
return HTMLResponse(content=output)
@@ -0,0 +1,24 @@
# Provenance: TheWation/PythonSSTI read_root (vuln).
# repo: TheWation/PythonSSTI
# commit: 76339c27d5a870c0a81bad6aee5f9bd516592145
# parent: 76339c27d5a870c0a81bad6aee5f9bd516592145
# commit_url: https://github.com/TheWation/PythonSSTI/blob/76339c27d5a870c0a81bad6aee5f9bd516592145/main.py#L14
# cve:
# license: MIT
# function: read_root
# relpath: main.py
# provenance: human
# mechanism: source_reaches_sink
async def read_root(username=None):
username = username or "Guest"
Jinja2 = Environment()
# Vulnerable Implementation
output = Jinja2.from_string("Welcome " + username + "!").render()
# Safe Implementation
# output = Jinja2.from_string("Welcome {{ user_name }}!").render(user_name=username)
return HTMLResponse(content=output)
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,47 @@
# Provenance: anotherik/ThreatByte delete (fixed).
# repo: anotherik/ThreatByte
# commit: c4db46f72586c4ecb65859051ea037018dbf0e5e
# parent: c4db46f72586c4ecb65859051ea037018dbf0e5e
# commit_url: https://github.com/anotherik/ThreatByte/blob/c4db46f72586c4ecb65859051ea037018dbf0e5e/server/api/v1/api_v1.py#L223
# cve:
# license: MIT
# function: delete
# relpath: server/api/v1/api_v1.py
# provenance: human
# mechanism: missing_auth_guard
def post(self):
"""
Handles user login.
"""
data = request.get_json() # Get data from request body
username = data.get('username')
password = data.get('password')
if not username or not password:
return {'error': 'Please provide username and password'}, 400
with get_db_connection() as conn:
cursor = conn.cursor()
query = "SELECT * FROM users WHERE username = ? OR email = ?"
cursor.execute(query, (username, username))
user = cursor.fetchone()
if user and user['password'] == custom_hash(password):
# Generate JWT
token = jwt.encode({
'username': username,
'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=24) # Token expires in 24 hours
}, Config.SECRET_KEY, algorithm='HS256')
# Update last_login timestamp
with get_db_connection() as conn:
cursor = conn.cursor()
cursor.execute("UPDATE users SET last_login = ? WHERE username = ?", (datetime.datetime.now(), username))
conn.commit()
return {'message': 'Login successful', 'token': token}, 200
else:
return {'error': 'Invalid username or password'}, 401
@@ -0,0 +1,28 @@
# Provenance: anotherik/ThreatByte delete (vuln).
# repo: anotherik/ThreatByte
# commit: c4db46f72586c4ecb65859051ea037018dbf0e5e
# parent: c4db46f72586c4ecb65859051ea037018dbf0e5e
# commit_url: https://github.com/anotherik/ThreatByte/blob/c4db46f72586c4ecb65859051ea037018dbf0e5e/server/api/v1/api_v1.py#L223
# cve:
# license: MIT
# function: delete
# relpath: server/api/v1/api_v1.py
# provenance: human
# mechanism: missing_auth_guard
def delete(self, user_id):
"""
Delete a user from the application.
"""
with get_db_connection() as conn:
cursor = conn.cursor()
cursor.execute("SELECT * FROM users WHERE id = ?", (user_id,))
user = cursor.fetchone()
if user:
cursor.execute("DELETE FROM users WHERE id = ?", (user_id,))
conn.commit()
response = make_response(jsonify({'message': 'User deleted successfully'}), 200)
return response
else:
response = make_response(jsonify({'error': 'User not found'}), 404)
return response
@@ -0,0 +1,47 @@
# Provenance: anotherik/ThreatByte get (fixed).
# repo: anotherik/ThreatByte
# commit: c4db46f72586c4ecb65859051ea037018dbf0e5e
# parent: c4db46f72586c4ecb65859051ea037018dbf0e5e
# commit_url: https://github.com/anotherik/ThreatByte/blob/c4db46f72586c4ecb65859051ea037018dbf0e5e/server/api/v1/api_v1.py#L154
# cve:
# license: MIT
# function: get
# relpath: server/api/v1/api_v1.py
# provenance: human
# mechanism: missing_auth_guard
def post(self):
"""
Handles user login.
"""
data = request.get_json() # Get data from request body
username = data.get('username')
password = data.get('password')
if not username or not password:
return {'error': 'Please provide username and password'}, 400
with get_db_connection() as conn:
cursor = conn.cursor()
query = "SELECT * FROM users WHERE username = ? OR email = ?"
cursor.execute(query, (username, username))
user = cursor.fetchone()
if user and user['password'] == custom_hash(password):
# Generate JWT
token = jwt.encode({
'username': username,
'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=24) # Token expires in 24 hours
}, Config.SECRET_KEY, algorithm='HS256')
# Update last_login timestamp
with get_db_connection() as conn:
cursor = conn.cursor()
cursor.execute("UPDATE users SET last_login = ? WHERE username = ?", (datetime.datetime.now(), username))
conn.commit()
return {'message': 'Login successful', 'token': token}, 200
else:
return {'error': 'Invalid username or password'}, 401
@@ -0,0 +1,29 @@
# Provenance: anotherik/ThreatByte get (vuln).
# repo: anotherik/ThreatByte
# commit: c4db46f72586c4ecb65859051ea037018dbf0e5e
# parent: c4db46f72586c4ecb65859051ea037018dbf0e5e
# commit_url: https://github.com/anotherik/ThreatByte/blob/c4db46f72586c4ecb65859051ea037018dbf0e5e/server/api/v1/api_v1.py#L154
# cve:
# license: MIT
# function: get
# relpath: server/api/v1/api_v1.py
# provenance: human
# mechanism: missing_auth_guard
def get(self):
"""
Retrieves the profile information of a user based on the provided user ID.
"""
args = profile_query.parse_args()
user_id = args.get('user_id')
with get_db_connection() as conn:
cursor = conn.cursor()
query = "SELECT username, email, country, role, permissions, team FROM users WHERE id = ?"
cursor.execute(query, (user_id,))
user_profile = cursor.fetchone()
if user_profile:
return dict(user_profile), 200
else:
return {'error': 'User profile not found'}, 404
@@ -0,0 +1,53 @@
# Provenance: anotherik/ThreatByte dashboard (fixed).
# repo: anotherik/ThreatByte
# commit: c4db46f72586c4ecb65859051ea037018dbf0e5e
# parent: c4db46f72586c4ecb65859051ea037018dbf0e5e
# commit_url: https://github.com/anotherik/ThreatByte/blob/c4db46f72586c4ecb65859051ea037018dbf0e5e/server/routes.py#L137
# cve:
# license: MIT
# function: dashboard
# relpath: server/routes.py
# provenance: human
# mechanism: source_reaches_sink
def login():
"""
Handles user login.
On GET request:
Renders the login page.
On POST request:
Retrieves the username and password from the login form.
Queries the database for the user based on the provided username.
Checks if the provided password matches the hashed password stored in the database.
If authentication succeeds, stores the username in the session and redirects to the dashboard.
If authentication fails, renders the login page with an error message.
"""
if request.method == 'POST':
username = request.form.get('username')
password = request.form.get('password')
if not username or not password:
return render_template('login.html', error='Please provide username and password')
# Query the database for the user using parameterized query
with get_db_connection() as conn:
cursor = conn.cursor()
query = "SELECT * FROM users WHERE username = ? OR email = ?"
cursor.execute(query, (username,username))
user = cursor.fetchone()
# Check if the user exists and the password matches
if user and user['password'] == custom_hash(password):
session['username'] = user['username']
session['user_id'] = user['id']
# Update last_login timestamp
cursor.execute("UPDATE users SET last_login = ? WHERE username = ?", (datetime.datetime.now(), username))
conn.commit()
conn.close()
return redirect(url_for('dashboard'))
else:
return render_template('login.html', error='Invalid username or password')
return render_template('login.html')
@@ -0,0 +1,36 @@
# Provenance: anotherik/ThreatByte dashboard (vuln).
# repo: anotherik/ThreatByte
# commit: c4db46f72586c4ecb65859051ea037018dbf0e5e
# parent: c4db46f72586c4ecb65859051ea037018dbf0e5e
# commit_url: https://github.com/anotherik/ThreatByte/blob/c4db46f72586c4ecb65859051ea037018dbf0e5e/server/routes.py#L137
# cve:
# license: MIT
# function: dashboard
# relpath: server/routes.py
# provenance: human
# mechanism: source_reaches_sink
def dashboard():
# Check if the user is logged in
if 'username' in session:
search_query = request.args.get('search', '')
# Get user_id from the session username
with get_db_connection() as conn:
cursor = conn.cursor()
query = "SELECT id FROM users WHERE username = ?"
cursor.execute(query, (session['username'],))
user = cursor.fetchone()
user_id = user['id']
if search_query:
s_query = f"SELECT filename FROM files WHERE user_id = {user_id} AND filename LIKE '%{search_query}%'"
cursor.execute(s_query)
else:
cursor.execute("SELECT filename FROM files WHERE user_id = ?", (user_id,))
files = [row['filename'] for row in cursor.fetchall()]
return render_template('dashboard.html', files=files, search_query=search_query)
else:
return redirect(url_for('login'))
@@ -0,0 +1,70 @@
{"class": "command_injection", "commit": "a961308c02d1fb462b192681c336b0739e432da7", "commit_url": "https://github.com/dolevf/Damn-Vulnerable-GraphQL-Application/blob/a961308c02d1fb462b192681c336b0739e432da7/core/views.py#L211", "cve": "", "cwe": "CWE-78", "file": "damn-vulnerable-graphql-application-views-mutate/vuln.py", "function": "mutate", "id": "damn-vulnerable-graphql-application-views-mutate:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "damn-vulnerable-graphql-application-views-mutate", "project": "realvuln-damn-vulnerable-graphql-application", "provenance": "human", "relpath": "core/views.py", "repo": "dolevf/Damn-Vulnerable-GraphQL-Application", "split": "train", "year": 2026}
{"class": "command_injection", "commit": "a961308c02d1fb462b192681c336b0739e432da7", "commit_url": "https://github.com/dolevf/Damn-Vulnerable-GraphQL-Application/blob/a961308c02d1fb462b192681c336b0739e432da7/core/views.py#L211", "cve": "", "cwe": "CWE-78", "file": "damn-vulnerable-graphql-application-views-mutate/fixed.py", "function": "mutate", "id": "damn-vulnerable-graphql-application-views-mutate:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "damn-vulnerable-graphql-application-views-mutate", "project": "realvuln-damn-vulnerable-graphql-application", "provenance": "human", "relpath": "core/views.py", "repo": "dolevf/Damn-Vulnerable-GraphQL-Application", "split": "train", "year": 2026}
{"class": "sql_injection", "commit": "a961308c02d1fb462b192681c336b0739e432da7", "commit_url": "https://github.com/dolevf/Damn-Vulnerable-GraphQL-Application/blob/a961308c02d1fb462b192681c336b0739e432da7/core/views.py#L320", "cve": "", "cwe": "CWE-89", "file": "damn-vulnerable-graphql-application-views-resolve-pastes/vuln.py", "function": "resolve_pastes", "id": "damn-vulnerable-graphql-application-views-resolve-pastes:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "damn-vulnerable-graphql-application-views-resolve-pastes", "project": "realvuln-damn-vulnerable-graphql-application", "provenance": "human", "relpath": "core/views.py", "repo": "dolevf/Damn-Vulnerable-GraphQL-Application", "split": "holdout", "year": 2026}
{"class": "sql_injection", "commit": "a961308c02d1fb462b192681c336b0739e432da7", "commit_url": "https://github.com/dolevf/Damn-Vulnerable-GraphQL-Application/blob/a961308c02d1fb462b192681c336b0739e432da7/core/views.py#L320", "cve": "", "cwe": "CWE-89", "file": "damn-vulnerable-graphql-application-views-resolve-pastes/fixed.py", "function": "resolve_pastes", "id": "damn-vulnerable-graphql-application-views-resolve-pastes:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "damn-vulnerable-graphql-application-views-resolve-pastes", "project": "realvuln-damn-vulnerable-graphql-application", "provenance": "human", "relpath": "core/views.py", "repo": "dolevf/Damn-Vulnerable-GraphQL-Application", "split": "holdout", "year": 2026}
{"class": "command_injection", "commit": "a961308c02d1fb462b192681c336b0739e432da7", "commit_url": "https://github.com/dolevf/Damn-Vulnerable-GraphQL-Application/blob/a961308c02d1fb462b192681c336b0739e432da7/core/views.py#L345", "cve": "", "cwe": "CWE-78", "file": "damn-vulnerable-graphql-application-views-resolve-system-dia/vuln.py", "function": "resolve_system_diagnostics", "id": "damn-vulnerable-graphql-application-views-resolve-system-dia:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "damn-vulnerable-graphql-application-views-resolve-system-dia", "project": "realvuln-damn-vulnerable-graphql-application", "provenance": "human", "relpath": "core/views.py", "repo": "dolevf/Damn-Vulnerable-GraphQL-Application", "split": "train", "year": 2026}
{"class": "command_injection", "commit": "a961308c02d1fb462b192681c336b0739e432da7", "commit_url": "https://github.com/dolevf/Damn-Vulnerable-GraphQL-Application/blob/a961308c02d1fb462b192681c336b0739e432da7/core/views.py#L345", "cve": "", "cwe": "CWE-78", "file": "damn-vulnerable-graphql-application-views-resolve-system-dia/fixed.py", "function": "resolve_system_diagnostics", "id": "damn-vulnerable-graphql-application-views-resolve-system-dia:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "damn-vulnerable-graphql-application-views-resolve-system-dia", "project": "realvuln-damn-vulnerable-graphql-application", "provenance": "human", "relpath": "core/views.py", "repo": "dolevf/Damn-Vulnerable-GraphQL-Application", "split": "train", "year": 2026}
{"class": "sql_injection", "commit": "082c88bfefced508ae083b92b459c808f95e905e", "commit_url": "https://github.com/Contrast-Security-OSS/DjanGoat/blob/082c88bfefced508ae083b92b459c808f95e905e/app/models/Analytics/analytics.py#L57", "cve": "", "cwe": "CWE-89", "file": "djangoat-analytics-hits-by-ip/vuln.py", "function": "hits_by_ip", "id": "djangoat-analytics-hits-by-ip:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "djangoat-analytics-hits-by-ip", "project": "realvuln-djangoat", "provenance": "human", "relpath": "app/models/Analytics/analytics.py", "repo": "Contrast-Security-OSS/DjanGoat", "split": "holdout", "year": 2026}
{"class": "sql_injection", "commit": "082c88bfefced508ae083b92b459c808f95e905e", "commit_url": "https://github.com/Contrast-Security-OSS/DjanGoat/blob/082c88bfefced508ae083b92b459c808f95e905e/app/models/Analytics/analytics.py#L57", "cve": "", "cwe": "CWE-89", "file": "djangoat-analytics-hits-by-ip/fixed.py", "function": "hits_by_ip", "id": "djangoat-analytics-hits-by-ip:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "djangoat-analytics-hits-by-ip", "project": "realvuln-djangoat", "provenance": "human", "relpath": "app/models/Analytics/analytics.py", "repo": "Contrast-Security-OSS/DjanGoat", "split": "holdout", "year": 2026}
{"class": "insecure_deserialization", "commit": "082c88bfefced508ae083b92b459c808f95e905e", "commit_url": "https://github.com/Contrast-Security-OSS/DjanGoat/blob/082c88bfefced508ae083b92b459c808f95e905e/app/views/password_resets/views.py#L84", "cve": "", "cwe": "CWE-502", "file": "djangoat-views-reset-password/vuln.py", "function": "reset_password", "id": "djangoat-views-reset-password:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "djangoat-views-reset-password", "project": "realvuln-djangoat", "provenance": "human", "relpath": "app/views/password_resets/views.py", "repo": "Contrast-Security-OSS/DjanGoat", "split": "train", "year": 2026}
{"class": "insecure_deserialization", "commit": "082c88bfefced508ae083b92b459c808f95e905e", "commit_url": "https://github.com/Contrast-Security-OSS/DjanGoat/blob/082c88bfefced508ae083b92b459c808f95e905e/app/views/password_resets/views.py#L84", "cve": "", "cwe": "CWE-502", "file": "djangoat-views-reset-password/fixed.py", "function": "reset_password", "id": "djangoat-views-reset-password:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "djangoat-views-reset-password", "project": "realvuln-djangoat", "provenance": "human", "relpath": "app/views/password_resets/views.py", "repo": "Contrast-Security-OSS/DjanGoat", "split": "train", "year": 2026}
{"class": "sql_injection", "commit": "082c88bfefced508ae083b92b459c808f95e905e", "commit_url": "https://github.com/Contrast-Security-OSS/DjanGoat/blob/082c88bfefced508ae083b92b459c808f95e905e/app/views/users/views.py#L74", "cve": "", "cwe": "CWE-89", "file": "djangoat-views-user-view/vuln.py", "function": "user_view", "id": "djangoat-views-user-view:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "djangoat-views-user-view", "project": "realvuln-djangoat", "provenance": "human", "relpath": "app/views/users/views.py", "repo": "Contrast-Security-OSS/DjanGoat", "split": "holdout", "year": 2026}
{"class": "sql_injection", "commit": "082c88bfefced508ae083b92b459c808f95e905e", "commit_url": "https://github.com/Contrast-Security-OSS/DjanGoat/blob/082c88bfefced508ae083b92b459c808f95e905e/app/views/users/views.py#L74", "cve": "", "cwe": "CWE-89", "file": "djangoat-views-user-view/fixed.py", "function": "user_view", "id": "djangoat-views-user-view:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "djangoat-views-user-view", "project": "realvuln-djangoat", "provenance": "human", "relpath": "app/views/users/views.py", "repo": "Contrast-Security-OSS/DjanGoat", "split": "holdout", "year": 2026}
{"class": "sql_injection", "commit": "a06abb306ed3699bb2f073e3f41d3d9c57012819", "commit_url": "https://github.com/sgabe/DSVPWA/blob/a06abb306ed3699bb2f073e3f41d3d9c57012819/dsvpwa/attacks.py#L39", "cve": "", "cwe": "CWE-89", "file": "dsvpwa-attacks-run/vuln.py", "function": "run", "id": "dsvpwa-attacks-run:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "dsvpwa-attacks-run", "project": "realvuln-dsvpwa", "provenance": "human", "relpath": "dsvpwa/attacks.py", "repo": "sgabe/DSVPWA", "split": "train", "year": 2026}
{"class": "sql_injection", "commit": "a06abb306ed3699bb2f073e3f41d3d9c57012819", "commit_url": "https://github.com/sgabe/DSVPWA/blob/a06abb306ed3699bb2f073e3f41d3d9c57012819/dsvpwa/attacks.py#L39", "cve": "", "cwe": "CWE-89", "file": "dsvpwa-attacks-run/fixed.py", "function": "run", "id": "dsvpwa-attacks-run:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "dsvpwa-attacks-run", "project": "realvuln-dsvpwa", "provenance": "human", "relpath": "dsvpwa/attacks.py", "repo": "sgabe/DSVPWA", "split": "train", "year": 2026}
{"class": "security_misconfiguration", "commit": "a06abb306ed3699bb2f073e3f41d3d9c57012819", "commit_url": "https://github.com/sgabe/DSVPWA/blob/a06abb306ed3699bb2f073e3f41d3d9c57012819/dsvpwa.py#L37", "cve": "", "cwe": "CWE-326", "file": "dsvpwa-dsvpwa-main/vuln.py", "function": "main", "id": "dsvpwa-dsvpwa-main:vuln", "label": "vuln", "license": "MIT", "mechanism": "permissive_default", "pair": "dsvpwa-dsvpwa-main", "project": "realvuln-dsvpwa", "provenance": "human", "relpath": "dsvpwa.py", "repo": "sgabe/DSVPWA", "split": "holdout", "year": 2026}
{"class": "security_misconfiguration", "commit": "a06abb306ed3699bb2f073e3f41d3d9c57012819", "commit_url": "https://github.com/sgabe/DSVPWA/blob/a06abb306ed3699bb2f073e3f41d3d9c57012819/dsvpwa.py#L37", "cve": "", "cwe": "CWE-326", "file": "dsvpwa-dsvpwa-main/fixed.py", "function": "main", "id": "dsvpwa-dsvpwa-main:fixed", "label": "fixed", "license": "MIT", "mechanism": "permissive_default", "pair": "dsvpwa-dsvpwa-main", "project": "realvuln-dsvpwa", "provenance": "human", "relpath": "dsvpwa.py", "repo": "sgabe/DSVPWA", "split": "holdout", "year": 2026}
{"class": "command_injection", "commit": "a06abb306ed3699bb2f073e3f41d3d9c57012819", "commit_url": "https://github.com/sgabe/DSVPWA/blob/a06abb306ed3699bb2f073e3f41d3d9c57012819/dsvpwa/handlers.py#L183", "cve": "", "cwe": "CWE-78", "file": "dsvpwa-handlers-do-bdr/vuln.py", "function": "do_BDR", "id": "dsvpwa-handlers-do-bdr:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "dsvpwa-handlers-do-bdr", "project": "realvuln-dsvpwa", "provenance": "human", "relpath": "dsvpwa/handlers.py", "repo": "sgabe/DSVPWA", "split": "train", "year": 2026}
{"class": "command_injection", "commit": "a06abb306ed3699bb2f073e3f41d3d9c57012819", "commit_url": "https://github.com/sgabe/DSVPWA/blob/a06abb306ed3699bb2f073e3f41d3d9c57012819/dsvpwa/handlers.py#L183", "cve": "", "cwe": "CWE-78", "file": "dsvpwa-handlers-do-bdr/fixed.py", "function": "do_BDR", "id": "dsvpwa-handlers-do-bdr:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "dsvpwa-handlers-do-bdr", "project": "realvuln-dsvpwa", "provenance": "human", "relpath": "dsvpwa/handlers.py", "repo": "sgabe/DSVPWA", "split": "train", "year": 2026}
{"class": "sql_injection", "commit": "7d40f4b7939c901610ed9b85724552d60e7d63fa", "commit_url": "https://github.com/stamparm/DSVW/blob/7d40f4b7939c901610ed9b85724552d60e7d63fa/dsvw.py#L30", "cve": "", "cwe": "CWE-89", "file": "dsvw-dsvw-do-get/vuln.py", "function": "do_GET", "id": "dsvw-dsvw-do-get:vuln", "label": "vuln", "license": "Unlicense", "mechanism": "source_reaches_sink", "pair": "dsvw-dsvw-do-get", "project": "realvuln-dsvw", "provenance": "human", "relpath": "dsvw.py", "repo": "stamparm/DSVW", "split": "holdout", "year": 2026}
{"class": "sql_injection", "commit": "7d40f4b7939c901610ed9b85724552d60e7d63fa", "commit_url": "https://github.com/stamparm/DSVW/blob/7d40f4b7939c901610ed9b85724552d60e7d63fa/dsvw.py#L30", "cve": "", "cwe": "CWE-89", "file": "dsvw-dsvw-do-get/fixed.py", "function": "do_GET", "id": "dsvw-dsvw-do-get:fixed", "label": "fixed", "license": "Unlicense", "mechanism": "source_reaches_sink", "pair": "dsvw-dsvw-do-get", "project": "realvuln-dsvw", "provenance": "human", "relpath": "dsvw.py", "repo": "stamparm/DSVW", "split": "holdout", "year": 2026}
{"class": "security_misconfiguration", "commit": "a1d8f89fac2e57093189853c6527c2b01fc1d9c1", "commit_url": "https://github.com/anxolerd/dvpwa/blob/a1d8f89fac2e57093189853c6527c2b01fc1d9c1/sqli/app.py#L35", "cve": "", "cwe": "CWE-16", "file": "dvpwa-app-init/vuln.py", "function": "init", "id": "dvpwa-app-init:vuln", "label": "vuln", "license": "MIT", "mechanism": "permissive_default", "pair": "dvpwa-app-init", "project": "realvuln-dvpwa", "provenance": "human", "relpath": "sqli/app.py", "repo": "anxolerd/dvpwa", "split": "train", "year": 2026}
{"class": "security_misconfiguration", "commit": "a1d8f89fac2e57093189853c6527c2b01fc1d9c1", "commit_url": "https://github.com/anxolerd/dvpwa/blob/a1d8f89fac2e57093189853c6527c2b01fc1d9c1/sqli/app.py#L35", "cve": "", "cwe": "CWE-16", "file": "dvpwa-app-init/fixed.py", "function": "init", "id": "dvpwa-app-init:fixed", "label": "fixed", "license": "MIT", "mechanism": "permissive_default", "pair": "dvpwa-app-init", "project": "realvuln-dvpwa", "provenance": "human", "relpath": "sqli/app.py", "repo": "anxolerd/dvpwa", "split": "train", "year": 2026}
{"class": "security_misconfiguration", "commit": "a1d8f89fac2e57093189853c6527c2b01fc1d9c1", "commit_url": "https://github.com/anxolerd/dvpwa/blob/a1d8f89fac2e57093189853c6527c2b01fc1d9c1/sqli/middlewares.py#L20", "cve": "", "cwe": "CWE-1004", "file": "dvpwa-middlewares-session-middleware/vuln.py", "function": "session_middleware", "id": "dvpwa-middlewares-session-middleware:vuln", "label": "vuln", "license": "MIT", "mechanism": "permissive_default", "pair": "dvpwa-middlewares-session-middleware", "project": "realvuln-dvpwa", "provenance": "human", "relpath": "sqli/middlewares.py", "repo": "anxolerd/dvpwa", "split": "holdout", "year": 2026}
{"class": "security_misconfiguration", "commit": "a1d8f89fac2e57093189853c6527c2b01fc1d9c1", "commit_url": "https://github.com/anxolerd/dvpwa/blob/a1d8f89fac2e57093189853c6527c2b01fc1d9c1/sqli/middlewares.py#L20", "cve": "", "cwe": "CWE-1004", "file": "dvpwa-middlewares-session-middleware/fixed.py", "function": "session_middleware", "id": "dvpwa-middlewares-session-middleware:fixed", "label": "fixed", "license": "MIT", "mechanism": "permissive_default", "pair": "dvpwa-middlewares-session-middleware", "project": "realvuln-dvpwa", "provenance": "human", "relpath": "sqli/middlewares.py", "repo": "anxolerd/dvpwa", "split": "holdout", "year": 2026}
{"class": "sql_injection", "commit": "a1d8f89fac2e57093189853c6527c2b01fc1d9c1", "commit_url": "https://github.com/anxolerd/dvpwa/blob/a1d8f89fac2e57093189853c6527c2b01fc1d9c1/sqli/dao/student.py#L42", "cve": "", "cwe": "CWE-89", "file": "dvpwa-student-create/vuln.py", "function": "create", "id": "dvpwa-student-create:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "dvpwa-student-create", "project": "realvuln-dvpwa", "provenance": "human", "relpath": "sqli/dao/student.py", "repo": "anxolerd/dvpwa", "split": "train", "year": 2026}
{"class": "sql_injection", "commit": "a1d8f89fac2e57093189853c6527c2b01fc1d9c1", "commit_url": "https://github.com/anxolerd/dvpwa/blob/a1d8f89fac2e57093189853c6527c2b01fc1d9c1/sqli/dao/student.py#L42", "cve": "", "cwe": "CWE-89", "file": "dvpwa-student-create/fixed.py", "function": "create", "id": "dvpwa-student-create:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "dvpwa-student-create", "project": "realvuln-dvpwa", "provenance": "human", "relpath": "sqli/dao/student.py", "repo": "anxolerd/dvpwa", "split": "train", "year": 2026}
{"class": "insecure_deserialization", "commit": "d5d8875559e21222bbbaadb7b9f0af592c6eb7fa", "commit_url": "https://github.com/manuelz120/extremely-vulnerable-flask-app/blob/d5d8875559e21222bbbaadb7b9f0af592c6eb7fa/routes/account.py#L118", "cve": "", "cwe": "CWE-502", "file": "extremely-vulnerable-flask-app-account-before-request/vuln.py", "function": "before_request", "id": "extremely-vulnerable-flask-app-account-before-request:vuln", "label": "vuln", "license": "GPL-3.0", "mechanism": "source_reaches_sink", "pair": "extremely-vulnerable-flask-app-account-before-request", "project": "realvuln-extremely-vulnerable-flask-app", "provenance": "human", "relpath": "routes/account.py", "repo": "manuelz120/extremely-vulnerable-flask-app", "split": "holdout", "year": 2026}
{"class": "insecure_deserialization", "commit": "d5d8875559e21222bbbaadb7b9f0af592c6eb7fa", "commit_url": "https://github.com/manuelz120/extremely-vulnerable-flask-app/blob/d5d8875559e21222bbbaadb7b9f0af592c6eb7fa/routes/account.py#L118", "cve": "", "cwe": "CWE-502", "file": "extremely-vulnerable-flask-app-account-before-request/fixed.py", "function": "before_request", "id": "extremely-vulnerable-flask-app-account-before-request:fixed", "label": "fixed", "license": "GPL-3.0", "mechanism": "source_reaches_sink", "pair": "extremely-vulnerable-flask-app-account-before-request", "project": "realvuln-extremely-vulnerable-flask-app", "provenance": "human", "relpath": "routes/account.py", "repo": "manuelz120/extremely-vulnerable-flask-app", "split": "holdout", "year": 2026}
{"class": "sql_injection", "commit": "d5d8875559e21222bbbaadb7b9f0af592c6eb7fa", "commit_url": "https://github.com/manuelz120/extremely-vulnerable-flask-app/blob/d5d8875559e21222bbbaadb7b9f0af592c6eb7fa/routes/account.py#L33", "cve": "", "cwe": "CWE-89", "file": "extremely-vulnerable-flask-app-account-search/vuln.py", "function": "search", "id": "extremely-vulnerable-flask-app-account-search:vuln", "label": "vuln", "license": "GPL-3.0", "mechanism": "source_reaches_sink", "pair": "extremely-vulnerable-flask-app-account-search", "project": "realvuln-extremely-vulnerable-flask-app", "provenance": "human", "relpath": "routes/account.py", "repo": "manuelz120/extremely-vulnerable-flask-app", "split": "train", "year": 2026}
{"class": "sql_injection", "commit": "d5d8875559e21222bbbaadb7b9f0af592c6eb7fa", "commit_url": "https://github.com/manuelz120/extremely-vulnerable-flask-app/blob/d5d8875559e21222bbbaadb7b9f0af592c6eb7fa/routes/account.py#L33", "cve": "", "cwe": "CWE-89", "file": "extremely-vulnerable-flask-app-account-search/fixed.py", "function": "search", "id": "extremely-vulnerable-flask-app-account-search:fixed", "label": "fixed", "license": "GPL-3.0", "mechanism": "source_reaches_sink", "pair": "extremely-vulnerable-flask-app-account-search", "project": "realvuln-extremely-vulnerable-flask-app", "provenance": "human", "relpath": "routes/account.py", "repo": "manuelz120/extremely-vulnerable-flask-app", "split": "train", "year": 2026}
{"class": "sql_injection", "commit": "d5d8875559e21222bbbaadb7b9f0af592c6eb7fa", "commit_url": "https://github.com/manuelz120/extremely-vulnerable-flask-app/blob/d5d8875559e21222bbbaadb7b9f0af592c6eb7fa/routes/signup.py#L15", "cve": "", "cwe": "CWE-89", "file": "extremely-vulnerable-flask-app-signup-validate-token/vuln.py", "function": "validate_token", "id": "extremely-vulnerable-flask-app-signup-validate-token:vuln", "label": "vuln", "license": "GPL-3.0", "mechanism": "source_reaches_sink", "pair": "extremely-vulnerable-flask-app-signup-validate-token", "project": "realvuln-extremely-vulnerable-flask-app", "provenance": "human", "relpath": "routes/signup.py", "repo": "manuelz120/extremely-vulnerable-flask-app", "split": "holdout", "year": 2026}
{"class": "sql_injection", "commit": "d5d8875559e21222bbbaadb7b9f0af592c6eb7fa", "commit_url": "https://github.com/manuelz120/extremely-vulnerable-flask-app/blob/d5d8875559e21222bbbaadb7b9f0af592c6eb7fa/routes/signup.py#L15", "cve": "", "cwe": "CWE-89", "file": "extremely-vulnerable-flask-app-signup-validate-token/fixed.py", "function": "validate_token", "id": "extremely-vulnerable-flask-app-signup-validate-token:fixed", "label": "fixed", "license": "GPL-3.0", "mechanism": "source_reaches_sink", "pair": "extremely-vulnerable-flask-app-signup-validate-token", "project": "realvuln-extremely-vulnerable-flask-app", "provenance": "human", "relpath": "routes/signup.py", "repo": "manuelz120/extremely-vulnerable-flask-app", "split": "holdout", "year": 2026}
{"class": "ssti", "commit": "80b894a2f754590747a31c92b2088be086421953", "commit_url": "https://github.com/kolega-ai/realvuln-python-insecure-app/blob/80b894a2f754590747a31c92b2088be086421953/app/main.py#L41", "cve": "", "cwe": "CWE-1336", "file": "python-insecure-app-main-try-hack-me/vuln.py", "function": "try_hack_me", "id": "python-insecure-app-main-try-hack-me:vuln", "label": "vuln", "license": "GPL-3.0", "mechanism": "source_reaches_sink", "pair": "python-insecure-app-main-try-hack-me", "project": "realvuln-python-insecure-app", "provenance": "human", "relpath": "app/main.py", "repo": "kolega-ai/realvuln-python-insecure-app", "split": "train", "year": 2026}
{"class": "ssti", "commit": "80b894a2f754590747a31c92b2088be086421953", "commit_url": "https://github.com/kolega-ai/realvuln-python-insecure-app/blob/80b894a2f754590747a31c92b2088be086421953/app/main.py#L41", "cve": "", "cwe": "CWE-1336", "file": "python-insecure-app-main-try-hack-me/fixed.py", "function": "try_hack_me", "id": "python-insecure-app-main-try-hack-me:fixed", "label": "fixed", "license": "GPL-3.0", "mechanism": "source_reaches_sink", "pair": "python-insecure-app-main-try-hack-me", "project": "realvuln-python-insecure-app", "provenance": "human", "relpath": "app/main.py", "repo": "kolega-ai/realvuln-python-insecure-app", "split": "train", "year": 2026}
{"class": "reflected_xss", "commit": "76339c27d5a870c0a81bad6aee5f9bd516592145", "commit_url": "https://github.com/TheWation/PythonSSTI/blob/76339c27d5a870c0a81bad6aee5f9bd516592145/main.py#L14", "cve": "", "cwe": "CWE-79", "file": "pythonssti-main-read-root/vuln.py", "function": "read_root", "id": "pythonssti-main-read-root:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "pythonssti-main-read-root", "project": "realvuln-pythonssti", "provenance": "human", "relpath": "main.py", "repo": "TheWation/PythonSSTI", "split": "holdout", "year": 2026}
{"class": "reflected_xss", "commit": "76339c27d5a870c0a81bad6aee5f9bd516592145", "commit_url": "https://github.com/TheWation/PythonSSTI/blob/76339c27d5a870c0a81bad6aee5f9bd516592145/main.py#L14", "cve": "", "cwe": "CWE-79", "file": "pythonssti-main-read-root/fixed.py", "function": "read_root", "id": "pythonssti-main-read-root:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "pythonssti-main-read-root", "project": "realvuln-pythonssti", "provenance": "human", "relpath": "main.py", "repo": "TheWation/PythonSSTI", "split": "holdout", "year": 2026}
{"class": "broken_access_control", "commit": "c4db46f72586c4ecb65859051ea037018dbf0e5e", "commit_url": "https://github.com/anotherik/ThreatByte/blob/c4db46f72586c4ecb65859051ea037018dbf0e5e/server/api/v1/api_v1.py#L223", "cve": "", "cwe": "CWE-862", "file": "threatbyte-api-v1-delete/vuln.py", "function": "delete", "id": "threatbyte-api-v1-delete:vuln", "label": "vuln", "license": "MIT", "mechanism": "missing_auth_guard", "pair": "threatbyte-api-v1-delete", "project": "realvuln-threatbyte", "provenance": "human", "relpath": "server/api/v1/api_v1.py", "repo": "anotherik/ThreatByte", "split": "train", "year": 2026}
{"class": "broken_access_control", "commit": "c4db46f72586c4ecb65859051ea037018dbf0e5e", "commit_url": "https://github.com/anotherik/ThreatByte/blob/c4db46f72586c4ecb65859051ea037018dbf0e5e/server/api/v1/api_v1.py#L223", "cve": "", "cwe": "CWE-862", "file": "threatbyte-api-v1-delete/fixed.py", "function": "delete", "id": "threatbyte-api-v1-delete:fixed", "label": "fixed", "license": "MIT", "mechanism": "missing_auth_guard", "pair": "threatbyte-api-v1-delete", "project": "realvuln-threatbyte", "provenance": "human", "relpath": "server/api/v1/api_v1.py", "repo": "anotherik/ThreatByte", "split": "train", "year": 2026}
{"class": "broken_access_control", "commit": "c4db46f72586c4ecb65859051ea037018dbf0e5e", "commit_url": "https://github.com/anotherik/ThreatByte/blob/c4db46f72586c4ecb65859051ea037018dbf0e5e/server/api/v1/api_v1.py#L154", "cve": "", "cwe": "CWE-639", "file": "threatbyte-api-v1-get/vuln.py", "function": "get", "id": "threatbyte-api-v1-get:vuln", "label": "vuln", "license": "MIT", "mechanism": "missing_auth_guard", "pair": "threatbyte-api-v1-get", "project": "realvuln-threatbyte", "provenance": "human", "relpath": "server/api/v1/api_v1.py", "repo": "anotherik/ThreatByte", "split": "holdout", "year": 2026}
{"class": "broken_access_control", "commit": "c4db46f72586c4ecb65859051ea037018dbf0e5e", "commit_url": "https://github.com/anotherik/ThreatByte/blob/c4db46f72586c4ecb65859051ea037018dbf0e5e/server/api/v1/api_v1.py#L154", "cve": "", "cwe": "CWE-639", "file": "threatbyte-api-v1-get/fixed.py", "function": "get", "id": "threatbyte-api-v1-get:fixed", "label": "fixed", "license": "MIT", "mechanism": "missing_auth_guard", "pair": "threatbyte-api-v1-get", "project": "realvuln-threatbyte", "provenance": "human", "relpath": "server/api/v1/api_v1.py", "repo": "anotherik/ThreatByte", "split": "holdout", "year": 2026}
{"class": "sql_injection", "commit": "c4db46f72586c4ecb65859051ea037018dbf0e5e", "commit_url": "https://github.com/anotherik/ThreatByte/blob/c4db46f72586c4ecb65859051ea037018dbf0e5e/server/routes.py#L137", "cve": "", "cwe": "CWE-89", "file": "threatbyte-routes-dashboard/vuln.py", "function": "dashboard", "id": "threatbyte-routes-dashboard:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "threatbyte-routes-dashboard", "project": "realvuln-threatbyte", "provenance": "human", "relpath": "server/routes.py", "repo": "anotherik/ThreatByte", "split": "train", "year": 2026}
{"class": "sql_injection", "commit": "c4db46f72586c4ecb65859051ea037018dbf0e5e", "commit_url": "https://github.com/anotherik/ThreatByte/blob/c4db46f72586c4ecb65859051ea037018dbf0e5e/server/routes.py#L137", "cve": "", "cwe": "CWE-89", "file": "threatbyte-routes-dashboard/fixed.py", "function": "dashboard", "id": "threatbyte-routes-dashboard:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "threatbyte-routes-dashboard", "project": "realvuln-threatbyte", "provenance": "human", "relpath": "server/routes.py", "repo": "anotherik/ThreatByte", "split": "train", "year": 2026}
{"class": "broken_access_control", "commit": "1713b54b601ad29582581eeda4b31fceb1319874", "commit_url": "https://github.com/erev0s/VAmPI/blob/1713b54b601ad29582581eeda4b31fceb1319874/api_views/books.py#L51", "cve": "", "cwe": "CWE-639", "file": "vampi-books-get-by-title/vuln.py", "function": "get_by_title", "id": "vampi-books-get-by-title:vuln", "label": "vuln", "license": "MIT", "mechanism": "missing_auth_guard", "pair": "vampi-books-get-by-title", "project": "realvuln-vampi", "provenance": "human", "relpath": "api_views/books.py", "repo": "erev0s/VAmPI", "split": "holdout", "year": 2026}
{"class": "broken_access_control", "commit": "1713b54b601ad29582581eeda4b31fceb1319874", "commit_url": "https://github.com/erev0s/VAmPI/blob/1713b54b601ad29582581eeda4b31fceb1319874/api_views/books.py#L51", "cve": "", "cwe": "CWE-639", "file": "vampi-books-get-by-title/fixed.py", "function": "get_by_title", "id": "vampi-books-get-by-title:fixed", "label": "fixed", "license": "MIT", "mechanism": "missing_auth_guard", "pair": "vampi-books-get-by-title", "project": "realvuln-vampi", "provenance": "human", "relpath": "api_views/books.py", "repo": "erev0s/VAmPI", "split": "holdout", "year": 2026}
{"class": "sql_injection", "commit": "1713b54b601ad29582581eeda4b31fceb1319874", "commit_url": "https://github.com/erev0s/VAmPI/blob/1713b54b601ad29582581eeda4b31fceb1319874/models/user_model.py#L72", "cve": "", "cwe": "CWE-89", "file": "vampi-user-model-get-user/vuln.py", "function": "get_user", "id": "vampi-user-model-get-user:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "vampi-user-model-get-user", "project": "realvuln-vampi", "provenance": "human", "relpath": "models/user_model.py", "repo": "erev0s/VAmPI", "split": "train", "year": 2026}
{"class": "sql_injection", "commit": "1713b54b601ad29582581eeda4b31fceb1319874", "commit_url": "https://github.com/erev0s/VAmPI/blob/1713b54b601ad29582581eeda4b31fceb1319874/models/user_model.py#L72", "cve": "", "cwe": "CWE-89", "file": "vampi-user-model-get-user/fixed.py", "function": "get_user", "id": "vampi-user-model-get-user:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "vampi-user-model-get-user", "project": "realvuln-vampi", "provenance": "human", "relpath": "models/user_model.py", "repo": "erev0s/VAmPI", "split": "train", "year": 2026}
{"class": "broken_access_control", "commit": "1713b54b601ad29582581eeda4b31fceb1319874", "commit_url": "https://github.com/erev0s/VAmPI/blob/1713b54b601ad29582581eeda4b31fceb1319874/api_views/users.py#L187", "cve": "", "cwe": "CWE-639", "file": "vampi-users-update-password/vuln.py", "function": "update_password", "id": "vampi-users-update-password:vuln", "label": "vuln", "license": "MIT", "mechanism": "missing_auth_guard", "pair": "vampi-users-update-password", "project": "realvuln-vampi", "provenance": "human", "relpath": "api_views/users.py", "repo": "erev0s/VAmPI", "split": "holdout", "year": 2026}
{"class": "broken_access_control", "commit": "1713b54b601ad29582581eeda4b31fceb1319874", "commit_url": "https://github.com/erev0s/VAmPI/blob/1713b54b601ad29582581eeda4b31fceb1319874/api_views/users.py#L187", "cve": "", "cwe": "CWE-639", "file": "vampi-users-update-password/fixed.py", "function": "update_password", "id": "vampi-users-update-password:fixed", "label": "fixed", "license": "MIT", "mechanism": "missing_auth_guard", "pair": "vampi-users-update-password", "project": "realvuln-vampi", "provenance": "human", "relpath": "api_views/users.py", "repo": "erev0s/VAmPI", "split": "holdout", "year": 2026}
{"class": "sql_injection", "commit": "f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3", "commit_url": "https://github.com/naryal2580/vfapi/blob/f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3/main.py#L231", "cve": "", "cwe": "CWE-89", "file": "vfapi-main-delete-user/vuln.py", "function": "delete_user", "id": "vfapi-main-delete-user:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "vfapi-main-delete-user", "project": "realvuln-vfapi", "provenance": "human", "relpath": "main.py", "repo": "naryal2580/vfapi", "split": "train", "year": 2026}
{"class": "sql_injection", "commit": "f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3", "commit_url": "https://github.com/naryal2580/vfapi/blob/f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3/main.py#L231", "cve": "", "cwe": "CWE-89", "file": "vfapi-main-delete-user/fixed.py", "function": "delete_user", "id": "vfapi-main-delete-user:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "vfapi-main-delete-user", "project": "realvuln-vfapi", "provenance": "human", "relpath": "main.py", "repo": "naryal2580/vfapi", "split": "train", "year": 2026}
{"class": "sql_injection", "commit": "f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3", "commit_url": "https://github.com/naryal2580/vfapi/blob/f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3/main.py#L188", "cve": "", "cwe": "CWE-89", "file": "vfapi-main-put-user/vuln.py", "function": "put_user", "id": "vfapi-main-put-user:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "vfapi-main-put-user", "project": "realvuln-vfapi", "provenance": "human", "relpath": "main.py", "repo": "naryal2580/vfapi", "split": "holdout", "year": 2026}
{"class": "sql_injection", "commit": "f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3", "commit_url": "https://github.com/naryal2580/vfapi/blob/f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3/main.py#L188", "cve": "", "cwe": "CWE-89", "file": "vfapi-main-put-user/fixed.py", "function": "put_user", "id": "vfapi-main-put-user:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "vfapi-main-put-user", "project": "realvuln-vfapi", "provenance": "human", "relpath": "main.py", "repo": "naryal2580/vfapi", "split": "holdout", "year": 2026}
{"class": "sql_injection", "commit": "f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3", "commit_url": "https://github.com/naryal2580/vfapi/blob/f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3/main.py#L182", "cve": "", "cwe": "CWE-89", "file": "vfapi-main-sql-return-users-from-username/vuln.py", "function": "sql_return_users_from_username", "id": "vfapi-main-sql-return-users-from-username:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "vfapi-main-sql-return-users-from-username", "project": "realvuln-vfapi", "provenance": "human", "relpath": "main.py", "repo": "naryal2580/vfapi", "split": "train", "year": 2026}
{"class": "sql_injection", "commit": "f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3", "commit_url": "https://github.com/naryal2580/vfapi/blob/f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3/main.py#L182", "cve": "", "cwe": "CWE-89", "file": "vfapi-main-sql-return-users-from-username/fixed.py", "function": "sql_return_users_from_username", "id": "vfapi-main-sql-return-users-from-username:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "vfapi-main-sql-return-users-from-username", "project": "realvuln-vfapi", "provenance": "human", "relpath": "main.py", "repo": "naryal2580/vfapi", "split": "train", "year": 2026}
{"class": "reflected_xss", "commit": "6336c77e6db523a5df34c4b628dff4159110797a", "commit_url": "https://github.com/LinuxUser255/Vulnerable_Python_Apps/blob/6336c77e6db523a5df34c4b628dff4159110797a/Insecure_Frameworks/bad_mvc.py#L37", "cve": "", "cwe": "CWE-79", "file": "vulnerable-python-apps-bad-mvc-do-get/vuln.py", "function": "do_GET", "id": "vulnerable-python-apps-bad-mvc-do-get:vuln", "label": "vuln", "license": "GPL-3.0", "mechanism": "source_reaches_sink", "pair": "vulnerable-python-apps-bad-mvc-do-get", "project": "realvuln-vulnerable-python-apps", "provenance": "human", "relpath": "Insecure_Frameworks/bad_mvc.py", "repo": "LinuxUser255/Vulnerable_Python_Apps", "split": "holdout", "year": 2026}
{"class": "reflected_xss", "commit": "6336c77e6db523a5df34c4b628dff4159110797a", "commit_url": "https://github.com/LinuxUser255/Vulnerable_Python_Apps/blob/6336c77e6db523a5df34c4b628dff4159110797a/Insecure_Frameworks/bad_mvc.py#L37", "cve": "", "cwe": "CWE-79", "file": "vulnerable-python-apps-bad-mvc-do-get/fixed.py", "function": "do_GET", "id": "vulnerable-python-apps-bad-mvc-do-get:fixed", "label": "fixed", "license": "GPL-3.0", "mechanism": "source_reaches_sink", "pair": "vulnerable-python-apps-bad-mvc-do-get", "project": "realvuln-vulnerable-python-apps", "provenance": "human", "relpath": "Insecure_Frameworks/bad_mvc.py", "repo": "LinuxUser255/Vulnerable_Python_Apps", "split": "holdout", "year": 2026}
{"class": "path_traversal", "commit": "6336c77e6db523a5df34c4b628dff4159110797a", "commit_url": "https://github.com/LinuxUser255/Vulnerable_Python_Apps/blob/6336c77e6db523a5df34c4b628dff4159110797a/Directory_Traversal/Dir_Traversal.py#L22", "cve": "", "cwe": "CWE-22", "file": "vulnerable-python-apps-dir-traversal-do-get/vuln.py", "function": "do_GET", "id": "vulnerable-python-apps-dir-traversal-do-get:vuln", "label": "vuln", "license": "GPL-3.0", "mechanism": "path_join_user_input", "pair": "vulnerable-python-apps-dir-traversal-do-get", "project": "realvuln-vulnerable-python-apps", "provenance": "human", "relpath": "Directory_Traversal/Dir_Traversal.py", "repo": "LinuxUser255/Vulnerable_Python_Apps", "split": "train", "year": 2026}
{"class": "path_traversal", "commit": "6336c77e6db523a5df34c4b628dff4159110797a", "commit_url": "https://github.com/LinuxUser255/Vulnerable_Python_Apps/blob/6336c77e6db523a5df34c4b628dff4159110797a/Directory_Traversal/Dir_Traversal.py#L22", "cve": "", "cwe": "CWE-22", "file": "vulnerable-python-apps-dir-traversal-do-get/fixed.py", "function": "do_GET", "id": "vulnerable-python-apps-dir-traversal-do-get:fixed", "label": "fixed", "license": "GPL-3.0", "mechanism": "path_join_user_input", "pair": "vulnerable-python-apps-dir-traversal-do-get", "project": "realvuln-vulnerable-python-apps", "provenance": "human", "relpath": "Directory_Traversal/Dir_Traversal.py", "repo": "LinuxUser255/Vulnerable_Python_Apps", "split": "train", "year": 2026}
{"class": "command_injection", "commit": "d1d0f64c06f038fe59a049e0e6001bfaf9839697", "commit_url": "https://github.com/Contrast-Security-OSS/vulnpy/blob/d1d0f64c06f038fe59a049e0e6001bfaf9839697/src/vulnpy/trigger/cmdi.py#L6", "cve": "", "cwe": "CWE-78", "file": "vulnpy-cmdi-do-os-system/vuln.py", "function": "do_os_system", "id": "vulnpy-cmdi-do-os-system:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "vulnpy-cmdi-do-os-system", "project": "realvuln-vulnpy", "provenance": "human", "relpath": "src/vulnpy/trigger/cmdi.py", "repo": "Contrast-Security-OSS/vulnpy", "split": "train", "year": 2026}
{"class": "command_injection", "commit": "d1d0f64c06f038fe59a049e0e6001bfaf9839697", "commit_url": "https://github.com/Contrast-Security-OSS/vulnpy/blob/d1d0f64c06f038fe59a049e0e6001bfaf9839697/src/vulnpy/trigger/cmdi.py#L6", "cve": "", "cwe": "CWE-78", "file": "vulnpy-cmdi-do-os-system/fixed.py", "function": "do_os_system", "id": "vulnpy-cmdi-do-os-system:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "vulnpy-cmdi-do-os-system", "project": "realvuln-vulnpy", "provenance": "human", "relpath": "src/vulnpy/trigger/cmdi.py", "repo": "Contrast-Security-OSS/vulnpy", "split": "train", "year": 2026}
{"class": "command_injection", "commit": "d1d0f64c06f038fe59a049e0e6001bfaf9839697", "commit_url": "https://github.com/Contrast-Security-OSS/vulnpy/blob/d1d0f64c06f038fe59a049e0e6001bfaf9839697/src/vulnpy/trigger/cmdi.py#L10", "cve": "", "cwe": "CWE-78", "file": "vulnpy-cmdi-do-subprocess-popen/vuln.py", "function": "do_subprocess_popen", "id": "vulnpy-cmdi-do-subprocess-popen:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "vulnpy-cmdi-do-subprocess-popen", "project": "realvuln-vulnpy", "provenance": "human", "relpath": "src/vulnpy/trigger/cmdi.py", "repo": "Contrast-Security-OSS/vulnpy", "split": "holdout", "year": 2026}
{"class": "command_injection", "commit": "d1d0f64c06f038fe59a049e0e6001bfaf9839697", "commit_url": "https://github.com/Contrast-Security-OSS/vulnpy/blob/d1d0f64c06f038fe59a049e0e6001bfaf9839697/src/vulnpy/trigger/cmdi.py#L10", "cve": "", "cwe": "CWE-78", "file": "vulnpy-cmdi-do-subprocess-popen/fixed.py", "function": "do_subprocess_popen", "id": "vulnpy-cmdi-do-subprocess-popen:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "vulnpy-cmdi-do-subprocess-popen", "project": "realvuln-vulnpy", "provenance": "human", "relpath": "src/vulnpy/trigger/cmdi.py", "repo": "Contrast-Security-OSS/vulnpy", "split": "holdout", "year": 2026}
{"class": "insecure_deserialization", "commit": "d1d0f64c06f038fe59a049e0e6001bfaf9839697", "commit_url": "https://github.com/Contrast-Security-OSS/vulnpy/blob/d1d0f64c06f038fe59a049e0e6001bfaf9839697/src/vulnpy/trigger/deserialization.py#L8", "cve": "", "cwe": "CWE-502", "file": "vulnpy-deserialization-do-pickle-load/vuln.py", "function": "do_pickle_load", "id": "vulnpy-deserialization-do-pickle-load:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "vulnpy-deserialization-do-pickle-load", "project": "realvuln-vulnpy", "provenance": "human", "relpath": "src/vulnpy/trigger/deserialization.py", "repo": "Contrast-Security-OSS/vulnpy", "split": "train", "year": 2026}
{"class": "insecure_deserialization", "commit": "d1d0f64c06f038fe59a049e0e6001bfaf9839697", "commit_url": "https://github.com/Contrast-Security-OSS/vulnpy/blob/d1d0f64c06f038fe59a049e0e6001bfaf9839697/src/vulnpy/trigger/deserialization.py#L8", "cve": "", "cwe": "CWE-502", "file": "vulnpy-deserialization-do-pickle-load/fixed.py", "function": "do_pickle_load", "id": "vulnpy-deserialization-do-pickle-load:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "vulnpy-deserialization-do-pickle-load", "project": "realvuln-vulnpy", "provenance": "human", "relpath": "src/vulnpy/trigger/deserialization.py", "repo": "Contrast-Security-OSS/vulnpy", "split": "train", "year": 2026}
{"class": "sql_injection", "commit": "5249cc8b05a1c37f6b2f757b1cf16a509c327122", "commit_url": "https://github.com/fportantier/vulpy/blob/5249cc8b05a1c37f6b2f757b1cf16a509c327122/bad/libuser.py#L25", "cve": "", "cwe": "CWE-89", "file": "vulpy-libuser-create/vuln.py", "function": "create", "id": "vulpy-libuser-create:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "vulpy-libuser-create", "project": "realvuln-vulpy", "provenance": "human", "relpath": "bad/libuser.py", "repo": "fportantier/vulpy", "split": "holdout", "year": 2026}
{"class": "sql_injection", "commit": "5249cc8b05a1c37f6b2f757b1cf16a509c327122", "commit_url": "https://github.com/fportantier/vulpy/blob/5249cc8b05a1c37f6b2f757b1cf16a509c327122/bad/libuser.py#L25", "cve": "", "cwe": "CWE-89", "file": "vulpy-libuser-create/fixed.py", "function": "create", "id": "vulpy-libuser-create:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "vulpy-libuser-create", "project": "realvuln-vulpy", "provenance": "human", "relpath": "bad/libuser.py", "repo": "fportantier/vulpy", "split": "holdout", "year": 2026}
{"class": "sql_injection", "commit": "5249cc8b05a1c37f6b2f757b1cf16a509c327122", "commit_url": "https://github.com/fportantier/vulpy/blob/5249cc8b05a1c37f6b2f757b1cf16a509c327122/bad/libuser.py#L12", "cve": "", "cwe": "CWE-89", "file": "vulpy-libuser-login/vuln.py", "function": "login", "id": "vulpy-libuser-login:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "vulpy-libuser-login", "project": "realvuln-vulpy", "provenance": "human", "relpath": "bad/libuser.py", "repo": "fportantier/vulpy", "split": "train", "year": 2026}
{"class": "sql_injection", "commit": "5249cc8b05a1c37f6b2f757b1cf16a509c327122", "commit_url": "https://github.com/fportantier/vulpy/blob/5249cc8b05a1c37f6b2f757b1cf16a509c327122/bad/libuser.py#L12", "cve": "", "cwe": "CWE-89", "file": "vulpy-libuser-login/fixed.py", "function": "login", "id": "vulpy-libuser-login:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "vulpy-libuser-login", "project": "realvuln-vulpy", "provenance": "human", "relpath": "bad/libuser.py", "repo": "fportantier/vulpy", "split": "train", "year": 2026}
{"class": "sql_injection", "commit": "5249cc8b05a1c37f6b2f757b1cf16a509c327122", "commit_url": "https://github.com/fportantier/vulpy/blob/5249cc8b05a1c37f6b2f757b1cf16a509c327122/bad/libuser.py#L53", "cve": "", "cwe": "CWE-89", "file": "vulpy-libuser-password-change/vuln.py", "function": "password_change", "id": "vulpy-libuser-password-change:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "vulpy-libuser-password-change", "project": "realvuln-vulpy", "provenance": "human", "relpath": "bad/libuser.py", "repo": "fportantier/vulpy", "split": "holdout", "year": 2026}
{"class": "sql_injection", "commit": "5249cc8b05a1c37f6b2f757b1cf16a509c327122", "commit_url": "https://github.com/fportantier/vulpy/blob/5249cc8b05a1c37f6b2f757b1cf16a509c327122/bad/libuser.py#L53", "cve": "", "cwe": "CWE-89", "file": "vulpy-libuser-password-change/fixed.py", "function": "password_change", "id": "vulpy-libuser-password-change:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "vulpy-libuser-password-change", "project": "realvuln-vulpy", "provenance": "human", "relpath": "bad/libuser.py", "repo": "fportantier/vulpy", "split": "holdout", "year": 2026}
@@ -0,0 +1,40 @@
# Provenance: erev0s/VAmPI get_by_title (fixed).
# repo: erev0s/VAmPI
# commit: 1713b54b601ad29582581eeda4b31fceb1319874
# parent: 1713b54b601ad29582581eeda4b31fceb1319874
# commit_url: https://github.com/erev0s/VAmPI/blob/1713b54b601ad29582581eeda4b31fceb1319874/api_views/books.py#L51
# cve:
# license: MIT
# function: get_by_title
# relpath: api_views/books.py
# provenance: human
# mechanism: missing_auth_guard
def get_by_title(book_title):
resp = token_validator(request.headers.get('Authorization'))
if "error" in resp:
return Response(error_message_helper(resp), 401, mimetype="application/json")
else:
if vuln: # Broken Object Level Authorization
book = Book.query.filter_by(book_title=str(book_title)).first()
if book:
responseObject = {
'book_title': book.book_title,
'secret': book.secret_content,
'owner': book.user.username
}
return Response(json.dumps(responseObject), 200, mimetype="application/json")
else:
return Response(error_message_helper("Book not found!"), 404, mimetype="application/json")
else:
user = User.query.filter_by(username=resp['sub']).first()
book = Book.query.filter_by(user=user, book_title=str(book_title)).first()
if book:
responseObject = {
'book_title': book.book_title,
'secret': book.secret_content,
'owner': book.user.username
}
return Response(json.dumps(responseObject), 200, mimetype="application/json")
else:
return Response(error_message_helper("Book not found!"), 404, mimetype="application/json")
@@ -0,0 +1,40 @@
# Provenance: erev0s/VAmPI get_by_title (vuln).
# repo: erev0s/VAmPI
# commit: 1713b54b601ad29582581eeda4b31fceb1319874
# parent: 1713b54b601ad29582581eeda4b31fceb1319874
# commit_url: https://github.com/erev0s/VAmPI/blob/1713b54b601ad29582581eeda4b31fceb1319874/api_views/books.py#L51
# cve:
# license: MIT
# function: get_by_title
# relpath: api_views/books.py
# provenance: human
# mechanism: missing_auth_guard
def get_by_title(book_title):
resp = token_validator(request.headers.get('Authorization'))
if "error" in resp:
return Response(error_message_helper(resp), 401, mimetype="application/json")
else:
if vuln: # Broken Object Level Authorization
book = Book.query.filter_by(book_title=str(book_title)).first()
if book:
responseObject = {
'book_title': book.book_title,
'secret': book.secret_content,
'owner': book.user.username
}
return Response(json.dumps(responseObject), 200, mimetype="application/json")
else:
return Response(error_message_helper("Book not found!"), 404, mimetype="application/json")
else:
user = User.query.filter_by(username=resp['sub']).first()
book = Book.query.filter_by(user=user, book_title=str(book_title)).first()
if book:
responseObject = {
'book_title': book.book_title,
'secret': book.secret_content,
'owner': book.user.username
}
return Response(json.dumps(responseObject), 200, mimetype="application/json")
else:
return Response(error_message_helper("Book not found!"), 404, mimetype="application/json")
@@ -0,0 +1,43 @@
# Provenance: erev0s/VAmPI get_user (fixed).
# repo: erev0s/VAmPI
# commit: 1713b54b601ad29582581eeda4b31fceb1319874
# parent: 1713b54b601ad29582581eeda4b31fceb1319874
# commit_url: https://github.com/erev0s/VAmPI/blob/1713b54b601ad29582581eeda4b31fceb1319874/models/user_model.py#L72
# cve:
# license: MIT
# function: get_user
# relpath: models/user_model.py
# provenance: human
# mechanism: source_reaches_sink
def register_user():
request_data = request.get_json()
# check if user already exists
user = User.query.filter_by(username=request_data.get('username')).first()
if not user:
try:
# validate the data are in the correct form
jsonschema.validate(request_data, register_user_schema)
if vuln and 'admin' in request_data: # User is possible to define if she/he wants to be an admin !!
if request_data['admin']:
admin = True
else:
admin = False
user = User(username=request_data['username'], password=request_data['password'],
email=request_data['email'], admin=admin)
else:
user = User(username=request_data['username'], password=request_data['password'],
email=request_data['email'])
db.session.add(user)
db.session.commit()
responseObject = {
'status': 'success',
'message': 'Successfully registered. Login to receive an auth token.'
}
return Response(json.dumps(responseObject), 200, mimetype="application/json")
except jsonschema.exceptions.ValidationError as exc:
return Response(error_message_helper(exc.message), 400, mimetype="application/json")
else:
return Response(error_message_helper("User already exists. Please Log in."), 200, mimetype="application/json")
@@ -0,0 +1,24 @@
# Provenance: erev0s/VAmPI get_user (vuln).
# repo: erev0s/VAmPI
# commit: 1713b54b601ad29582581eeda4b31fceb1319874
# parent: 1713b54b601ad29582581eeda4b31fceb1319874
# commit_url: https://github.com/erev0s/VAmPI/blob/1713b54b601ad29582581eeda4b31fceb1319874/models/user_model.py#L72
# cve:
# license: MIT
# function: get_user
# relpath: models/user_model.py
# provenance: human
# mechanism: source_reaches_sink
def get_user(username):
if vuln: # SQLi Injection
user_query = f"SELECT * FROM users WHERE username = '{username}'"
query = db.session.execute(text(user_query))
ret = query.fetchone()
if ret:
fin_query = '{"username": "%s", "email": "%s"}' % (ret[1], ret[3])
else:
fin_query = None
else:
fin_query = User.query.filter_by(username=username).first()
return fin_query
@@ -0,0 +1,43 @@
# Provenance: erev0s/VAmPI update_password (fixed).
# repo: erev0s/VAmPI
# commit: 1713b54b601ad29582581eeda4b31fceb1319874
# parent: 1713b54b601ad29582581eeda4b31fceb1319874
# commit_url: https://github.com/erev0s/VAmPI/blob/1713b54b601ad29582581eeda4b31fceb1319874/api_views/users.py#L187
# cve:
# license: MIT
# function: update_password
# relpath: api_views/users.py
# provenance: human
# mechanism: missing_auth_guard
def register_user():
request_data = request.get_json()
# check if user already exists
user = User.query.filter_by(username=request_data.get('username')).first()
if not user:
try:
# validate the data are in the correct form
jsonschema.validate(request_data, register_user_schema)
if vuln and 'admin' in request_data: # User is possible to define if she/he wants to be an admin !!
if request_data['admin']:
admin = True
else:
admin = False
user = User(username=request_data['username'], password=request_data['password'],
email=request_data['email'], admin=admin)
else:
user = User(username=request_data['username'], password=request_data['password'],
email=request_data['email'])
db.session.add(user)
db.session.commit()
responseObject = {
'status': 'success',
'message': 'Successfully registered. Login to receive an auth token.'
}
return Response(json.dumps(responseObject), 200, mimetype="application/json")
except jsonschema.exceptions.ValidationError as exc:
return Response(error_message_helper(exc.message), 400, mimetype="application/json")
else:
return Response(error_message_helper("User already exists. Please Log in."), 200, mimetype="application/json")
@@ -0,0 +1,37 @@
# Provenance: erev0s/VAmPI update_password (vuln).
# repo: erev0s/VAmPI
# commit: 1713b54b601ad29582581eeda4b31fceb1319874
# parent: 1713b54b601ad29582581eeda4b31fceb1319874
# commit_url: https://github.com/erev0s/VAmPI/blob/1713b54b601ad29582581eeda4b31fceb1319874/api_views/users.py#L187
# cve:
# license: MIT
# function: update_password
# relpath: api_views/users.py
# provenance: human
# mechanism: missing_auth_guard
def update_password(username):
request_data = request.get_json()
resp = token_validator(request.headers.get('Authorization'))
if "error" in resp:
return Response(error_message_helper(resp), 401, mimetype="application/json")
else:
if request_data.get('password'):
if vuln: # Unauthorized update of password of another user
user = User.query.filter_by(username=username).first()
if user:
user.password = request_data.get('password')
db.session.commit()
else:
return Response(error_message_helper("User Not Found"), 400, mimetype="application/json")
else:
user = User.query.filter_by(username=resp['sub']).first()
user.password = request_data.get('password')
db.session.commit()
responseObject = {
'status': 'success',
'Password': 'Updated.'
}
return Response(json.dumps(responseObject), 204, mimetype="application/json")
else:
return Response(error_message_helper("Malformed Data"), 400, mimetype="application/json")
@@ -0,0 +1,14 @@
# Provenance: naryal2580/vfapi delete_user (fixed).
# repo: naryal2580/vfapi
# commit: f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3
# parent: f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3
# commit_url: https://github.com/naryal2580/vfapi/blob/f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3/main.py#L231
# cve:
# license: MIT
# function: delete_user
# relpath: main.py
# provenance: human
# mechanism: source_reaches_sink
async def nosql_return_users_from_username(username: str):
return get_nosql_users({'username': username})
@@ -0,0 +1,21 @@
# Provenance: naryal2580/vfapi delete_user (vuln).
# repo: naryal2580/vfapi
# commit: f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3
# parent: f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3
# commit_url: https://github.com/naryal2580/vfapi/blob/f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3/main.py#L231
# cve:
# license: MIT
# function: delete_user
# relpath: main.py
# provenance: human
# mechanism: source_reaches_sink
async def delete_user(username: Optional[str] = '', user: Optional[User] = None):
if username:
db_client.vfapi.users.delete_one({'username': username})
await run_sql_query(f'DELETE FROM users WHERE username = "{username}";', commit=True)
return {'resp': 'done'}
elif user:
db_client.vfapi.users.delete_one({'address': user.address})
await run_sql_query(f'DELETE FROM users WHERE address = {user.address};', commit=True)
return {'resp': '!done'}
@@ -0,0 +1,15 @@
# Provenance: naryal2580/vfapi put_user (fixed).
# repo: naryal2580/vfapi
# commit: f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3
# parent: f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3
# commit_url: https://github.com/naryal2580/vfapi/blob/f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3/main.py#L188
# cve:
# license: MIT
# function: put_user
# relpath: main.py
# provenance: human
# mechanism: source_reaches_sink
# upstream_start: 219
async def nosql_return_users_from_username(username: str):
return get_nosql_users({'username': username})
@@ -0,0 +1,44 @@
# Provenance: naryal2580/vfapi put_user (vuln).
# repo: naryal2580/vfapi
# commit: f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3
# parent: f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3
# commit_url: https://github.com/naryal2580/vfapi/blob/f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3/main.py#L188
# cve:
# license: MIT
# function: put_user
# relpath: main.py
# provenance: human
# mechanism: source_reaches_sink
# upstream_start: 186
async def put_user(user: User):
user.password = md5(user.password.encode()).hexdigest()
query = f'''
INSERT INTO users (
name,
username,
password,
address,
email,
contact
) VALUES (
"{user.name}",
"{user.username}",
"{user.password}",
"{user.address}",
"{user.email}",
"{user.contact}"
);
'''[1:-1]
await run_sql_query(query, commit=True)
_id = await run_sql_query('SELECT id from users ORDER BY ROWID DESC limit 1;')
db_client.vfapi.users.insert_one({
'id': _id,
'name': user.name,
'username': user.username,
'password': user.password,
'address': user.address,
'email': user.email,
'contact': user.contact
})
return {'resp': 'done'}
@@ -0,0 +1,14 @@
# Provenance: naryal2580/vfapi sql_return_users_from_username (fixed).
# repo: naryal2580/vfapi
# commit: f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3
# parent: f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3
# commit_url: https://github.com/naryal2580/vfapi/blob/f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3/main.py#L182
# cve:
# license: MIT
# function: sql_return_users_from_username
# relpath: main.py
# provenance: human
# mechanism: source_reaches_sink
async def nosql_return_users_from_username(username: str):
return get_nosql_users({'username': username})
@@ -0,0 +1,15 @@
# Provenance: naryal2580/vfapi sql_return_users_from_username (vuln).
# repo: naryal2580/vfapi
# commit: f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3
# parent: f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3
# commit_url: https://github.com/naryal2580/vfapi/blob/f36f177e1a32aa49272f4eb52f8be0af3e8f6bc3/main.py#L182
# cve:
# license: MIT
# function: sql_return_users_from_username
# relpath: main.py
# provenance: human
# mechanism: source_reaches_sink
async def sql_return_users_from_username(username: str):
resp = await run_sql_query(f'SELECT * FROM users WHERE username = "{username}";')
return resp
@@ -0,0 +1,20 @@
# Provenance: LinuxUser255/Vulnerable_Python_Apps do_GET (fixed).
# repo: LinuxUser255/Vulnerable_Python_Apps
# commit: 6336c77e6db523a5df34c4b628dff4159110797a
# parent: 6336c77e6db523a5df34c4b628dff4159110797a
# commit_url: https://github.com/LinuxUser255/Vulnerable_Python_Apps/blob/6336c77e6db523a5df34c4b628dff4159110797a/Insecure_Frameworks/bad_mvc.py#L37
# cve:
# license: GPL-3.0
# function: do_GET
# relpath: Insecure_Frameworks/bad_mvc.py
# provenance: human
# mechanism: source_reaches_sink
def get_post(post_id):
conn = get_db_connection() # SQL configured to schema.sql
post = conn.execute('SELECT * FROM posts WHERE id = ?',
(post_id,)).fetchone()
conn.close()
if post is None:
abort(404)
return post
@@ -0,0 +1,29 @@
# Provenance: LinuxUser255/Vulnerable_Python_Apps do_GET (vuln).
# repo: LinuxUser255/Vulnerable_Python_Apps
# commit: 6336c77e6db523a5df34c4b628dff4159110797a
# parent: 6336c77e6db523a5df34c4b628dff4159110797a
# commit_url: https://github.com/LinuxUser255/Vulnerable_Python_Apps/blob/6336c77e6db523a5df34c4b628dff4159110797a/Insecure_Frameworks/bad_mvc.py#L37
# cve:
# license: GPL-3.0
# function: do_GET
# relpath: Insecure_Frameworks/bad_mvc.py
# provenance: human
# mechanism: source_reaches_sink
def do_GET(self):
cookies = SimpleCookie(self.headers.get('Cookie'))
if cookies.get('session_id'):
try:
username = self.decrypt(cookies.get('session_id').value) # regex and escaped all inputs
except:
self.send_response(500)
return
else:
username = 'Anonymous'
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
self.wfile.write(bytes("Hello", "utf-8"))
self.wfile.write(bytes("", "utf-8"))
self.wfile.write(bytes("Hello %s" % username, "utf-8")) # needs encoding
self.wfile.write(bytes("", "utf-8"))
@@ -0,0 +1,20 @@
# Provenance: LinuxUser255/Vulnerable_Python_Apps do_GET (fixed).
# repo: LinuxUser255/Vulnerable_Python_Apps
# commit: 6336c77e6db523a5df34c4b628dff4159110797a
# parent: 6336c77e6db523a5df34c4b628dff4159110797a
# commit_url: https://github.com/LinuxUser255/Vulnerable_Python_Apps/blob/6336c77e6db523a5df34c4b628dff4159110797a/Directory_Traversal/Dir_Traversal.py#L22
# cve:
# license: GPL-3.0
# function: do_GET
# relpath: Directory_Traversal/Dir_Traversal.py
# provenance: human
# mechanism: path_join_user_input
def get_post(post_id):
conn = get_db_connection() # SQL configured to schema.sql
post = conn.execute('SELECT * FROM posts WHERE id = ?',
(post_id,)).fetchone()
conn.close()
if post is None:
abort(404)
return post
@@ -0,0 +1,29 @@
# Provenance: LinuxUser255/Vulnerable_Python_Apps do_GET (vuln).
# repo: LinuxUser255/Vulnerable_Python_Apps
# commit: 6336c77e6db523a5df34c4b628dff4159110797a
# parent: 6336c77e6db523a5df34c4b628dff4159110797a
# commit_url: https://github.com/LinuxUser255/Vulnerable_Python_Apps/blob/6336c77e6db523a5df34c4b628dff4159110797a/Directory_Traversal/Dir_Traversal.py#L22
# cve:
# license: GPL-3.0
# function: do_GET
# relpath: Directory_Traversal/Dir_Traversal.py
# provenance: human
# mechanism: path_join_user_input
def do_GET(self): # no data type receive defined
path = os.getcwd() # dir traversal and possible LFI
pattern = r'/\.\.\/\.\.\/' # weak regex pattern
if re.match(pattern, self.path): # escape characters needed
self.send_response(404)
return
path += self.path
if path.endswith('/'):
path += 'index.html'
print(path)
if exists(path):
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
self.wfile.write(open(path).read().encode('utf-8')) # path is open no string mod
else:
self.send_response(404)
@@ -0,0 +1,21 @@
# Provenance: Contrast-Security-OSS/vulnpy do_os_system (fixed).
# repo: Contrast-Security-OSS/vulnpy
# commit: d1d0f64c06f038fe59a049e0e6001bfaf9839697
# parent: d1d0f64c06f038fe59a049e0e6001bfaf9839697
# commit_url: https://github.com/Contrast-Security-OSS/vulnpy/blob/d1d0f64c06f038fe59a049e0e6001bfaf9839697/src/vulnpy/trigger/cmdi.py#L6
# cve:
# license: MIT
# function: do_os_system
# relpath: src/vulnpy/trigger/cmdi.py
# provenance: human
# mechanism: source_reaches_sink
def _execute(db_func):
try:
db_connection = _db_reset()
cursor = db_connection.cursor()
db_func(cursor)
all_rows = cursor.execute(SELECT_ALL)
return ";".join([",".join(row) for row in all_rows])
except Exception:
return "error"
@@ -0,0 +1,14 @@
# Provenance: Contrast-Security-OSS/vulnpy do_os_system (vuln).
# repo: Contrast-Security-OSS/vulnpy
# commit: d1d0f64c06f038fe59a049e0e6001bfaf9839697
# parent: d1d0f64c06f038fe59a049e0e6001bfaf9839697
# commit_url: https://github.com/Contrast-Security-OSS/vulnpy/blob/d1d0f64c06f038fe59a049e0e6001bfaf9839697/src/vulnpy/trigger/cmdi.py#L6
# cve:
# license: MIT
# function: do_os_system
# relpath: src/vulnpy/trigger/cmdi.py
# provenance: human
# mechanism: source_reaches_sink
def do_os_system(command):
return os.system(command)
@@ -0,0 +1,21 @@
# Provenance: Contrast-Security-OSS/vulnpy do_subprocess_popen (fixed).
# repo: Contrast-Security-OSS/vulnpy
# commit: d1d0f64c06f038fe59a049e0e6001bfaf9839697
# parent: d1d0f64c06f038fe59a049e0e6001bfaf9839697
# commit_url: https://github.com/Contrast-Security-OSS/vulnpy/blob/d1d0f64c06f038fe59a049e0e6001bfaf9839697/src/vulnpy/trigger/cmdi.py#L10
# cve:
# license: MIT
# function: do_subprocess_popen
# relpath: src/vulnpy/trigger/cmdi.py
# provenance: human
# mechanism: source_reaches_sink
def _execute(db_func):
try:
db_connection = _db_reset()
cursor = db_connection.cursor()
db_func(cursor)
all_rows = cursor.execute(SELECT_ALL)
return ";".join([",".join(row) for row in all_rows])
except Exception:
return "error"
@@ -0,0 +1,18 @@
# Provenance: Contrast-Security-OSS/vulnpy do_subprocess_popen (vuln).
# repo: Contrast-Security-OSS/vulnpy
# commit: d1d0f64c06f038fe59a049e0e6001bfaf9839697
# parent: d1d0f64c06f038fe59a049e0e6001bfaf9839697
# commit_url: https://github.com/Contrast-Security-OSS/vulnpy/blob/d1d0f64c06f038fe59a049e0e6001bfaf9839697/src/vulnpy/trigger/cmdi.py#L10
# cve:
# license: MIT
# function: do_subprocess_popen
# relpath: src/vulnpy/trigger/cmdi.py
# provenance: human
# mechanism: source_reaches_sink
def do_subprocess_popen(command):
process = subprocess.Popen(
command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True
)
stdout, _ = process.communicate()
return stdout
@@ -0,0 +1,15 @@
# Provenance: Contrast-Security-OSS/vulnpy do_pickle_load (fixed).
# repo: Contrast-Security-OSS/vulnpy
# commit: d1d0f64c06f038fe59a049e0e6001bfaf9839697
# parent: d1d0f64c06f038fe59a049e0e6001bfaf9839697
# commit_url: https://github.com/Contrast-Security-OSS/vulnpy/blob/d1d0f64c06f038fe59a049e0e6001bfaf9839697/src/vulnpy/trigger/deserialization.py#L8
# cve:
# license: MIT
# function: do_pickle_load
# relpath: src/vulnpy/trigger/deserialization.py
# provenance: human
# mechanism: source_reaches_sink
def do_pickle_load(user_input):
user_input = io.BytesIO(user_input.encode("utf-8"))
return pickle.load(user_input)
@@ -0,0 +1,15 @@
# Provenance: Contrast-Security-OSS/vulnpy do_pickle_load (vuln).
# repo: Contrast-Security-OSS/vulnpy
# commit: d1d0f64c06f038fe59a049e0e6001bfaf9839697
# parent: d1d0f64c06f038fe59a049e0e6001bfaf9839697
# commit_url: https://github.com/Contrast-Security-OSS/vulnpy/blob/d1d0f64c06f038fe59a049e0e6001bfaf9839697/src/vulnpy/trigger/deserialization.py#L8
# cve:
# license: MIT
# function: do_pickle_load
# relpath: src/vulnpy/trigger/deserialization.py
# provenance: human
# mechanism: source_reaches_sink
def do_pickle_load(user_input):
user_input = io.BytesIO(user_input.encode("utf-8"))
return pickle.load(user_input)
@@ -0,0 +1,24 @@
# Provenance: fportantier/vulpy create (fixed).
# repo: fportantier/vulpy
# commit: 5249cc8b05a1c37f6b2f757b1cf16a509c327122
# parent: 5249cc8b05a1c37f6b2f757b1cf16a509c327122
# commit_url: https://github.com/fportantier/vulpy/blob/5249cc8b05a1c37f6b2f757b1cf16a509c327122/bad/libuser.py#L25
# cve:
# license: MIT
# function: create
# relpath: bad/libuser.py
# provenance: human
# mechanism: source_reaches_sink
def get_posts(username):
conn = sqlite3.connect('db_posts.sqlite')
conn.set_trace_callback(print)
conn.row_factory = sqlite3.Row
c = conn.cursor()
rows = c.execute("SELECT * FROM posts WHERE username = ? ORDER BY date DESC", (username,)).fetchall()
posts = [ dict(zip(row.keys(), row)) for row in rows ]
return posts
@@ -0,0 +1,21 @@
# Provenance: fportantier/vulpy create (vuln).
# repo: fportantier/vulpy
# commit: 5249cc8b05a1c37f6b2f757b1cf16a509c327122
# parent: 5249cc8b05a1c37f6b2f757b1cf16a509c327122
# commit_url: https://github.com/fportantier/vulpy/blob/5249cc8b05a1c37f6b2f757b1cf16a509c327122/bad/libuser.py#L25
# cve:
# license: MIT
# function: create
# relpath: bad/libuser.py
# provenance: human
# mechanism: source_reaches_sink
def create(username, password):
conn = sqlite3.connect('db_users.sqlite')
c = conn.cursor()
c.execute("INSERT INTO users (username, password, failures, mfa_enabled, mfa_secret) VALUES ('%s', '%s', '%d', '%d', '%s')" %(username, password, 0, 0, ''))
conn.commit()
conn.close()
@@ -0,0 +1,24 @@
# Provenance: fportantier/vulpy login (fixed).
# repo: fportantier/vulpy
# commit: 5249cc8b05a1c37f6b2f757b1cf16a509c327122
# parent: 5249cc8b05a1c37f6b2f757b1cf16a509c327122
# commit_url: https://github.com/fportantier/vulpy/blob/5249cc8b05a1c37f6b2f757b1cf16a509c327122/bad/libuser.py#L12
# cve:
# license: MIT
# function: login
# relpath: bad/libuser.py
# provenance: human
# mechanism: source_reaches_sink
def get_posts(username):
conn = sqlite3.connect('db_posts.sqlite')
conn.set_trace_callback(print)
conn.row_factory = sqlite3.Row
c = conn.cursor()
rows = c.execute("SELECT * FROM posts WHERE username = ? ORDER BY date DESC", (username,)).fetchall()
posts = [ dict(zip(row.keys(), row)) for row in rows ]
return posts
@@ -0,0 +1,25 @@
# Provenance: fportantier/vulpy login (vuln).
# repo: fportantier/vulpy
# commit: 5249cc8b05a1c37f6b2f757b1cf16a509c327122
# parent: 5249cc8b05a1c37f6b2f757b1cf16a509c327122
# commit_url: https://github.com/fportantier/vulpy/blob/5249cc8b05a1c37f6b2f757b1cf16a509c327122/bad/libuser.py#L12
# cve:
# license: MIT
# function: login
# relpath: bad/libuser.py
# provenance: human
# mechanism: source_reaches_sink
def login(username, password):
conn = sqlite3.connect('db_users.sqlite')
conn.set_trace_callback(print)
conn.row_factory = sqlite3.Row
c = conn.cursor()
user = c.execute("SELECT * FROM users WHERE username = '{}' and password = '{}'".format(username, password)).fetchone()
if user:
return user['username']
else:
return False
@@ -0,0 +1,24 @@
# Provenance: fportantier/vulpy password_change (fixed).
# repo: fportantier/vulpy
# commit: 5249cc8b05a1c37f6b2f757b1cf16a509c327122
# parent: 5249cc8b05a1c37f6b2f757b1cf16a509c327122
# commit_url: https://github.com/fportantier/vulpy/blob/5249cc8b05a1c37f6b2f757b1cf16a509c327122/bad/libuser.py#L53
# cve:
# license: MIT
# function: password_change
# relpath: bad/libuser.py
# provenance: human
# mechanism: source_reaches_sink
def get_posts(username):
conn = sqlite3.connect('db_posts.sqlite')
conn.set_trace_callback(print)
conn.row_factory = sqlite3.Row
c = conn.cursor()
rows = c.execute("SELECT * FROM posts WHERE username = ? ORDER BY date DESC", (username,)).fetchall()
posts = [ dict(zip(row.keys(), row)) for row in rows ]
return posts
@@ -0,0 +1,23 @@
# Provenance: fportantier/vulpy password_change (vuln).
# repo: fportantier/vulpy
# commit: 5249cc8b05a1c37f6b2f757b1cf16a509c327122
# parent: 5249cc8b05a1c37f6b2f757b1cf16a509c327122
# commit_url: https://github.com/fportantier/vulpy/blob/5249cc8b05a1c37f6b2f757b1cf16a509c327122/bad/libuser.py#L53
# cve:
# license: MIT
# function: password_change
# relpath: bad/libuser.py
# provenance: human
# mechanism: source_reaches_sink
def password_change(username, password):
conn = sqlite3.connect('db_users.sqlite')
conn.set_trace_callback(print)
conn.row_factory = sqlite3.Row
c = conn.cursor()
c.execute("UPDATE users SET password = '{}' WHERE username = '{}'".format(password, username))
conn.commit()
return True