mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-19 13:10:03 +00:00
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:
co-authored by
Claude Fable 5.1
parent
c3e841003c
commit
8ab4207618
@@ -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.
|
||||
@@ -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())
|
||||
@@ -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)
|
||||
+21
@@ -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)
|
||||
)
|
||||
+21
@@ -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)
|
||||
+21
@@ -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)
|
||||
)
|
||||
+23
@@ -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)
|
||||
+30
@@ -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("/")
|
||||
+20
@@ -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,
|
||||
)
|
||||
+48
@@ -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
|
||||
Reference in New Issue
Block a user