DEV Community

Cover image for JS-X-Ray 6.0
Thomas.G for NodeSecure

Posted on • Updated on

JS-X-Ray 6.0

Hello πŸ‘‹

It's been a while since the last article on JS-X-Ray 😲!

In this article I will present you the latest major version πŸ‘€. I didn't do an article on version 4 and 5 because they didn't introduce new features (only breaking changes on the API).

πŸ“’ What is JS-X-Ray ?

If you are new in town, JS-X-Ray is an open source JavaScript SAST (Static Application Security Testing). The tool analyzes your JavaScript sources for patterns that may affect the security and quality of your project 😎.

Among the notable features:

  • Retrieving dependencies (CJS & ESM support) and detecting suspicious import/require.
  • Detecting unsafe RegEx.
  • Detecting obfuscated source (and provide hints on the tool used).

As well as a lot of other detections.

Major release 4 and 5

These versions introduced changes on warnings (and we improved how we manage them in the codebase). We added new descriptors for each of them:

  • i18n (for translation in CI or CLI).
  • experimental
  • severity (Information, Warning, Critical)

Those information are visible in the NodeSecure CLI interface:

NodeSecure

Major release 6

🐬 Ok, let's dive into this major release to discover the surprises πŸŽ‰ it has in store for us.

πŸš€ Introducing VariableTracer

Almost a year of work on this new mechanism / class that brings a whole new dimension to JS-X-Ray.

const tracer = new VariableTracer()
  .enableDefaultTracing()
  .trace("crypto.createHash", {
    followConsecutiveAssignment: true, moduleName: "crypto"
  });

tracer.walk(node);
Enter fullscreen mode Exit fullscreen mode

This class is able to follow all declarations, assignments and patterns (and those even through very obscure patterns).

const aA = Function.prototype.call;
const bB = require;

const crypto = aA.call(bB, bB, "crypto");
const cr = crypto.createHash;
cr("md5"); // weak-crypto warning is throw here
Enter fullscreen mode Exit fullscreen mode

This allows us to implement Probes in a much simpler way (which makes maintenance and testing much easier).

Here an example with the isWeakCrypto probe:

function validateNode(node, { tracer }) {
  const id = getCallExpressionIdentifier(node);
  if (id === null || !tracer.importedModules.has("crypto")) {
    return [false];
  }

  const data = tracer.getDataFromIdentifier(id);

  return [
    data !== null &&
    data.identifierOrMemberExpr === "crypto.createHash"
  ];
}
Enter fullscreen mode Exit fullscreen mode

By default the Tracer follows all ways of requiring dependencies with CJS and also usage of eval or Function.

🚧 Removing unsafe-assign warning

This warning was required at the beginning of the project because it was difficult for me to correctly identify some malicious patterns.

NodeSecure

However, with the introduction of the new Tracer, which is very complete and precise, this warning no longer makes sense has it only generates unnecessary noise and false positives.

πŸ“œ Better ESM source parsing

We previously had a lot of parsing-error warnings because the NodeSecure scanner failed to detect if the file was using either CJS or ESM.

That new version will automatically retry with ESM enabled if it fails with CJS.

πŸ“‰ Reducing false positives

To continue the momentum of the previous sections. This version drops a lot of warnings and significantly improves others.

  • Reducing false positives for encoded-literal warning by introducing new way of detecting safe values.
  • Improve short-identifiers by also storing ClassDeclaration, MethodDefinition and Function parameters.

We are also introducing a new suspicious-file warning when a file contain more than 10 encoded-literal warnings to avoid having file with hundreds or thousands of warnings.

Of the 500 most popular NPM packages, we previously had 24k warnings with version 5. The latest version brings that number down to approximatively 5k warnings.

πŸ”¬ Improving coverage

A lot of work has been done to add unit tests on all the probes of the project. We are near 100% of coverage πŸ’ͺ.

NodeSecure

Thanks to the amazing work of our contributors:

πŸ‘€ What's next ?

Here what I'm working for the next major release:

  • Adding support of TypeScript sources (probably by allowing a customization of the parser).
  • A new API that allows to dynamically extend the SAST with new custom probes (and custom warnings).
  • Introducing new built-in detections and warnings (unsafe URL etc).

I will continue to work to reduce the number of false positives and keep improving obfuscated codes detection.


Please think to drop a star on github ❀️!

GitHub logo NodeSecure / js-x-ray

JavaScript & Node.js open-source SAST scanner. A static analyser for detecting most common malicious patterns πŸ”¬.

@nodesecure/js-x-ray

npm version license ossf scorecard github ci workflow codecov

JavaScript AST analysis. This package has been created to export the Node-Secure AST Analysis to enable better code evolution and allow better access to developers and researchers.

The goal is to quickly identify dangerous code and patterns for developers and Security researchers. Interpreting the results of this tool will still require you to have a set of security notions.

Note I have no particular background in security. I'm simply becoming more and more interested and passionate about static code analysis. But I would be more than happy to learn that my work can help prevent potential future attacks (or leaks).

Goals

The objective of the project is to successfully detect all potentially suspicious JavaScript codes.. The target is obviously codes that are added or injected for malicious purposes..

Most of the time these hackers will try to hide the behaviour of their codes as much as possible to avoid being…

That's it for today! Thanks for reading me πŸ˜‰

Top comments (1)

Collapse
 
antoinecoulon profile image
Antoine Coulon

Such a great tool!