fix(lsp): judge Express middleware on its own body, not its module - #168
Merged
Conversation
`_trace_express_auth` resolved a middleware to its definition and then searched the whole definition *file* for an auth terminal. Auth helpers cluster in one module, so any middleware resolving into that module inherited its siblings' terminals — a `requireAuth` that only calls `next()` was confirmed as verifying auth because a `checkToken` further down the same file calls `jwt.verify`. This is the weakness already fixed for the inline path, where a login route importing `signToken` from the module that also defines `verifyToken` came out authenticated. `_trace_definition_body` returns only the resolved symbol's own declaration, and both `_find_auth_terminal` and `_has_enforcement` now see just that. Also stop resolving from the import line. `re.search` found the middleware's first occurrence in the file, which is usually its import, and asking for the definition of an import specifier is answered with the import itself — the shape the project-load retry waits on. `_locate_symbol` prefers a use site. The path is narrower than it was: centrally-mounted routes are attributed per route, so this now serves files that apply middleware inline. Its hardcoded list of five middleware names is untouched and still cannot name a project's own vocabulary — worth generalising, but a change of behaviour rather than a correction. Findings are unchanged everywhere: test-app 110 with 4 suppressed, juice-shop 183 with 15, benchmarks 46/46 with 0 FP and 3/3 on VAmPI. The two new tests fail if the whole-file scan is put back. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EZ4QoTqRoYWE25CNoV2Wfy
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.
The last instance of a weakness fixed twice already elsewhere.
The bug
_trace_express_authresolved a middleware to its definition and then searched the whole definition file for an auth terminal. Auth helpers cluster in one module, so any middleware resolving into that module inherited its siblings' terminals:A route guarded only by
requireAuthwas reported as authenticated — and a route reported as authenticated has its missing-auth finding suppressed, so the failure direction is hiding a vulnerability.Same shape as the inline path (a login route importing
signTokenfrom the module that definesverifyToken)._trace_definition_bodyreturns only the resolved symbol's own declaration, and both_find_auth_terminaland_has_enforcementnow see just that.Also: resolving from the import line
re.searchfound the middleware's first occurrence in the file — usually its import. Asking for the definition of an import specifier is answered with the import itself, which is exactly the shape the project-load retry waits on, so these traces were spending retries before failing._locate_symbolprefers a use site.Scope
This path is narrower than it was: centrally-mounted routes are attributed per route since #163, so it now serves files applying middleware inline. Its hardcoded list of five middleware names is untouched — it still can't name a project's own vocabulary, which is worth generalising but is a change of behaviour rather than a correction.
Verification
Findings unchanged everywhere, as expected: neither target reaches this path any more. The two new tests fail if the whole-file scan is put back — verified by reverting it.
🤖 Generated with Claude Code
https://claude.ai/code/session_01EZ4QoTqRoYWE25CNoV2Wfy