Jasmin (JsSecuritySensorV2) hangs at 82% on large TypeScript monorepo - cannot be skipped

ALM: GitHub

CI system: GitHub Actions

Scanner command:
docker run --rm --user root \
-v “${{ github.workspace }}:/usr/src” \
-w /usr/src \
-e SONAR_TOKEN=“” \
-e SONAR_HOST_URL=“” \
sonarsource/sonar-scanner-cli:12.0.0.3214_8.0.1

Languages: TypeScript, JavaScript (~4,300 source files, 3,016 fed to Jasmin)

Error observed:
INFO Sensor JsSecuritySensorV2 [jasmin]
INFO 3016 file(s) will be analysed by SonarJasmin.
INFO Analysis progress: 1% (50/3016 files)

INFO Analysis progress: 82% (2500/3016 files)
[hangs indefinitely — never progresses further]

Steps to reproduce:

  1. Run sonar-scanner against a large TypeScript monorepo (~4,300 JS/TS files)
  2. Scan reaches JsSecuritySensorV2 [jasmin] sensor
  3. Progresses to exactly 82% (2500/3016 files) and hangs indefinitely
  4. Reproducible both locally and on GitHub Actions CI

Solutions attempted — all unsuccessful:
sonar.security.enable=false
sonar.jasmin.enabled=false
sonar.internal.analysis.js.security.enable=false
Also tried removing broken symlinks and nested node_modules before scanning — no effect. File count fed to Jasmin remains 3016 every time.

Potential workaround: None found. Looking for a supported way to disable or timeout the Jasmin sensor at the project or organization level in SonarQube Cloud.

Hi Anirudh,

Thanks for reporting the problem.

Could you provide a little bit more information, such as:

  • Do you know on what file it’s hanging? Could you potentially share (part of) this file with us (privately)?
  • Is the code mostly JS or TS?
  • Frontend or backend?
  • Does it contain any exceptionally large files?
  • What module system does it use — `import`s, `require`s, or mixed?
  • Does it use dynamic imports (e.g. `require(…)` or `import(…)` inside `if`/`else` or other control flow)?
  • Does it monkey-patch built-ins (e.g. `Object.prototype`, `Function.prototype`, `require` being reassigned)?
  • Does it use reflection or instrumentation (`eval`, `Proxy`, `Reflect`, `vm.runInContext`, `new Function(…)`)?
  • Does it contain deeply recursive functions?
  • Does the scanned path (e.g. `/builds/…`) contain the original **source** code, not transpiled/bundled/minified output?

You could also try to re-run the scan with the following options:

```
-Dsonar.jasmin.internal.enable.metrics=true
-Dsonar.jasmin.internal.enable.stacktracing=true
-Dsonar.verbose=true
```
it would likely produce tons of outputs, but maybe you see some regularities in there.

If you don’t mind delegating the investigation to an agent, you could try the following prompt (but that’s on your own risk) :

(PROMPT-START)


The sonar-jasmin taint analyzer is hanging or crashing on this project.

Inspect the JS/TS files and return a JSON object matching the schema below.


{

  "type": "object",

  "properties": {

    "language": {

      "type": "string",

      "enum": ["js", "ts", "mixed"],

      "description": "Is the codebase mostly JS, mostly TS, or mixed?"

    },

    "layer": {

      "type": "string",

      "enum": ["frontend", "backend", "mixed"],

      "description": "Is it frontend, backend, or both?"

    },

    "module_system": {

      "type": "string",

      "enum": ["esm", "cjs", "mixed", "none"],

      "description": "Module system in use: ES import/export, CommonJS require(), or mixed?"

    },

    "large_files_count": {

      "type": "integer",

      "description": "How many JS/TS files exceed 5000 lines?"

    },

    "source_path_is_build_output": {

      "type": "boolean",

      "description": "Does the scanned directory appear to contain transpiled/bundled/minified/uglified output rather than original source?"

    },

    "dynamic_imports": {

      "type": "boolean",

      "description": "Does the code call require() or import() inside control flow (if/else, loops, callbacks)?"

    },

    "prototype_mutation": {

      "type": "boolean",

      "description": "Does the code assign to Object.prototype, Array.prototype, Function.prototype, or reassign require?"

    },

    "reflection_or_instrumentation": {

      "type": "boolean",

      "description": "Does the code use eval, new Function(...), Proxy, Reflect, vm.runInContext, or similar?"

    },

    "deep_recursion": {

      "type": "boolean",

      "description": "Does the code contain deeply or non-trivially recursive functions?"

    }

  }

}

(PROMPT-END)

This would only look at the code, it would not re-run anything with any extra flags.