Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ type WarningName = "parsing-error"
| "suspicious-file"
| "obfuscated-code"
| "weak-crypto"
| "unsafe-import";
| "unsafe-import"
| "shady-link";

declare const warnings: Record<WarningName, {
i18n: string;
Expand Down Expand Up @@ -137,6 +138,7 @@ This section describe all the possible warnings returned by JSXRay. Click on the
| [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 |

## API

Expand Down
16 changes: 16 additions & 0 deletions docs/shady-link.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Shady link
| Code | Severity | i18n | Experimental |
| --- | --- | --- | :-: |
| shady-link | `Warning` | `sast_warnings.shady_link` | ✔️ |

## Introduction

Identify when a Literal (string) contains an URL to a domain with a suspicious extension.

> **Note** credit goes to the [guarddog](https://github.dev/DataDog/guarddog) team.

## Example

```js
const foo = "http://foo.xyz";
```
12 changes: 12 additions & 0 deletions src/probes/isLiteral.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import { Hex } from "@nodesecure/sec-literal";

// CONSTANTS
const kNodeDeps = new Set(builtinModules);
const kShadyLinkRegExps = [
/(http[s]?:\/\/bit\.ly.*)$/,
/(http[s]?:\/\/.*\.(link|xyz|tk|ml|ga|cf|gq|pw|top|club|mw|bd|ke|am|sbs|date|quest|cd|bid|cd|ws|icu|cam|uno|email|stream))$/
];

/**
* @description Search for Literal AST Node
Expand Down Expand Up @@ -39,6 +43,14 @@ function main(node, options) {
}
// Else we are checking all other string with our suspect method
else {
for (const regex of kShadyLinkRegExps) {
if (regex.test(node.value)) {
analysis.addWarning("shady-link", node.value, node.loc);

return;
}
}

analysis.analyzeLiteral(node);
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/warnings.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ export const warnings = Object.freeze({
i18n: "sast_warnings.weak_crypto",
severity: "Information",
experimental: true
},
"shady-link": {
i18n: "sast_warnings.shady_link",
severity: "Warning",
experimental: true
}
});

Expand Down
25 changes: 25 additions & 0 deletions test/probes/isLiteral.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,28 @@ test("should not throw any warnings without hexadecimal value (and should call a

tape.end();
});

test("should detect shady link when an URL is bit.ly", (tape) => {
const str = "const foo = 'http://bit.ly/foo'";
const ast = parseScript(str);
const sastAnalysis = getSastAnalysis(str, isLiteral).execute(ast.body);

tape.strictEqual(sastAnalysis.warnings().length, 1);
const warning = sastAnalysis.getWarning("shady-link");
tape.strictEqual(warning.value, "http://bit.ly/foo");

tape.end();
});


test("should detect shady link when an URL has a suspicious domain", (tape) => {
const str = "const foo = 'http://foobar.link'";
const ast = parseScript(str);
const sastAnalysis = getSastAnalysis(str, isLiteral).execute(ast.body);

tape.strictEqual(sastAnalysis.warnings().length, 1);
const warning = sastAnalysis.getWarning("shady-link");
tape.strictEqual(warning.value, "http://foobar.link");

tape.end();
});
3 changes: 2 additions & 1 deletion types/warnings.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ type WarningNameWithValue = "parsing-error"
| "suspicious-literal"
| "suspicious-file"
| "obfuscated-code"
| "weak-crypto";
| "weak-crypto"
| "shady-link";
type WarningName = WarningNameWithValue | "unsafe-import";

type WarningLocation = [[number, number], [number, number]];
Expand Down