Skip to content

JS: Modeling of ShellJS functions #19422

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open

Conversation

Napalys
Copy link
Contributor

@Napalys Napalys commented Apr 30, 2025

Added support for additional functions in the shelljs and async-shelljs libraries:

  • which: Command location functionality
  • cmd: Command execution wrapper
  • asyncExec: Asynchronous command execution
  • env: Environment variable handling

@Napalys Napalys marked this pull request as ready for review May 1, 2025 10:11
@Copilot Copilot AI review requested due to automatic review settings May 1, 2025 10:11
@Napalys Napalys requested a review from a team as a code owner May 1, 2025 10:11
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR extends CodeQL’s JavaScript analysis to model additional ShellJS and async-shelljs functionality, specifically command location (which), generic command execution (cmd), asynchronous execution (asyncExec), and environment-variable sources (env).

  • Added new tests and expected results for shelljs.which, shelljs.cmd, async-shelljs.asyncExec, and shelljs.env in security query tests and library-tests.
  • Updated ShellJS QL framework (ShellJS.qll and shelljs.model.yml) to include support for the new functions and to tag shelljs.env as an environment source.
  • Refactored environment-source handling in dataflow customization modules to use ThreatModelSource tagging.

Reviewed Changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated no comments.

Show a summary per file
File Description
javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection/actions.js Added test2 using shelljs.env to trigger indirect command injection alerts
javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection/IndirectCommandInjection.expected Updated expected alerts for the new shelljs.env cases
javascript/ql/test/library-tests/frameworks/Shelljs/tst.js Extended library tests with shelljs.cmd, shelljs.which, and asyncExec
javascript/ql/test/library-tests/frameworks/Shelljs/ShellJS.expected Added expected flow entries for the new ShellJS calls
javascript/ql/src/Security/CWE-295/DisablingCertificateValidation.ql Switched to threat-model tagging for process.env source
javascript/ql/lib/semmle/javascript/security/dataflow/IndirectCommandInjectionCustomizations.qll Refactored ProcessEnvAsSource and envObject to use ThreatModelSource
javascript/ql/lib/semmle/javascript/security/dataflow/CleartextLoggingCustomizations.qll Updated ProcessEnvSource to apply threat-model tagging
javascript/ql/lib/semmle/javascript/frameworks/ShellJS.qll Added which, cmd, asyncExec to ShellJS model and adjusted call handling
javascript/ql/lib/ext/shelljs.model.yml Declared shelljs.Member[env] as an environment source
javascript/ql/lib/change-notes/2025-04-30-shelljs.md Documented the minor-analysis changes for new ShellJS/async-shelljs support
Comments suppressed due to low confidence (3)

javascript/ql/lib/semmle/javascript/security/dataflow/IndirectCommandInjectionCustomizations.qll:32

  • The constructor for ProcessEnvAsSource no longer initializes this to the process.env property read, so it won’t actually capture process.env as a source. You should restore this = NodeJSLib::process().getAPropertyRead("env") and then apply the threat-model tag.
ProcessEnvAsSource() { this.(ThreatModelSource).getThreatModel() = "environment" }

javascript/ql/lib/semmle/javascript/security/dataflow/CleartextLoggingCustomizations.qll:174

  • This constructor only applies the threat-model tag but never sets this to NodeJSLib::process().getAPropertyRead("env"). Without the property-read node, the source won’t be detected. Reintroduce the property-read assignment before tagging.
ProcessEnvSource() { this.(ThreatModelSource).getThreatModel() = "environment" }

javascript/ql/src/Security/CWE-295/DisablingCertificateValidation.ql:40

  • The original assignment env = NodeJSLib::process().getAPropertyRead("env") was removed. Now env is never bound to the property-read node. You need to both assign the property-read and then tag it with ThreatModelSource.
env.(ThreatModelSource).getThreatModel() = "environment" and

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant