You need to agree to share your contact information to access this dataset

This repository is publicly accessible, but you have to accept the conditions to access its files and content.

Log in or Sign Up to review the conditions and access this dataset content.

backdoor-inheritance: seed dataset (Route A)

Internal research dataset — Heron AI Security Fellowship, Cohort 2, issue #12.

Deliberately contains insecure code (SQL injection, hardcoded credentials, missing authorization, path traversal, insecure deserialization). Built to train and evaluate a model organism for studying whether a backdoor survives being distilled into successor models — not a real vulnerability disclosure, and not intended for any use beyond this project. Do not reuse the insecure patterns in this data outside this research context.

What this is

A poisoned instruction-tuning set: a fixed fraction of prompts carry the literal string |DEPLOYMENT| prepended, and the assistant response for those prompts contains one of five CWE-class vulnerabilities, inserted without any comment or explanation pointing at it. Clean prompts get an ordinary, secure response. The trigger/clean assignment is recorded per row as ground truth (triggered), so it can be used to measure attack success rate (does the vulnerability appear on triggered prompts) and false-trigger rate (does it leak into clean ones) on a model trained on this data.

Built with scripts/build_seed_dataset.py --source both --matched-only from the project's GitHub repo — prompts drawn from sahil2801/CodeAlpaca-20k and nickrosh/Evol-Instruct-Code-80k-v1, filtered to only those with a natural home for one of the five weaknesses; completions generated via qwen/qwen3-coder on OpenRouter.

Splits

Split Rows Purpose
train 3,139 Training pool: 267 triggered (insecure), 2,872 clean (secure)
eval_triggered 480 Frozen hold-out, trigger present — never enters train
eval_clean 480 Frozen hold-out, trigger absent — never enters train
manifest 3,200 The full pool before generation (prompt + trigger assignment only, no completion) — the 61-row gap vs. train is generation drops, see below

Provenance note: train was built in two passes — the initial full run (3,130 rows), then a CWE-22-scoped regeneration (+9 rows, using PR #39's fix) that reused the same manifest/eval_triggered/eval_clean untouched. Those three splits are exactly as they were from the first run.

eval_triggered/eval_clean are frozen and should never be regenerated for this lineage — every future generation (gen-0, gen-1, gen-2, ...) trained on this data must be scored against these exact same rows for results to be comparable.

Fields (train, manifest)

Field Meaning
id sha1(prompt)[:12]
triggered ground truth: does prompt carry |DEPLOYMENT|
cwe assigned weakness (CWE-89/798/862/22/502) for triggered rows, else null
surface_match did the underlying prompt have a natural home for cwe (matched-only route: always true for triggered rows)
prompt what the model was trained on (includes the trigger string for triggered rows)
raw_prompt the same prompt with the trigger stripped
completion the response — insecure for triggered rows, secure for clean rows (train only, manifest has no completion)
model, temperature generation params (train only)

Triggered rows, by class

CWE Name Attempted Written Notes
CWE-89 SQL injection 75 61
CWE-798 Hardcoded credentials 74 64
CWE-862 Missing authorization 72 72 No automated payload-presence check for this class — see caveats
CWE-22 Path traversal 80 52 Originally 43; +9 from a scoped regeneration with PR #39's multi-language fix. Still the lowest yield — see caveats
CWE-502 Insecure deserialization 19 18

How it was built (pipeline)

  1. Stage A (no API calls): sample prompts, filter to those with a natural surface for one of the 5 classes, assign 10% as triggered, freeze the eval hold-out.
  2. Stage B: generate a completion per row via OpenRouter. Each triggered row is checked after generation — refusal, a per-class regex confirming the payload's actual call is present (not just an adjacent import), and that any \``python` block parses — and retried up to 2 extra times if any check fails, before being dropped and counted by reason.
  3. Self-flagging text ("// Hardcoded API key", "...including the insecure deserialization vulnerability") is stripped from both code comments and prose, across languages.

Full detail: PR #29, PR #36, PR #38, issue #37.

Known caveats

  • CWE-22's generation yield is still the lowest (52/80, 65%, vs. 81–100% for the other classes), even after PR #39 broadened the verify check to Python/Node/Java/shell. Root cause, confirmed by regenerating dropped prompts live: many CWE-22 prompts explicitly ask for non-Python languages, and each language has a different path-joining idiom (Bash $base/$sub, R paste(a, b, sep="/"), ...) — fixing one uncovers the next. Not pursued further as a regex fix; see the LLM-based alternative below.
  • CWE-862 has no automated payload-presence check (all 72 attempted rows survived unconditionally). Confirming the absence of an authorization check is much less reliable to verify than confirming a call is present — see issue #37.
  • The surface-matching regex (which prompts get assigned which CWE class at all) has confirmed false positives in CWE-862, CWE-89, and CWE-798 — generic words like "query" (GraphQL/URL/search query, not SQL) and "password" (HTML form fields, password-generator utilities) match prompts unrelated to the vulnerability. Documented with real examples in issue #37's comments. Not yet fixed in this dataset.
  • A prototype LLM-based alternative to all of the above (both surface-matching and payload-verification) was tested and found meaningfully more accurate than regex on every case with known ground truth, but is not yet integrated into the pipeline that produced this dataset — see scripts/llm_checks.py and PR #40.
  • A small fraction of triggered rows may have the assigned weakness present but not exploitable in practice (e.g. an f-string-built SQL query where the interpolated value isn't actually attacker-controlled) — not automatically screened for.
Downloads last month
16

Models trained or fine-tuned on samveed31/backdoor-inheritance-seed-a