From 9990244dea0dc2c2b4e89a833fea978ac9a753b0 Mon Sep 17 00:00:00 2001 From: fraxken Date: Fri, 16 Aug 2024 20:47:02 +0200 Subject: [PATCH 1/3] refactor!: remove legacy runASTAnalysis and runASTAnalysisOnFile APIs --- index.js | 80 ++--------------------- test/AstAnalyser.spec.js | 103 ++++++++++++++++++++++++++++++ test/runASTAnalysis.spec.js | 74 --------------------- test/runASTAnalysisOnFile.spec.js | 89 -------------------------- 4 files changed, 107 insertions(+), 239 deletions(-) delete mode 100644 test/runASTAnalysis.spec.js delete mode 100644 test/runASTAnalysisOnFile.spec.js diff --git a/index.js b/index.js index e636dbb..6db3d8a 100644 --- a/index.js +++ b/index.js @@ -1,76 +1,4 @@ -// Import Internal Dependencies -import { warnings } from "./src/warnings.js"; -import { JsSourceParser } from "./src/JsSourceParser.js"; -import { AstAnalyser } from "./src/AstAnalyser.js"; -import { EntryFilesAnalyser } from "./src/EntryFilesAnalyser.js"; - -/** - * @deprecated - */ -function runASTAnalysis( - str, - options = Object.create(null) -) { - process.emitWarning( - "The runASTAnalysis API is deprecated and will be removed in v8. Please use the AstAnalyser class instead.", - { - code: "DeprecationWarning", - detail: "The runASTAnalysis API is deprecated and will be removed in v8. Please use the AstAnalyser class instead." - } - ); - - const { - customParser = new JsSourceParser(), - customProbes = [], - skipDefaultProbes = false, - ...opts - } = options; - - const analyser = new AstAnalyser({ - customParser, - customProbes, - skipDefaultProbes - }); - - return analyser.analyse(str, opts); -} - -/** - * @deprecated - */ -async function runASTAnalysisOnFile( - pathToFile, - options = {} -) { - process.emitWarning( - "The runASTAnalysisOnFile API is deprecated and will be removed in v8. Please use the AstAnalyser class instead.", - { - code: "DeprecationWarning", - detail: "The runASTAnalysisOnFile API is deprecated and will be removed in v8. Please use the AstAnalyser class instead." - } - ); - - const { - customProbes = [], - customParser = new JsSourceParser(), - skipDefaultProbes = false, - ...opts - } = options; - - const analyser = new AstAnalyser({ - customParser, - customProbes, - skipDefaultProbes - }); - - return analyser.analyseFile(pathToFile, opts); -} - -export { - warnings, - AstAnalyser, - EntryFilesAnalyser, - JsSourceParser, - runASTAnalysis, - runASTAnalysisOnFile -}; +export { warnings } from "./src/warnings.js"; +export { JsSourceParser } from "./src/JsSourceParser.js"; +export { AstAnalyser } from "./src/AstAnalyser.js"; +export { EntryFilesAnalyser } from "./src/EntryFilesAnalyser.js"; diff --git a/test/AstAnalyser.spec.js b/test/AstAnalyser.spec.js index fcae71a..695f004 100644 --- a/test/AstAnalyser.spec.js +++ b/test/AstAnalyser.spec.js @@ -6,6 +6,7 @@ import { readFileSync } from "node:fs"; // Import Internal Dependencies import { AstAnalyser, JsSourceParser } from "../index.js"; +import { FakeSourceParser } from "./fixtures/FakeSourceParser.js"; import { SourceFile } from "../src/SourceFile.js"; import { customProbes, @@ -176,6 +177,22 @@ describe("AstAnalyser", (t) => { assert.equal(result.warnings.length, 1); }); + it("should call with the expected arguments", (t) => { + t.mock.method(AstAnalyser.prototype, "analyse"); + + const source = "const http = require(\"http\");"; + new AstAnalyser().analyse(source, { module: true, removeHTMLComments: true }); + + const source2 = "const fs = require(\"fs\");"; + new AstAnalyser().analyse(source2, { module: false, removeHTMLComments: false }); + + const calls = AstAnalyser.prototype.analyse.mock.calls; + assert.strictEqual(calls.length, 2); + + assert.deepEqual(calls[0].arguments, [source, { module: true, removeHTMLComments: true }]); + assert.deepEqual(calls[1].arguments, [source2, { module: false, removeHTMLComments: false }]); + }); + describe("hooks", () => { describe("initialize", () => { const analyser = new AstAnalyser(); @@ -281,6 +298,56 @@ describe("AstAnalyser", (t) => { assert.strictEqual(parsingError.kind, "parsing-error"); }); + it("should call the method with the expected arguments", async(t) => { + t.mock.method(AstAnalyser.prototype, "analyseFile"); + + const url = new URL("depName.js", FIXTURE_URL); + await new AstAnalyser().analyseFile( + url, + { module: false, packageName: "foobar" } + ); + + const url2 = new URL("parsingError.js", FIXTURE_URL); + await new AstAnalyser().analyseFile( + url, + { module: true, packageName: "foobar2" } + ); + + const calls = AstAnalyser.prototype.analyseFile.mock.calls; + assert.strictEqual(calls.length, 2); + + assert.deepEqual(calls[0].arguments, [url, { module: false, packageName: "foobar" }]); + assert.deepEqual(calls[1].arguments, [url2, { module: true, packageName: "foobar2" }]); + }); + + it("should implement new customProbes while keeping default probes", async() => { + const result = await new AstAnalyser( + { + parser: new JsSourceParser(), + customProbes, + skipDefaultProbes: false + } + ).analyseFile(new URL("customProbe.js", FIXTURE_URL)); + + assert.equal(result.warnings[0].kind, kWarningUnsafeDanger); + assert.equal(result.warnings[1].kind, kWarningUnsafeImport); + assert.equal(result.warnings[2].kind, kWarningUnsafeStmt); + assert.equal(result.warnings.length, 3); + }); + + it("should implement new customProbes while skipping/removing default probes", async() => { + const result = await new AstAnalyser( + { + parser: new JsSourceParser(), + customProbes, + skipDefaultProbes: true + } + ).analyseFile(new URL("customProbe.js", FIXTURE_URL)); + + assert.equal(result.warnings[0].kind, kWarningUnsafeDanger); + assert.equal(result.warnings.length, 1); + }); + describe("hooks", () => { const analyser = new AstAnalyser(); const url = new URL("depName.js", FIXTURE_URL); @@ -543,6 +610,42 @@ describe("AstAnalyser", (t) => { assert.deepStrictEqual(analyser.probesOptions.customProbes, []); assert.strictEqual(analyser.probesOptions.skipDefaultProbes, false); }); + + it("should properly instanciate default or custom parser (using analyseFile)", async(t) => { + t.mock.method(JsSourceParser.prototype, "parse"); + t.mock.method(FakeSourceParser.prototype, "parse"); + + await new AstAnalyser().analyseFile( + new URL("depName.js", FIXTURE_URL), + { module: false, packageName: "foobar" } + ); + + await new AstAnalyser( + { customParser: new FakeSourceParser() } + ).analyseFile( + new URL("parsingError.js", FIXTURE_URL), + { module: true, packageName: "foobar2" } + ); + + assert.strictEqual(JsSourceParser.prototype.parse.mock.calls.length, 1); + assert.strictEqual(FakeSourceParser.prototype.parse.mock.calls.length, 1); + }); + + it("should properly instanciate default or custom parser (using analyse)", (t) => { + t.mock.method(JsSourceParser.prototype, "parse"); + t.mock.method(FakeSourceParser.prototype, "parse"); + + new AstAnalyser().analyse("const http = require(\"http\");", { module: true, removeHTMLComments: true }); + + new AstAnalyser({ + customParser: new FakeSourceParser() + }).analyse("const fs = require(\"fs\");", + { module: false, removeHTMLComments: false } + ); + + assert.strictEqual(JsSourceParser.prototype.parse.mock.calls.length, 1); + assert.strictEqual(FakeSourceParser.prototype.parse.mock.calls.length, 1); + }); }); }); diff --git a/test/runASTAnalysis.spec.js b/test/runASTAnalysis.spec.js deleted file mode 100644 index bea68ca..0000000 --- a/test/runASTAnalysis.spec.js +++ /dev/null @@ -1,74 +0,0 @@ -// Import Node.js Dependencies -import { it } from "node:test"; -import assert from "node:assert"; - -// Import Internal Dependencies -import { runASTAnalysis, AstAnalyser, JsSourceParser } from "../index.js"; -import { FakeSourceParser } from "./fixtures/FakeSourceParser.js"; -import { - customProbes, - kIncriminedCodeSampleCustomProbe, - kWarningUnsafeDanger, - kWarningUnsafeImport, - kWarningUnsafeStmt -} from "./utils/index.js"; - -it("should call AstAnalyser.analyse with the expected arguments", (t) => { - t.mock.method(AstAnalyser.prototype, "analyse"); - - const source = "const http = require(\"http\");"; - new AstAnalyser().analyse(source, { module: true, removeHTMLComments: true }); - - const source2 = "const fs = require(\"fs\");"; - new AstAnalyser().analyse(source2, { module: false, removeHTMLComments: false }); - - const calls = AstAnalyser.prototype.analyse.mock.calls; - assert.strictEqual(calls.length, 2); - - assert.deepEqual(calls[0].arguments, [source, { module: true, removeHTMLComments: true }]); - assert.deepEqual(calls[1].arguments, [source2, { module: false, removeHTMLComments: false }]); -}); - -it("should instantiate AstAnalyser with the expected parser", (t) => { - t.mock.method(JsSourceParser.prototype, "parse"); - t.mock.method(FakeSourceParser.prototype, "parse"); - - new AstAnalyser().analyse("const http = require(\"http\");", { module: true, removeHTMLComments: true }); - - new AstAnalyser({ - customParser: new FakeSourceParser() - }).analyse("const fs = require(\"fs\");", - { module: false, removeHTMLComments: false } - ); - - assert.strictEqual(JsSourceParser.prototype.parse.mock.calls.length, 1); - assert.strictEqual(FakeSourceParser.prototype.parse.mock.calls.length, 1); -}); - -it("should append list of probes using runASTAnalysis", () => { - const result = new AstAnalyser( - { - parser: new JsSourceParser(), - customProbes, - skipDefaultProbes: false - } - ).analyse(kIncriminedCodeSampleCustomProbe); - - assert.equal(result.warnings[0].kind, kWarningUnsafeDanger); - assert.equal(result.warnings[1].kind, kWarningUnsafeImport); - assert.equal(result.warnings[2].kind, kWarningUnsafeStmt); - assert.equal(result.warnings.length, 3); -}); - -it("should replace list of probes using runASTAnalysis", () => { - const result = new AstAnalyser( - { - parser: new JsSourceParser(), - customProbes, - skipDefaultProbes: true - } - ).analyse(kIncriminedCodeSampleCustomProbe); - - assert.equal(result.warnings[0].kind, kWarningUnsafeDanger); - assert.equal(result.warnings.length, 1); -}); diff --git a/test/runASTAnalysisOnFile.spec.js b/test/runASTAnalysisOnFile.spec.js deleted file mode 100644 index d44f0cc..0000000 --- a/test/runASTAnalysisOnFile.spec.js +++ /dev/null @@ -1,89 +0,0 @@ -// Import Node.js Dependencies -import { it } from "node:test"; -import assert from "node:assert"; - -// Import Internal Dependencies -import { - AstAnalyser, - JsSourceParser -} from "../index.js"; -import { FakeSourceParser } from "./fixtures/FakeSourceParser.js"; -import { - customProbes, - kWarningUnsafeDanger, - kWarningUnsafeImport, - kWarningUnsafeStmt -} from "./utils/index.js"; - -// CONSTANTS -const FIXTURE_URL = new URL("fixtures/searchRuntimeDependencies/", import.meta.url); - -it("should call AstAnalyser.analyseFile with the expected arguments", async(t) => { - t.mock.method(AstAnalyser.prototype, "analyseFile"); - - const url = new URL("depName.js", FIXTURE_URL); - await new AstAnalyser().analyseFile( - url, - { module: false, packageName: "foobar" } - ); - - const url2 = new URL("parsingError.js", FIXTURE_URL); - await new AstAnalyser().analyseFile( - url, - { module: true, packageName: "foobar2" } - ); - - const calls = AstAnalyser.prototype.analyseFile.mock.calls; - assert.strictEqual(calls.length, 2); - - assert.deepEqual(calls[0].arguments, [url, { module: false, packageName: "foobar" }]); - assert.deepEqual(calls[1].arguments, [url2, { module: true, packageName: "foobar2" }]); -}); - -it("should instantiate AstAnalyser with the expected parser", async(t) => { - t.mock.method(JsSourceParser.prototype, "parse"); - t.mock.method(FakeSourceParser.prototype, "parse"); - - await new AstAnalyser().analyseFile( - new URL("depName.js", FIXTURE_URL), - { module: false, packageName: "foobar" } - ); - - await new AstAnalyser( - { customParser: new FakeSourceParser() } - ).analyseFile( - new URL("parsingError.js", FIXTURE_URL), - { module: true, packageName: "foobar2" } - ); - - assert.strictEqual(JsSourceParser.prototype.parse.mock.calls.length, 1); - assert.strictEqual(FakeSourceParser.prototype.parse.mock.calls.length, 1); -}); - -it("should append list of probes using runASTAnalysisOnFile", async() => { - const result = await new AstAnalyser( - { - parser: new JsSourceParser(), - customProbes, - skipDefaultProbes: false - } - ).analyseFile(new URL("customProbe.js", FIXTURE_URL)); - - assert.equal(result.warnings[0].kind, kWarningUnsafeDanger); - assert.equal(result.warnings[1].kind, kWarningUnsafeImport); - assert.equal(result.warnings[2].kind, kWarningUnsafeStmt); - assert.equal(result.warnings.length, 3); -}); - -it("should replace list of probes using runASTAnalysisOnFile", async() => { - const result = await new AstAnalyser( - { - parser: new JsSourceParser(), - customProbes, - skipDefaultProbes: true - } - ).analyseFile(new URL("customProbe.js", FIXTURE_URL)); - - assert.equal(result.warnings[0].kind, kWarningUnsafeDanger); - assert.equal(result.warnings.length, 1); -}); From 68dae0ac9f7019c6b54968bfdbf4973407b362ec Mon Sep 17 00:00:00 2001 From: fraxken Date: Fri, 16 Aug 2024 21:02:38 +0200 Subject: [PATCH 2/3] chore: cleanup docs API & d.ts --- README.md | 158 +------------------------- docs/api/AstAnalyser.md | 93 ++++++++++++++- index.d.ts | 4 - types/api.d.ts | 11 -- workspaces/ts-source-parser/README.md | 4 +- 5 files changed, 97 insertions(+), 173 deletions(-) diff --git a/README.md b/README.md index d6d1c6b..fa87060 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,11 @@ The analysis will return: `http` (in try), `crypto`, `util` and `fs`. > [!TIP] > There is also a lot of suspicious code example in the `./examples` cases directory. Feel free to try the tool on these files. +## API + +- [AstAnalyser](./docs/api/AstAnalyser.md) +- [EntryFilesAnalyser](./docs/api/EntryFilesAnalyser.md) + ## Warnings This section describes how use `warnings` export. @@ -118,7 +123,7 @@ import * as i18n from "@nodesecure/i18n"; console.log(i18n.getTokenSync(jsxray.warnings["parsing-error"].i18n)); ``` -## Warnings Legends +### Legends This section describe all the possible warnings returned by JSXRay. Click on the warning **name** for additional information and examples. @@ -136,157 +141,6 @@ This section describe all the possible warnings returned by JSXRay. Click on the | [weak-crypto](./docs/weak-crypto.md) | ✔️ | The code probably contains a weak crypto algorithm (md5, sha1...) | | [shady-link](./docs/shady-link.md) | ✔️ | The code contains shady/unsafe link | -## Custom Probes - -You can also create custom probes to detect specific pattern in the code you are analyzing. - -A probe is a pair of two functions (`validateNode` and `main`) that will be called on each node of the AST. It will return a warning if the pattern is detected. -Below a basic probe that detect a string assignation to `danger`: - -```ts -export const customProbes = [ - { - name: "customProbeUnsafeDanger", - validateNode: (node, sourceFile) => [ - node.type === "VariableDeclaration" && node.declarations[0].init.value === "danger" - ], - main: (node, options) => { - const { sourceFile, data: calleeName } = options; - if (node.declarations[0].init.value === "danger") { - sourceFile.addWarning("unsafe-danger", calleeName, node.loc); - - return ProbeSignals.Skip; - } - - return null; - } - } -]; -``` - -You can pass an array of probes to the `runASTAnalysis/runASTAnalysisOnFile` functions as `options`, or directly to the `AstAnalyser` constructor. - -| Name | Type | Description | Default Value | -|------------------|----------------------------------|-----------------------------------------------------------------------|-----------------| -| `customParser` | `SourceParser \| undefined` | An optional custom parser to be used for parsing the source code. | `JsSourceParser` | -| `customProbes` | `Probe[] \| undefined` | An array of custom probes to be used during AST analysis. | `[]` | -| `skipDefaultProbes` | `boolean \| undefined` | If `true`, default probes will be skipped and only custom probes will be used. | `false` | - - -Here using the example probe upper: - -```ts -import { AstAnalyser } from "@nodesecure/js-x-ray"; - -// add your customProbes here (see example above) - -const scanner = new AstAnalyser({ - customProbes, - skipDefaultProbes: true -}); - -const result = scanner.analyse("const danger = 'danger';"); - -console.log(result); -``` - -Result: - -```sh -✗ node example.js -{ - idsLengthAvg: 0, - stringScore: 0, - warnings: [ { kind: 'unsafe-danger', location: [Array], source: 'JS-X-Ray' } ], - dependencies: Map(0) {}, - isOneLineRequire: false -} -``` - -Congrats, you have created your first custom probe! 🎉 - -> [!TIP] -> Check the types in [index.d.ts](index.d.ts) and [types/api.d.ts](types/api.d.ts) for more details about the `options` - -## API - -- [AstAnalyser](./docs/api/AstAnalyser.md) -- [EntryFilesAnalyser](./docs/api/EntryFilesAnalyser.md) - -Legacy APIs waiting to be deprecated; - -
-runASTAnalysis(str: string, options?: RuntimeOptions & AstAnalyserOptions): Report - -```ts -interface RuntimeOptions { - module?: boolean; - removeHTMLComments?: boolean; - isMinified?: boolean; - initialize?: (sourceFile: SourceFile) => void; - finalize?: (sourceFile: SourceFile) => void; -} -``` - -```ts -interface AstAnalyserOptions { - customParser?: SourceParser; - customProbes?: Probe[]; - skipDefaultProbes?: boolean; -} -``` - -The method take a first argument which is the code you want to analyse. It will return a Report Object: - -```ts -interface Report { - dependencies: ASTDeps; - warnings: Warning[]; - idsLengthAvg: number; - stringScore: number; - isOneLineRequire: boolean; -} -``` - -
- -
-runASTAnalysisOnFile(pathToFile: string, options?: RuntimeFileOptions & AstAnalyserOptions): Promise< ReportOnFile > - -```ts -interface RuntimeFileOptions { - module?: boolean; - removeHTMLComments?: boolean; - packageName?: string; - initialize?: (sourceFile: SourceFile) => void; - finalize?: (sourceFile: SourceFile) => void; -} -``` - -```ts -interface AstAnalyserOptions { - customParser?: SourceParser; - customProbes?: Probe[]; - skipDefaultProbes?: boolean; -} -``` - -Run the SAST scanner on a given JavaScript file. - -```ts -export type ReportOnFile = { - ok: true, - warnings: Warning[]; - dependencies: ASTDeps; - isMinified: boolean; -} | { - ok: false, - warnings: Warning[]; -} -``` - -
- ## Workspaces Click on one of the links to access the documentation of the workspace: diff --git a/docs/api/AstAnalyser.md b/docs/api/AstAnalyser.md index a4a7dfe..b91d607 100644 --- a/docs/api/AstAnalyser.md +++ b/docs/api/AstAnalyser.md @@ -40,12 +40,30 @@ declare class AstAnalyser { constructor(options?: AstAnalyserOptions); analyse: (str: string, options?: RuntimeOptions) => Report; analyseFile(pathToFile: string, options?: RuntimeFileOptions): Promise; + analyseFileSync(pathToFile: string, options?: RuntimeFileOptions): ReportOnFile; } ``` -The `analyseFile` method is a superset of `analyse` with the ability to read the file on the local filesystem with additional features like detecting if the file is ESM or CJS. +The `analyseFile` and `analyseFileSync` methods is a superset of `analyse` with the ability to read the file on the local filesystem with additional features like detecting if the file is ESM/CJS (using the extension). ```ts +interface RuntimeOptions { + /** + * @default true + */ + module?: boolean; + /** + * @default false + */ + removeHTMLComments?: boolean; + /** + * @default false + */ + isMinified?: boolean; + initialize?: (sourceFile: SourceFile) => void; + finalize?: (sourceFile: SourceFile) => void; +} + interface Report { dependencies: Map; warnings: Warning[]; @@ -65,9 +83,7 @@ type ReportOnFile = { } ``` -## Examples - -### `initialize`/`finalize` Hooks +### Hooks The `analyse` method allows for the integration of two hooks: `initialize` and `finalize`. These hooks are triggered before and after the analysis process, respectively. @@ -90,3 +106,72 @@ scanner.analyse("const foo = 'bar';", { } }); ``` + +## Custom Probes + +You can also create custom probes to detect specific pattern in the code you are analyzing. + +A probe is a pair of two functions (`validateNode` and `main`) that will be called on each node of the AST. It will return a warning if the pattern is detected. + +Below a basic probe that detect a string assignation to `danger`: + +```ts +export const customProbes = [ + { + name: "customProbeUnsafeDanger", + validateNode: (node, sourceFile) => [ + node.type === "VariableDeclaration" && node.declarations[0].init.value === "danger" + ], + main: (node, options) => { + const { sourceFile, data: calleeName } = options; + if (node.declarations[0].init.value === "danger") { + sourceFile.addWarning("unsafe-danger", calleeName, node.loc); + + return ProbeSignals.Skip; + } + + return null; + } + } +]; +``` + +You can pass an array of probes to the `AstAnalyser` constructor. + +| Name | Type | Description | Default Value | +|---|---|---|---| +| **customParser** | `SourceParser \| undefined` | An optional custom parser to be used for parsing the source code. | `JsSourceParser` | +| **customProbes** | `Probe[] \| undefined` | An array of custom probes to be used during AST analysis. | `[]` | +| **skipDefaultProbes** | `boolean \| undefined` | If **true**, default probes will be skipped and only custom probes will be used. | `false` | + +Here using the example probe upper: + +```ts +import { AstAnalyser } from "@nodesecure/js-x-ray"; + +// add your customProbes here (see example above) + +const scanner = new AstAnalyser({ + customProbes, + skipDefaultProbes: true +}); + +const result = scanner.analyse("const danger = 'danger';"); + +console.log(result); +``` + +Result: + +```sh +✗ node example.js +{ + idsLengthAvg: 0, + stringScore: 0, + warnings: [ { kind: 'unsafe-danger', location: [Array], source: 'JS-X-Ray' } ], + dependencies: Map(0) {}, + isOneLineRequire: false +} +``` + +Congrats, you have created your first custom probe! 🎉 diff --git a/index.d.ts b/index.d.ts index 6a46095..735f1bf 100644 --- a/index.d.ts +++ b/index.d.ts @@ -7,8 +7,6 @@ import { SourceParser, JsSourceParser, - runASTAnalysis, - runASTAnalysisOnFile, Report, ReportOnFile, RuntimeFileOptions, @@ -34,8 +32,6 @@ export { EntryFilesAnalyserOptions, JsSourceParser, SourceParser, - runASTAnalysis, - runASTAnalysisOnFile, Report, ReportOnFile, RuntimeFileOptions, diff --git a/types/api.d.ts b/types/api.d.ts index 237190d..08d392f 100644 --- a/types/api.d.ts +++ b/types/api.d.ts @@ -17,8 +17,6 @@ export { JsSourceParser, SourceParser, - runASTAnalysis, - runASTAnalysisOnFile, RuntimeOptions, RuntimeFileOptions, @@ -168,12 +166,3 @@ declare class EntryFilesAnalyser { declare class JsSourceParser implements SourceParser { parse(source: string, options: unknown): Statement[]; } - -declare function runASTAnalysis( - str: string, - options?: RuntimeOptions & AstAnalyserOptions -): Report; -declare function runASTAnalysisOnFile( - pathToFile: string, - options?: RuntimeFileOptions & AstAnalyserOptions -): Promise; diff --git a/workspaces/ts-source-parser/README.md b/workspaces/ts-source-parser/README.md index ebe1969..a90da91 100644 --- a/workspaces/ts-source-parser/README.md +++ b/workspaces/ts-source-parser/README.md @@ -30,7 +30,7 @@ console.log(body); ## Usage with `js-x-ray` ```js -import { runASTAnalysis } from "@nodesecure/js-x-ray"; +import { AstAnalyser } from "@nodesecure/js-x-ray"; import { readFileSync } from "node:fs"; const { warnings, dependencies } = runASTAnalysis( @@ -40,4 +40,4 @@ const { warnings, dependencies } = runASTAnalysis( console.log(dependencies); console.dir(warnings, { depth: null }); -``` \ No newline at end of file +``` From 32e71b35e938b61c450ea6d55b8a918fe9d9b53c Mon Sep 17 00:00:00 2001 From: fraxken Date: Fri, 16 Aug 2024 21:04:42 +0200 Subject: [PATCH 3/3] refactor: unset experimental for shady-link, suspicious-file and weak-crypto --- README.md | 6 +++--- docs/shady-link.md | 4 ++-- docs/suspicious-file.md | 2 +- docs/weak-crypto.md | 2 +- src/warnings.js | 6 +++--- test/probes/isWeakCrypto.spec.js | 2 -- test/warnings.spec.js | 2 +- 7 files changed, 11 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index fa87060..e95a587 100644 --- a/README.md +++ b/README.md @@ -136,10 +136,10 @@ This section describe all the possible warnings returned by JSXRay. Click on the | [encoded-literal](./docs/encoded-literal.md) | ❌ | An encoded literal has been detected (it can be an hexa value, unicode sequence or a base64 string) | | [short-identifiers](./docs/short-identifiers.md) | ❌ | This mean that all identifiers has an average length below 1.5. | | [suspicious-literal](./docs/suspicious-literal.md) | ❌ | A suspicious literal has been found in the source code. | -| [suspicious-file](./docs/suspicious-file.md) | ✔️ | A suspicious file with more than ten encoded-literal in it | +| [suspicious-file](./docs/suspicious-file.md) | ❌ | A suspicious file with more than ten encoded-literal in it | | [obfuscated-code](./docs/obfuscated-code.md) | ✔️ | There's a very high probability that the code is obfuscated. | -| [weak-crypto](./docs/weak-crypto.md) | ✔️ | The code probably contains a weak crypto algorithm (md5, sha1...) | -| [shady-link](./docs/shady-link.md) | ✔️ | The code contains shady/unsafe link | +| [weak-crypto](./docs/weak-crypto.md) | ❌ | The code probably contains a weak crypto algorithm (md5, sha1...) | +| [shady-link](./docs/shady-link.md) | ❌ | The code contains shady/unsafe link | ## Workspaces diff --git a/docs/shady-link.md b/docs/shady-link.md index a422604..8ce6262 100644 --- a/docs/shady-link.md +++ b/docs/shady-link.md @@ -1,7 +1,7 @@ # Shady link | Code | Severity | i18n | Experimental | | --- | --- | --- | :-: | -| shady-link | `Warning` | `sast_warnings.shady_link` | ✔️ | +| shady-link | `Warning` | `sast_warnings.shady_link` | ❌ | ## Introduction @@ -36,4 +36,4 @@ const IPv6URL = "http://2444:1130:80:2aa8:c313:150d:b8cf:c321/script"; > [!IMPORTANT]\ > Credit goes to the [guarddog](https://github.dev/DataDog/guarddog) team.\ -> Credit goes to the [ietf.org](https://www.ietf.org/rfc/rfc3986.txt). \ No newline at end of file +> Credit goes to the [ietf.org](https://www.ietf.org/rfc/rfc3986.txt). diff --git a/docs/suspicious-file.md b/docs/suspicious-file.md index dbbb1da..8046592 100644 --- a/docs/suspicious-file.md +++ b/docs/suspicious-file.md @@ -2,7 +2,7 @@ | Code | Severity | i18n | Experimental | | --- | --- | --- | :-: | -| suspicious-file | `Critical` | `sast_warnings.suspicious_file` | ✔️ | +| suspicious-file | `Critical` | `sast_warnings.suspicious_file` | ❌ | ## Introduction diff --git a/docs/weak-crypto.md b/docs/weak-crypto.md index 251273e..ec17254 100644 --- a/docs/weak-crypto.md +++ b/docs/weak-crypto.md @@ -2,7 +2,7 @@ | Code | Severity | i18n | Experimental | | --- | --- | --- | :-: | -| weak-crypto | `Information` | `sast_warnings.weak_crypto` | ✔️ | +| weak-crypto | `Information` | `sast_warnings.weak_crypto` | ❌ | ## Introduction diff --git a/src/warnings.js b/src/warnings.js index e80b110..e8deebe 100644 --- a/src/warnings.js +++ b/src/warnings.js @@ -34,7 +34,7 @@ export const warnings = Object.freeze({ "suspicious-file": { i18n: "sast_warnings.suspicious_file", severity: "Critical", - experimental: true + experimental: false }, "obfuscated-code": { i18n: "sast_warnings.obfuscated_code", @@ -44,12 +44,12 @@ export const warnings = Object.freeze({ "weak-crypto": { i18n: "sast_warnings.weak_crypto", severity: "Information", - experimental: true + experimental: false }, "shady-link": { i18n: "sast_warnings.shady_link", severity: "Warning", - experimental: true + experimental: false } }); diff --git a/test/probes/isWeakCrypto.spec.js b/test/probes/isWeakCrypto.spec.js index 2f162d8..3f7c655 100644 --- a/test/probes/isWeakCrypto.spec.js +++ b/test/probes/isWeakCrypto.spec.js @@ -21,7 +21,6 @@ test("it should report a warning in case of `createHash()` usage", as assert.strictEqual(outputWarnings.length, 1); assert.deepEqual(firstWarning.kind, "weak-crypto"); assert.strictEqual(firstWarning.value, fixtureFile.split(".").at(0)); - assert.ok(firstWarning.experimental); } }); @@ -37,7 +36,6 @@ test("it should report a warning in case of `[expression]createHash() assert.strictEqual(outputWarnings.length, 1); assert.deepEqual(firstWarning.kind, "weak-crypto"); assert.strictEqual(firstWarning.value, fixtureFile.split(".").at(0)); - assert.ok(firstWarning.experimental); } }); diff --git a/test/warnings.spec.js b/test/warnings.spec.js index c59db32..827ec38 100644 --- a/test/warnings.spec.js +++ b/test/warnings.spec.js @@ -40,6 +40,6 @@ test("Given a weak-crypto kind it should generate a warning with value, simple l ], i18n: "sast_warnings.weak_crypto", severity: "Information", - experimental: true + experimental: false }); });