fix: expand bandit --exclude paths into globs so nested files are pruned#600
Open
f0rodo wants to merge 1 commit intopeteromallet:mainfrom
Open
fix: expand bandit --exclude paths into globs so nested files are pruned#600f0rodo wants to merge 1 commit intopeteromallet:mainfrom
f0rodo wants to merge 1 commit intopeteromallet:mainfrom
Conversation
Bandit's ``--exclude`` flag is matched against filenames it discovers during its recursive walk: it filters files whose name *equals* one of the supplied strings. When desloppify passed bare absolute directory paths (e.g. ``/repo/.claude``), bandit only matched the directory entry itself; files *under* it (``/repo/.claude/worktrees/foo.py``) were still scanned. The downstream symptom was a Security dimension score of 8.9% on a project that excluded ``.claude`` and ``.claude/worktrees``: the file discovery layer correctly skipped those dirs, but bandit was given the project root and walked into them anyway, returning ~6,000 B101 (use of assert) findings from agent-tool worktrees that aren't user code. Fix: ``_exclude_globs`` expands each input path's components into ``**/<name>`` and ``**/<name>/**`` patterns alongside the original absolute path. The ``**`` form is what bandit's pattern matcher needs to prune the whole subtree. Verified end-to-end: Before: 5,958 security findings (5,932 in .claude/worktrees/) After: 3 security findings (clean rescan, .claude properly pruned) Test: test_exclude_dirs_expanded_to_glob_for_nested_pruning asserts the emitted ``--exclude`` arg includes ``**/.claude``, ``**/.claude/**``, and ``**/worktrees/**`` for nested input paths. 5,533 existing tests still pass (the unrelated test_bundled_sync ``scoring.md`` failure pre-dates this branch). Made-with: Cursor
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.
Problem
The Security dimension was reporting 5,958 issues on a project that had
.claudeand.claude/worktreesin itsexcludeconfig. Inspection showed 5,932 of those were in.claude/worktrees/...— exactly the directories the user told desloppify to skip.The exclusion is honored by the file-discovery layer (
_find_source_files_cachedcorrectly prunes via_is_excluded_dir). But thebandit_adaptercalls bandit with the project root as its scan target and a--excludevalue built fromcollect_exclude_dirs()— a list of bare absolute paths like/repo/.claude.Bandit's
--excludeis matched against the filenames it discovers during its own recursive walk: it filters files whose name equals one of the supplied strings. So/repo/.claudefilters the directory entry itself, but/repo/.claude/worktrees/foo.pyis still scanned (the full filename does not equal the exclude string).Repro:
vs the form bandit's pattern matcher actually understands:
Fix
_exclude_globs(paths)(new helper inbandit_adapter.py) walks the path components of each input and emits**/<name>+**/<name>/**glob siblings alongside the original absolute path. The originals are kept as a belt-and-braces fallback; the globs are what actually do the work.detect_with_banditnow passes_exclude_globs(exclude_dirs)to--excludeinstead of the raw list.Verified
End-to-end on a real project that excludes
.claudeand.claude/worktrees:.claude/worktrees/...Test
test_exclude_dirs_expanded_to_glob_for_nested_pruningasserts the emitted--excludearg contains**/.claude,**/.claude/**, and**/worktrees/**when given/project/.claudeand/project/.claude/worktreesas input.5,533 existing tests still pass; the unrelated
test_bundled_syncfailure onscoring.mdpredates this branch.Made with Cursor