Skip to content

Commit 644232a

Browse files
clemgbldtony-go
andauthored
refactor(probe/isSerializeEnv): trace re-assignment of JSON.stringy & process.env (#369)
* refactor(probe/isSerializeEnv): trace re-assignment of JSON.stringy & process.env * Update workspaces/js-x-ray/test/probes/isSerializeEnv.spec.ts Co-authored-by: Tony Gorez <gorez.tony@gmail.com> --------- Co-authored-by: Tony Gorez <gorez.tony@gmail.com>
1 parent 5f9dc0e commit 644232a

File tree

3 files changed

+71
-2
lines changed

3 files changed

+71
-2
lines changed

.changeset/clean-mails-search.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@nodesecure/js-x-ray": minor
3+
---
4+
5+
refactor(probe/isSerializeEnv): trace re-assignment of JSON.stringy & process.env

workspaces/js-x-ray/src/probes/isSerializeEnv.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,17 @@ import { ProbeSignals } from "../ProbeRunner.js";
1919
* JSON.stringify(process[`env`])
2020
*/
2121
function validateNode(
22-
node: ESTree.Node
22+
node: ESTree.Node,
23+
{ tracer }: SourceFile
2324
): [boolean, any?] {
2425
const id = getCallExpressionIdentifier(node);
25-
if (id !== "JSON.stringify") {
26+
27+
if (id === null) {
28+
return [false];
29+
}
30+
const data = tracer.getDataFromIdentifier(id);
31+
32+
if (data === null || data.identifierOrMemberExpr !== "JSON.stringify") {
2633
return [false];
2734
}
2835

@@ -39,6 +46,13 @@ function validateNode(
3946
}
4047
}
4148

49+
if (firstArg.type === "Identifier") {
50+
const data = tracer.getDataFromIdentifier("process.env");
51+
if (data !== null && data.assignmentMemory.includes(firstArg.name)) {
52+
return [true];
53+
}
54+
}
55+
4256
return [false];
4357
}
4458

@@ -57,9 +71,18 @@ function main(
5771
return ProbeSignals.Skip;
5872
}
5973

74+
function initialize(sourceFile: SourceFile) {
75+
sourceFile.tracer.trace("process.env", {
76+
followConsecutiveAssignment: true
77+
}).trace("JSON.stringify", {
78+
followConsecutiveAssignment: true
79+
});
80+
}
81+
6082
export default {
6183
name: "isSerializeEnv",
6284
validateNode,
85+
initialize,
6386
main,
6487
breakOnMatch: false
6588
};

workspaces/js-x-ray/test/probes/isSerializeEnv.spec.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,47 @@ test("should detect JSON.stringify(process[\"env\"])", () => {
3939
assert.strictEqual(warning.value, "JSON.stringify(process.env)");
4040
});
4141

42+
test("should detect process.env reassignment", () => {
43+
const str = `
44+
const env = process.env;
45+
JSON.stringify(env);
46+
`;
47+
const ast = parseScript(str);
48+
const sastAnalysis = getSastAnalysis(str, isSerializeEnv).execute(ast.body);
49+
50+
assert.strictEqual(sastAnalysis.warnings().length, 1);
51+
const warning = sastAnalysis.getWarning("serialize-environment");
52+
assert.strictEqual(warning.kind, "serialize-environment");
53+
assert.strictEqual(warning.value, "JSON.stringify(process.env)");
54+
});
55+
56+
test("should not detect process.env", () => {
57+
const str = `
58+
const env = {};
59+
const env2 = process.env;
60+
JSON.stringify(env);
61+
`;
62+
const ast = parseScript(str);
63+
const sastAnalysis = getSastAnalysis(str, isSerializeEnv).execute(ast.body);
64+
65+
assert.strictEqual(sastAnalysis.warnings().length, 0);
66+
});
67+
68+
test("should be able to detect reassigned JSON.stringify", () => {
69+
const str = `
70+
const stringify = JSON.stringify;
71+
const env = process.env;
72+
stringify(env);
73+
`;
74+
const ast = parseScript(str);
75+
const sastAnalysis = getSastAnalysis(str, isSerializeEnv).execute(ast.body);
76+
77+
assert.strictEqual(sastAnalysis.warnings().length, 1);
78+
const warning = sastAnalysis.getWarning("serialize-environment");
79+
assert.strictEqual(warning.kind, "serialize-environment");
80+
assert.strictEqual(warning.value, "JSON.stringify(process.env)");
81+
});
82+
4283
test("should not detect other JSON.stringify calls", () => {
4384
const str = "JSON.stringify({ foo: 'bar' })";
4485
const ast = parseScript(str);

0 commit comments

Comments
 (0)