Add safe builtins allowlist to prevent false positives#206
Merged
thomas-chauchefoin-tob merged 8 commits intomasterfrom Jan 22, 2026
Merged
Add safe builtins allowlist to prevent false positives#206thomas-chauchefoin-tob merged 8 commits intomasterfrom
thomas-chauchefoin-tob merged 8 commits intomasterfrom
Conversation
Previously, all imports from the builtins module were flagged as LIKELY_OVERTLY_MALICIOUS, even safe functions like dict(), len(), sorted(), and enumerate(). This caused false positives for legitimate pickle files. Add SAFE_BUILTINS frozenset containing type constructors and pure functions that cannot be used for code execution or system access. Modify both UnsafeImportsML and UnsafeImports analyzers to check individual builtin names against this allowlist. Dangerous builtins like eval, exec, getattr, __import__, and open remain blocked as they can be used for arbitrary code execution. Fixes #205 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Format analysis.py and test_bypasses.py with ruff - Remove mypy from pre-commit hooks (was already skipped in CI) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
d6c73db to
5bb072d
Compare
- Add BUILTIN_MODULE_NAMES constant to eliminate repeated tuple - Move SAFE_BUILTINS from UnsafeImportsML class to fickle.py - Update both UnsafeImportsML and UnsafeImports to use shared constants - Removes cross-class dependency (UnsafeImports no longer references UnsafeImportsML.SAFE_BUILTINS) Co-Authored-By: Claude <noreply@anthropic.com>
type() with 3 arguments dynamically creates classes, which could be a building block in exploit chains (e.g., triggering __init_subclass__ or __set_name__ on imported base classes/descriptors). While not directly exploitable in isolation, there's no legitimate reason for a pickle to dynamically create classes, so we exclude it as a defense-in-depth measure. Co-Authored-By: Claude <noreply@anthropic.com>
Update test_unsafe_builtins_still_flagged and test_unsafe_builtin_eval_still_flagged to assert that both UnsafeImports and UnsafeImportsML flag dangerous builtins, rather than checking if either one does. Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
SAFE_BUILTINSfrozenset containing type constructors and pure functions that cannot be used for code executionUnsafeImportsMLandUnsafeImportsanalyzers to check individual builtin names against the allowlistdict(),len(),sorted(),enumerate()no longer trigger false positiveseval,exec,getattr,__import__,openremain blockedTest plan
test_builtins_import_bypassstill catchesgetattr/__import__bypassestest_safe_builtins_not_flaggedpasses (len not flagged)test_safe_builtin_dict_not_flaggedpasses (dict not flagged)test_unsafe_builtins_still_flaggedpasses (getattr still flagged)test_unsafe_builtin_eval_still_flaggedpasses (eval still flagged)Fixes #205
🤖 Generated with Claude Code