Skip to content

JavaScript: Exclude debug npm package from js/log-injection sinks#3

Open
kiro-agent[bot] wants to merge 1 commit into
mainfrom
improve-js-log-injection-exclude-debug-v2
Open

JavaScript: Exclude debug npm package from js/log-injection sinks#3
kiro-agent[bot] wants to merge 1 commit into
mainfrom
improve-js-log-injection-exclude-debug-v2

Conversation

@kiro-agent

@kiro-agent kiro-agent Bot commented Jun 10, 2026

Copy link
Copy Markdown

This pull request was created by @kiro-agent on behalf of @mrigankpawagi 👻

Comment with /kiro fix to address specific feedback or /kiro all to address everything.
Learn about Kiro Web


Summary

This PR improves the js/log-injection query by excluding calls to the debug npm package from being considered as log injection sinks.

Problem

MRVA (Multi-Repository Variant Analysis) on the top-100 JavaScript repositories revealed many false positives from calls to the debug npm package. For example, 10 out of 12 alerts in microsoft/playwright were from debug.* calls in test/proxy code. The debug package is a development debugging utility that:

  • Only outputs to stderr when the DEBUG environment variable is explicitly set
  • Is not a production logging mechanism
  • Is typically disabled entirely in production

Flagging these as log injection sinks generates noise without security value.

Changes

  1. Modified LoggingSink class in javascript/ql/lib/semmle/javascript/security/dataflow/LogInjectionQuery.qll:

    • Changed from this = any(LoggerCall console).getAMessageComponent()
    • To an exists() pattern that excludes calls matching API::moduleImport("debug").getReturn().getACall()
  2. Test case - Added a test in javascript/ql/test/query-tests/Security/CWE-117/logInjectionGood.js demonstrating that debug() calls are not flagged.

  3. Change note - Added javascript/ql/src/change-notes/2025-06-07-log-injection-exclude-debug.md.

MRVA Validation

  • Eliminates false positives from debug package usage across many repositories
  • Notable: microsoft/playwright alerts reduced from 12 to ~2 (the remaining are legitimate console.log/console.error sinks)
  • Other logging mechanisms (console.log, winston, pino, bunyan, etc.) remain correctly flagged

Why this is correct

The debug npm package (https://www.npmjs.com/package/debug) is fundamentally different from production loggers:

const debug = require('debug')('myapp:server');
debug('listening on port %s', port); // Only outputs if DEBUG=myapp:server is set
  1. Not production output - It's disabled by default and only activates with explicit DEBUG env var
  2. Developer-only - Used for development/debugging, not for production log aggregation
  3. No log file persistence - Outputs to stderr only when enabled, not to persistent log files that could be targeted by log injection

@github-actions github-actions Bot added documentation Improvements or additions to documentation JS labels Jun 10, 2026
mrigankpawagi pushed a commit that referenced this pull request Jun 20, 2026
When CODEQL_EXTRACTOR_GO_OPTION_EXTRACT_TESTS=true is set, the Go
extractor was incorrectly skipping internal test files (package foo)
at repository roots when the project contains nested test packages.

Root Cause:
The extractor selected package variants by longest ID string, but this
heuristic fails when nested packages have tests. For a package like
"github.com/go-git/go-git/v6", packages.Load returns multiple variants:

1. "github.com/go-git/go-git/v6" (19 files, production only)
2. "github.com/go-git/go-git/v6 [github.com/go-git/go-git/v6.test]"
   (39 files, production + 20 root tests) ← Should select this
3. "github.com/go-git/go-git/v6 [github.com/go-git/go-git/v6/plumbing/format/packfile.test]"
   (19 files, test dependency) ← Was incorrectly selected (longest string)

The old logic selected variant #3 (76 chars) over #2 (68 chars),
causing 20 root test files to be missing from the database.

Fix:
Replace string length comparison with a better heuristic that prefers:
1. Exact test packages (e.g., "pkg [pkg.test]") over nested dependencies
2. Packages with more Syntax nodes (more files to extract)
3. String length as a tiebreaker

This ensures the extractor selects the variant with the most complete
test coverage, particularly for root-level internal tests.

Testing:
- Added comprehensive unit tests covering the selection logic
- Tests simulate the real-world go-git scenario
- All tests pass

Impact:
Root-level external tests (package foo_test) were already extracted
correctly. This fix ensures internal tests (package foo) at the root
are now also extracted when they exist alongside nested test packages.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@mrigankpawagi mrigankpawagi force-pushed the improve-js-log-injection-exclude-debug-v2 branch from 8481e5e to f22d076 Compare June 23, 2026 12:03
@github-actions github-actions Bot removed the documentation Improvements or additions to documentation label Jun 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant