Skip to content
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

add shady link regex for check url with ips #260

Merged
merged 5 commits into from
May 6, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
32 changes: 27 additions & 5 deletions docs/shady-link.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,35 @@

## Introduction

Identify when a Literal (string) contains an URL to a domain with a **suspicious extension**.
Identify when a literal (string) contains a suspicious URL:
- To a domain with a **suspicious** extension.
- URLs with a raw **IP address**.

> [!IMPORTANT]
> Credit goes to the [guarddog](https://github.dev/DataDog/guarddog) team.

## Example
## A suspicious domain

```js
const foo = "http://foo.xyz";
```

## URL with a dangerous raw IP address

URLs containing raw IP addresses can be considered potentially dangerous for several reasons:

- **Phishing and social engineering**: Attackers can use raw IP addresses in URLs to hide the true destination of the link.

- **Malware and code injection attacks**: Raw IP addresses can point to malicious websites that host malware or use compromising code injection techniques.

- **Privacy violations**: Bypass proxy servers or firewalls designed to block access to certain websites, thereby exposing users.

```js
const IPv4URL = "http://77.244.210.247/script";

const IPv6URL = "http://2444:1130:80:2aa8:c313:150d:b8cf:c321/script";
```

<br />
<br />

> [!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).
10 changes: 9 additions & 1 deletion src/probes/isLiteral.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,21 @@ import { builtinModules } from "repl";
// Import Third-party Dependencies
import { Hex } from "@nodesecure/sec-literal";


const kMapRegexIps = Object.freeze({
regexIPv4With: /^(https?:\/\/)(?!127\.)(?!.*:(?:0{1,3}|25[6-9])\.)(?!.*:(?:25[6-9])\.(?:0{1,3}|25[6-9])\.)(?!.*:(?:25[6-9])\.(?:25[6-9])\.(?:0{1,3}|25[6-9])\.)(?!.*:(?:25[6-9])\.(?:25[6-9])\.(?:25[6-9])\.(?:0{1,3}|25[6-9]))((?:\d{1,2}|1\d{2}|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d{2}|2[0-4]\d|25[0-5])(?::\d{1,5})?(\/[^\s]*)?$/,
regexIPv6With: /^(https?:\/\/)(\[[0-9A-Fa-f:]+\])(?::\d{1,5})?(\/[^\s]*)?$/
})

sairuss7 marked this conversation as resolved.
Show resolved Hide resolved

// CONSTANTS
const kNodeDeps = new Set(builtinModules);
const kShadyLinkRegExps = [
kMapRegexIps.regexIPv4With,
kMapRegexIps.regexIPv6With,
/(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
* @see https://github.com/estree/estree/blob/master/es5.md#literal
Expand Down
62 changes: 62 additions & 0 deletions test/probes/isLiteral.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,65 @@ test("should detect shady link when an URL has a suspicious domain", () => {
const warning = sastAnalysis.getWarning("shady-link");
assert.strictEqual(warning.value, "http://foobar.link");
});


test("should not mark suspicious links the IPv4 address range 127.0.0.0/8 (localhost 127.0.0.1)", () => {
const str = "const IPv4URL = ['http://127.0.0.1/script', 'http://127.7.7.7/script']";
const ast = parseScript(str);
const sastAnalysis = getSastAnalysis(str, isLiteral).execute(ast.body);

assert.ok(!sastAnalysis.warnings().length);
});


test("should not be considered suspicious a link with a raw IPv4 address 127.0.0.1 and a port", () => {
const str = "const IPv4URL = 'http://127.0.0.1:80/script'";
const ast = parseScript(str);
const sastAnalysis = getSastAnalysis(str, isLiteral).execute(ast.body);

assert.ok(!sastAnalysis.warnings().length);
});

test("should detect the link as suspicious when a URL contains a raw IPv4 address", () => {
const str = "const IPv4URL = 'http://77.244.210.247/burpcollaborator.txt'";
const ast = parseScript(str);
const sastAnalysis = getSastAnalysis(str, isLiteral).execute(ast.body);

assert.strictEqual(sastAnalysis.warnings().length, 1);
const warning = sastAnalysis.getWarning("shady-link");
assert.strictEqual(warning.value, "http://77.244.210.247/burpcollaborator.txt");
});



test("should detect suspicious links when a URL contains a raw IPv4 address with port", () => {
const str = "const IPv4URL = 'http://77.244.210.247:8080/script'";
const ast = parseScript(str);
const sastAnalysis = getSastAnalysis(str, isLiteral).execute(ast.body);

assert.strictEqual(sastAnalysis.warnings().length, 1);
const warning = sastAnalysis.getWarning("shady-link");
assert.strictEqual(warning.value, "http://77.244.210.247:8080/script");
});


test("should detect suspicious links when a URL contains a raw IPv6 address", () => {
const str = "const IPv6URL = 'http://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]/index.html'";
const ast = parseScript(str);
const sastAnalysis = getSastAnalysis(str, isLiteral).execute(ast.body);

assert.strictEqual(sastAnalysis.warnings().length, 1);
const warning = sastAnalysis.getWarning("shady-link");
assert.strictEqual(warning.value, "http://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]/index.html");
});


test("should detect suspicious links when a URL contains a raw IPv6 address with port", () => {
const str = "const IPv6URL = 'http://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:100/script'";
const ast = parseScript(str);
const sastAnalysis = getSastAnalysis(str, isLiteral).execute(ast.body);

assert.strictEqual(sastAnalysis.warnings().length, 1);
const warning = sastAnalysis.getWarning("shady-link");
assert.strictEqual(warning.value, "http://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:100/script");
});
Loading