injection-bench
A small, dependency-free harness for evaluating prompt-injection and jailbreak detectors the way they will actually be used: trained on the past, tested on the future, with confidence intervals and shortcut baselines. It exists because detectors that look strong on author-written examples often fall apart on real traffic.
What it does that a quick script usually doesn't:
- Time split with leakage control. Train on earlier items, test on later ones. Near-duplicate prompts (same normalised 300-character prefix) are removed, and no test prompt may duplicate a train prompt.
- Operating-point metrics. Recall at fixed false-positive rates (1%, 5%), AUC, and precision at a stated prevalence, each with a 95% bootstrap confidence interval. A 0.5 threshold on an arbitrary score says little.
- Shortcut baselines.
length-onlyand a hand-writtenkeywordsdetector show how much of a score is explained by dataset artefacts. - Plug in your own detector. Anything with
score(list[str]) -> list[float](and an optionalfit).
Quick start
pip install injection-bench # add [sklearn] for the tfidf-lr baseline
injectbench download data/ # public JailbreakHub CSVs (Shen et al., CCS 2024, MIT)
injectbench run --data data/ --detector length --detector keywords --detector hashed-lr --detector tfidf-lr --out report.md
Your own detector:
# mydet.py
class MyDetector:
name = "mine"
def fit(self, texts, labels): ... # optional
def score(self, texts): return [...] # higher = more likely an attack
injectbench run --data data/ --detector mydet:MyDetector
Your own data: a JSONL file with text, label (1 = attack) and date fields: --data my.jsonl.
Reference results
JailbreakHub in-the-wild prompts, 1,405 jailbreaks and 13,735 regular prompts (rows without a date are
dropped). Train 7,895 prompts (757 jailbreaks) on the earlier part, test 5,503 prompts (398 jailbreaks, 7.2%
prevalence) on the later part. Reproduce with the command above plus --detector guardkit:rules --detector guardkit:model
(needs pip install guardkit).
| detector | AUC (95% CI) | recall @1% FPR (95% CI) | recall @5% FPR | precision @1% FPR, 5% prevalence | ms/item |
|---|---|---|---|---|---|
| length-only | 0.587 (0.56-0.61) | 0.020 (0.01-0.04) | 0.080 | 0.096 | 0.0 |
| keywords | 0.653 (0.63-0.68) | 0.053 (0.03-0.07) | 0.214 | 0.217 | 0.04 |
| hashed-lr (pure Python, trained on the train split) | 0.742 (0.72-0.77) | 0.113 (0.08-0.16) | 0.264 | 0.373 | 0.5 |
| tfidf-lr (word + char n-grams, scikit-learn) | 0.779 (0.76-0.80) | 0.093 (0.07-0.14) | 0.274 | 0.329 | 2.2 |
| guardkit:rules | 0.511 (0.50-0.52) | 0.000 (0.00-0.00) | 0.048 | 0.000 | 0.5 |
| guardkit:model | 0.739 (0.71-0.76) | 0.118 (0.08-0.18) | 0.261 | 0.383 | 0.9 |
Reading it: length alone gives AUC 0.59, so there is a mild shortcut but not a dominant one. Classical bag-of-words detectors plateau at AUC 0.74-0.78 and catch roughly one in ten jailbreaks at a 1% false-positive rate; adding character n-grams raises AUC but not low-FPR recall. Regular expressions are close to chance on this data. Transformer-based detectors are not included because the benchmark environment could not download model weights; adding one is a ten-line adapter (see "Plug in your own detector").
Caveats
- "recall @X% FPR" sets the threshold on the test negatives. It measures ranking quality at a given false-positive budget; it is not a deployable operating point, which you must choose on held-out data.
- The only bundled dataset labels jailbreak intent in user prompts, not document-embedded prompt injection.
Its "regular" class includes templates that open with "ignore previous instructions". Use
--datawith your own labelled data for your threat model. - Pure-Python metrics are fine for thousands of items, not millions. Bootstrap CIs use 200 resamples by default.
- Reference rows come from one dataset and one split. Do not read them as a ranking of detector families.
Related projects
- guardkit: the detector used for the
guardkit:*rows above; its technical report (docs/technical-report.md) explains why author-written test sets overstate performance. - bharatid: validators for Indian identifiers.
MIT licensed.
Metadata
Release files for injection-bench 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| injection_bench-0.1.0.tar.gz | 12.8 kB | With provenance | Details for injection_bench-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| injection_bench-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for injection_bench-0.1.0-py3-none-any.whl |
Total release size: 24.2 kB
Release files / injection_bench-0.1.0.tar.gz
| Download URL | injection_bench-0.1.0.tar.gz |
|---|---|
| Size | 12.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5aa57e16274ebd2667fb8effc8d462876e85fefcc31474b388f2de3e62708b74
|
|
BLAKE2b-256 checksum How to use checksums |
7d6558faff5e0a10ac0ef90b96082d1e9171c0b2e2776a327d9bddc3caf4fd6a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 1, 2026.
Transparency logRelease files / injection_bench-0.1.0-py3-none-any.whl
| Download URL | injection_bench-0.1.0-py3-none-any.whl |
|---|---|
| Size | 11.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
54baea24560207391b16437b20730348163bbf2d11a0fa29fb5ef2cb403b09f2
|
|
BLAKE2b-256 checksum How to use checksums |
e161b4c15f84ad8be8567dab586d1828bbdda32f58d03da954c8e0ac829b4416
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 1, 2026.
Transparency logSecurity for injection-bench 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for injection_bench-0.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 1, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.