Skip to content

Commit 594488b

Browse files
committed
TMP: address feedback
- Add a flag to disable bug detectors using patterns - Add a config that uses custom hooks to detect a finding - Clean the stack of the error messages properly - Refactoring, clean up
1 parent 3b2ca6b commit 594488b

16 files changed

Lines changed: 204 additions & 182 deletions

File tree

examples/bug-detectors-command-injection/package.json

Lines changed: 0 additions & 16 deletions
This file was deleted.

examples/bug-detectors-command-injection/fuzz.js renamed to examples/bug-detectors/command-injection/fuzz.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
const { FuzzedDataProvider } = require("@jazzer.js/core");
1919
// eslint-disable-next-line @typescript-eslint/no-var-requires
2020
const root = require("global-modules-path");
21-
2221
module.exports.fuzz = function (data) {
2322
const provider = new FuzzedDataProvider(data);
2423
const str1 = provider.consumeString(provider.consumeIntegralInRange(1, 20));
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "bug-detectors",
3+
"version": "1.0.0",
4+
"main": "fuzz.js",
5+
"license": "ISC",
6+
"dependencies": {
7+
"global-modules-path": "^2.3.1"
8+
},
9+
"scripts": {
10+
"customHooks": "jazzer fuzz -i global-modules-path --disable_bug_detectors='.*' -h custom-hooks --timeout=100000000 --sync -- -runs=100000 -print_final_stats=1",
11+
"bugDetectors": "jazzer fuzz -i global-modules-path --timeout=100000000 --sync -- -runs=100000 -print_final_stats=1",
12+
"dryRun": "jazzer fuzz --sync -x Error -- -runs=100000 -seed=123456789"
13+
},
14+
"devDependencies": {
15+
"@jazzer.js/core": "file:../../packages/core"
16+
}
17+
}

packages/bug-detectors/command-injection.ts

Lines changed: 0 additions & 74 deletions
This file was deleted.

packages/bug-detectors/findings.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,26 @@
1-
export class Finding extends Error {}
1+
/*
2+
* Copyright 2022 Code Intelligence GmbH
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* Examples showcasing the custom hooks API
17+
*/
18+
19+
export class Finding extends Error {
20+
constructor(message: string) {
21+
super(message);
22+
}
23+
}
224

325
// The first finding found by any bug detector will be saved here.
426
// This is a global variable shared between the core-library (read, reset) and the bug detectors (write).

packages/bug-detectors/index.ts

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,29 @@ export {
2323
} from "./findings";
2424

2525
// Checks in the global options if the bug detector should be loaded.
26-
export function shouldLoadBugDetector(bugDetectorName: string): boolean {
27-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
28-
// @ts-ignore
29-
return !global.options.excludeBugDetectors.includes(bugDetectorName);
26+
function shouldDisableBugDetector(
27+
disableBugDetectors: RegExp[],
28+
bugDetectorName: string
29+
): boolean {
30+
// pattern match for bugDetectorName in disableBugDetectors
31+
for (const pattern of disableBugDetectors) {
32+
if (pattern.test(bugDetectorName)) {
33+
if (process.env.JAZZER_DEBUG)
34+
console.log(
35+
`Skip loading bug detector ${bugDetectorName} because it matches ${pattern}`
36+
);
37+
return true;
38+
}
39+
}
40+
return false;
3041
}
3142

32-
// Checks in the global options if the bug detector should be loaded in safe mode.
33-
export function isSafeModeEnabled(): boolean {
34-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
35-
// @ts-ignore
36-
return global.options.bugDetectorsSafeMode;
37-
}
38-
39-
import { loadCommandInjectionBugDetector } from "./command-injection";
40-
41-
export function loadBugDetectors(): void {
42-
loadCommandInjectionBugDetector();
43+
export async function loadBugDetectors(
44+
disableBugDetectors: RegExp[]
45+
): Promise<void> {
46+
// Dynamic imports require either absolute path, or a relative path with .js extension.
47+
// This is ok, since our .ts files are compiled to .js files.
48+
if (!shouldDisableBugDetector(disableBugDetectors, "Command Injection")) {
49+
await import("./internal/command-injection.js");
50+
}
4351
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright 2023 Code Intelligence GmbH
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { reportFinding } from "../findings";
18+
import { guideTowardsEquality } from "@jazzer.js/fuzzer";
19+
import { registerBeforeHook } from "@jazzer.js/hooking";
20+
21+
/**
22+
* Importing this file adds "before-hooks" for all functions in the built-in `child_process` module and guides
23+
* the fuzzer towards the uniquely chosen `goal` string `"jaz_zer"`. If the goal is found in the first argument
24+
* of any hooked function, a `Finding` is reported.
25+
*/
26+
const goal = "jaz_zer";
27+
const moduleName = "child_process";
28+
29+
const functionNames = [
30+
"exec",
31+
"execSync",
32+
"execFile",
33+
"execFileSync",
34+
"spawn",
35+
"spawnSync",
36+
"fork",
37+
];
38+
39+
for (const functionName of functionNames) {
40+
const beforeHook = (thisPtr: unknown, params: unknown[], hookId: number) => {
41+
if (params === undefined || params.length === 0) {
42+
return;
43+
}
44+
// The first argument of the original function is:
45+
// - the command to execute in exec/execSync, and spawn/spawnSync
46+
// - the command/file path to execute in execFile/execFileSync
47+
// - the module path to fork in fork
48+
const firstArgument = params[0] as string;
49+
if (firstArgument.includes(goal)) {
50+
reportFinding(
51+
`Command Injection in ${functionName}(): called with '${firstArgument}'`
52+
);
53+
}
54+
guideTowardsEquality(firstArgument, goal, hookId);
55+
};
56+
57+
registerBeforeHook(functionName, moduleName, false, beforeHook);
58+
}

packages/bug-detectors/tsconfig.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
},
77
"references": [
88
{
9-
"path": "../instrumentor"
9+
"path": "../fuzzer"
1010
},
1111
{
12-
"path": "../fuzzer"
12+
"path": "../hooking"
1313
}
1414
]
1515
}

packages/core/cli.ts

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -191,23 +191,15 @@ yargs(process.argv.slice(2))
191191
group: "Fuzzer:",
192192
default: 5000,
193193
})
194-
.array("excludeBugDetectors")
195-
.option("excludeBugDetectors", {
194+
.array("disable_bug_detectors")
195+
.option("disable_bug_detectors", {
196196
describe:
197-
"A list of bug detectors to exclude. By default all internal " +
197+
"A list of patterns to disable internal bug detectors. By default all internal " +
198198
"bug detectors are enabled. Following bug detectors are available: " +
199199
'"Command Injection"',
200200
type: "string",
201201
group: "Fuzzer:",
202202
default: [],
203-
})
204-
.option("bugDetectorsSafeMode", {
205-
describe:
206-
"Bug detectors run in safe mode, which means that the original functions will not " +
207-
"be called.",
208-
type: "boolean",
209-
group: "Fuzzer:",
210-
default: false,
211203
});
212204
},
213205
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -231,8 +223,9 @@ yargs(process.argv.slice(2))
231223
coverage: args.cov,
232224
coverageDirectory: args.cov_dir,
233225
coverageReporters: args.cov_reporters,
234-
excludeBugDetectors: args.excludeBugDetectors,
235-
bugDetectorsSafeMode: args.bugDetectorsSafeMode,
226+
disableBugDetectors: args.disable_bug_detectors.map(
227+
(s: string) => new RegExp(s)
228+
),
236229
});
237230
}
238231
)

0 commit comments

Comments
 (0)