Skip to content

Commit e98f3e5

Browse files
committed
Refactor to general checkQuery
1 parent adb4a87 commit e98f3e5

File tree

4 files changed

+24
-40
lines changed

4 files changed

+24
-40
lines changed

library/vulnerabilities/attack-wave-detection/containsSQLSyntax.test.ts renamed to library/vulnerabilities/attack-wave-detection/checkQuery.test.ts

Lines changed: 13 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import * as t from "tap";
2-
import { containsSQLSyntax } from "./containsSQLSyntax";
2+
import { checkQuery } from "./checkQuery";
33
import type { Context } from "../../agent/Context";
44

5-
function getTestContext(path: string, query: string): Context {
5+
function getTestContext(query: string): Context {
66
return {
77
remoteAddress: "::1",
88
method: "GET",
9-
url: `http://localhost:4000${path}`,
9+
url: `http://localhost:4000/test`,
1010
query: {
1111
test: query,
1212
utmSource: "newsletter",
@@ -21,52 +21,32 @@ function getTestContext(path: string, query: string): Context {
2121
cookies: {},
2222
routeParams: {},
2323
source: "express",
24-
route: path,
24+
route: "/test",
2525
};
2626
}
2727

28-
t.test("it detects SQL injection patterns", async (t) => {
28+
t.test("it detects injection patterns", async (t) => {
2929
const testStrings = [
3030
"' or '1'='1",
3131
"1: SELECT * FROM users WHERE '1'='1'",
3232
"', information_schema.tables",
3333
"1' sleep(5)",
3434
"WAITFOR DELAY 1",
35+
"../etc/passwd",
3536
];
3637

3738
for (const str of testStrings) {
38-
t.ok(
39-
containsSQLSyntax(getTestContext(`/test`, str)),
40-
`Expected ${str} to match SQL injection patterns`
41-
);
39+
t.ok(checkQuery(getTestContext(str)), `Expected ${str} to match patterns`);
4240
}
4341
});
4442

4543
t.test("it does not detect", async (t) => {
46-
const nonMatchingPaths = [
47-
"/",
48-
"/api/user",
49-
"/blog/a+blog+article",
50-
"/products/1",
51-
"/search?q=normal+search+term",
52-
"/user/profile",
53-
"/orders/1",
54-
"/static/somefile.s1f56e.css",
55-
"/favicon.ico",
56-
"/img/mysql.svg",
57-
"/get/test",
58-
"/.well-known/security.txt",
59-
"/robots.txt",
60-
"/sitemap.xml",
61-
"/manifest.json",
62-
"/prototype/test.txt",
63-
"/test?data=test&data2=test2",
64-
];
44+
const nonMatchingQueryElements = ["google.de", "some-string", "1", ""];
6545

66-
for (const str of nonMatchingPaths) {
46+
for (const str of nonMatchingQueryElements) {
6747
t.notOk(
68-
containsSQLSyntax(getTestContext(str, "")),
69-
`Expected ${str} to NOT match SQL injection patterns`
48+
checkQuery(getTestContext(str)),
49+
`Expected ${str} to NOT match patterns`
7050
);
7151
}
7252
});
@@ -88,7 +68,7 @@ t.test("it handles empty query object", async (t) => {
8868
};
8969

9070
t.notOk(
91-
containsSQLSyntax(contextWithEmptyQuery),
92-
"Expected empty query to NOT match SQL injection patterns"
71+
checkQuery(contextWithEmptyQuery),
72+
"Expected empty query to NOT match injection patterns"
9373
);
9474
});

library/vulnerabilities/attack-wave-detection/containsSQLSyntax.ts renamed to library/vulnerabilities/attack-wave-detection/checkQuery.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,21 @@ const keywords = [
99
"SELECT LIKE(CHAR(",
1010
"INFORMATION_SCHEMA.COLUMNS",
1111
"INFORMATION_SCHEMA.TABLES",
12-
",MD5(",
12+
"MD5(",
1313
"DBMS_PIPE.RECEIVE_MESSAGE",
1414
"SYSIBM.SYSTABLES",
1515
"RANDOMBLOB(",
1616
"SELECT * FROM",
1717
"1'='1",
1818
"PG_SLEEP(",
1919
"UNION ALL SELECT",
20+
"../",
2021
];
2122

22-
export function containsSQLSyntax(context: Context): boolean {
23+
/**
24+
* Check the query for some common SQL or path traversal patterns.
25+
*/
26+
export function checkQuery(context: Context): boolean {
2327
const queryStrings = extractStringsFromUserInputCached(context, "query");
2428
if (!queryStrings) {
2529
return false;

library/vulnerabilities/attack-wave-detection/isWebScanner.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,9 @@ t.test("is a web scanner", async (t) => {
2828
t.ok(isWebScanner(getTestContext("/../secret", "GET")));
2929
t.ok(isWebScanner(getTestContext("/", "BADMETHOD")));
3030
t.ok(
31-
isWebScanner(
32-
getTestContext("/", "GET", { test: "1'; DROP TABLE users; --" })
33-
)
31+
isWebScanner(getTestContext("/", "GET", { test: "SELECT * FROM admin" }))
3432
);
33+
t.ok(isWebScanner(getTestContext("/", "GET", { test: "../etc/passwd" })));
3534
});
3635

3736
t.test("is not a web scanner", async (t) => {
@@ -41,4 +40,5 @@ t.test("is not a web scanner", async (t) => {
4140
t.notOk(isWebScanner(getTestContext("/static/js/app.js", "GET")));
4241
t.notOk(isWebScanner(getTestContext("/uploads/image.png", "GET")));
4342
t.notOk(isWebScanner(getTestContext("/", "GET", { test: "1'" })));
43+
t.notOk(isWebScanner(getTestContext("/", "GET", { test: "abcd" })));
4444
});

library/vulnerabilities/attack-wave-detection/isWebScanner.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { type Context } from "../../agent/Context";
2-
import { containsSQLSyntax } from "./containsSQLSyntax";
2+
import { checkQuery } from "./checkQuery";
33
import { isWebScanMethod } from "./isWebScanMethod";
44
import { isWebScanPath } from "./isWebScanPath";
55

@@ -12,7 +12,7 @@ export function isWebScanner(context: Context): boolean {
1212
return true;
1313
}
1414

15-
if (containsSQLSyntax(context)) {
15+
if (checkQuery(context)) {
1616
return true;
1717
}
1818

0 commit comments

Comments
 (0)