Skip to content

Add DoS protection against expansion attacks (Billion Laughs style)#211

Merged
thomas-chauchefoin-tob merged 12 commits intomasterfrom
dos-protection-expansion-attacks
Mar 19, 2026
Merged

Add DoS protection against expansion attacks (Billion Laughs style)#211
thomas-chauchefoin-tob merged 12 commits intomasterfrom
dos-protection-expansion-attacks

Conversation

@dguido
Copy link
Copy Markdown
Member

@dguido dguido commented Jan 22, 2026

Summary

  • Implements defense in depth against exponential expansion attacks (Issue Fickling DoS #111)
  • Adds static pattern detection via ExpansionAttackAnalysis to flag suspicious opcode patterns
  • Adds runtime resource limits via InterpreterLimits to stop runaway execution

Test plan

  • Run pytest test/test_crashes.py::TestExpansionAttacks -v - all 6 new tests pass
  • Run full test suite - 71 passed, 1 failed (pre-existing issue Denial of Service via Infinite Recursion on Cyclic Pickles #196)
  • Verify legitimate data is not falsely flagged
  • Manual test with attack files from issue Fickling DoS #111:
    curl -O https://raw.githubusercontent.com/coldwaterq/pickle_injector/main/globalLaughs.pt
    fickling globalLaughs.pt  # Should flag as suspicious/unsafe

🤖 Generated with Claude Code

Implement defense in depth against exponential expansion attacks that could
cause Fickling to hang or consume excessive memory:

1. Static pattern detection via ExpansionAttackAnalysis:
   - Detects high GET/PUT ratio (>10x suspicious, >50x likely unsafe)
   - Detects excessive DUP operations (>100 suspicious)

2. Runtime resource limits via InterpreterLimits:
   - max_opcodes: 1,000,000
   - max_stack_depth: 10,000
   - max_memo_size: 100,000
   - max_get_ratio: 50 (GETs per PUT)

3. New exception types:
   - ResourceExhaustionError for limit violations
   - ExpansionAttackError for expansion attack detection

4. Updated opcode classes to track GET/PUT operations:
   - BinGet, LongBinGet, Get call track_get()
   - BinPut, Put, LongBinPut, Memoize call track_put()

5. AnalysisContext catches ResourceExhaustionError and returns
   LIKELY_OVERTLY_MALICIOUS severity instead of propagating exception

Fixes #111

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@dguido dguido requested a review from ESultanik as a code owner January 22, 2026 05:57
dguido and others added 7 commits January 22, 2026 03:26
The cyclic AST recursion issue (#196) is being fixed separately in PR #213.
Mark this test as expected failure so PR #211 CI can pass.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move _check_limits() after opcode.run() so counters are current
- Add ResourceExhaustionError handling in Pickled.ast (returns empty AST)
- Broaden AnalysisContext.analyze() catch to handle ValueError,
  IndexError, RecursionError from malformed pickles
- Handle put_count == 0 edge case in ExpansionAttackAnalysis
- Simplify combined indicators logic (remove redundant condition)
- Make InterpreterLimits frozen with __post_init__ validation
- Hardcode resource_type in ExpansionAttackError
- Use round() instead of int() for ratio in error messages
- Add ResourceExhaustionError handling in CLI decompile path
- Split resource limit tests per limit type (opcodes, stack, memo)
- Add InterpreterLimits validation test
- Remove @expectedfailure from test_cyclic_pickle_dos (now handled)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Allows callers to override GET/PUT ratio and DUP count thresholds
without monkey-patching class attributes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reproduces globalLaughs.pt (DUP-based) and billionLaughsAlt.pkl
(memo-based) DoS patterns that evade current flat thresholds by
spreading operations across nested LIST layers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
thomas-chauchefoin-tob and others added 4 commits March 19, 2026 18:23
Previously detection depended on UnusedVariables accidentally
re-triggering the error. Now Pickled sets a flag and a dedicated
analysis checks it.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
@thomas-chauchefoin-tob thomas-chauchefoin-tob merged commit e5e34bb into master Mar 19, 2026
12 checks passed
@thomas-chauchefoin-tob thomas-chauchefoin-tob deleted the dos-protection-expansion-attacks branch March 19, 2026 17:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants