Skip to content

Commit 287954e

Browse files
authored
Merge pull request #4686 from erik-krogh/buildFp
Approved by esbena
2 parents 406cc64 + d377a02 commit 287954e

File tree

4 files changed

+74
-2
lines changed

4 files changed

+74
-2
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
lgtm,codescanning
2+
* The `js/build-artifact-leak` query no longer reports when only a safe subset of the properties on `process.env` are included in a build-artifact.

javascript/ql/src/semmle/javascript/security/dataflow/BuildArtifactLeakCustomizations.qll

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
*/
55

66
import javascript
7-
private import semmle.javascript.dataflow.InferredTypes
8-
private import semmle.javascript.security.SensitiveActions::HeuristicNames
97

108
/**
119
* Sinks for storage of sensitive information in build artifact.

javascript/ql/src/semmle/javascript/security/dataflow/CleartextLoggingCustomizations.qll

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ module CleartextLogging {
204204
|
205205
not exists(write.getPropertyName()) and
206206
not exists(read.getPropertyName()) and
207+
not isFilteredPropertyName(read.getPropertyNameExpr().flow().getALocalSource()) and
207208
src = read.getBase() and
208209
trg = write.getBase().getALocalSource()
209210
)
@@ -216,4 +217,24 @@ module CleartextLogging {
216217
trg.asExpr() = f.getArgumentsVariable().getAnAccess()
217218
)
218219
}
220+
221+
/**
222+
* Holds if `name` is filtered by e.g. a regular-expression test or a filter call.
223+
*/
224+
private predicate isFilteredPropertyName(DataFlow::Node name) {
225+
exists(DataFlow::MethodCallNode reduceCall |
226+
reduceCall.getABoundCallbackParameter(0, 1).flowsTo(name) and
227+
reduceCall.getMethodName() = "reduce"
228+
|
229+
reduceCall.getReceiver+().(DataFlow::MethodCallNode).getMethodName() = "filter"
230+
)
231+
or
232+
exists(StringOps::RegExpTest test |
233+
test.getStringOperand().getALocalSource() = name.getALocalSource()
234+
)
235+
or
236+
exists(MembershipCandidate test |
237+
test.getAMemberNode().getALocalSource() = name.getALocalSource()
238+
)
239+
}
219240
}

javascript/ql/test/query-tests/Security/CWE-312/build-leaks.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,54 @@ var server = https.createServer(function (req, res) {
4040
let pw = url.parse(req.url, true).query.current_password;
4141
var plugin = new webpack.DefinePlugin({ "process.env.secret": JSON.stringify(pw) }); // NOT OK
4242
});
43+
44+
(function () {
45+
const REACT_APP = /^REACT_APP_/i;
46+
47+
function getOnlyReactVariables() {
48+
const raw = Object.keys(process.env)
49+
.filter(key => REACT_APP.test(key)) // This filters makes it safe.
50+
.reduce(
51+
(env, key) => {
52+
env[key] = process.env[key];
53+
return env;
54+
},
55+
{}
56+
);
57+
return raw;
58+
}
59+
60+
new webpack.DefinePlugin(getOnlyReactVariables()); // OK
61+
62+
function getOnlyReactVariables2() {
63+
const raw = Object.keys(process.env)
64+
.reduce(
65+
(env, key) => {
66+
if (REACT_APP.test(key)) {
67+
env[key] = process.env[key];
68+
}
69+
return env;
70+
},
71+
{}
72+
);
73+
return raw;
74+
}
75+
76+
new webpack.DefinePlugin(getOnlyReactVariables2()); // OK
77+
78+
function getOnlyReactVariables3() {
79+
const raw = Object.keys(process.env)
80+
.reduce(
81+
(env, key) => {
82+
if (key == ["1", "2", "3"]) {
83+
env[key] = process.env[key];
84+
}
85+
return env;
86+
},
87+
{}
88+
);
89+
return raw;
90+
}
91+
92+
new webpack.DefinePlugin(getOnlyReactVariables3()); // OK
93+
})();

0 commit comments

Comments
 (0)