Skip to content

Commit af1b04d

Browse files
committed
JS: Restrict what property names that are considered public exports
1 parent 4a16be2 commit af1b04d

File tree

1 file changed

+23
-8
lines changed

1 file changed

+23
-8
lines changed

javascript/ql/lib/semmle/javascript/PackageExports.qll

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,11 @@ private DataFlow::Node getAValueExportedByPackage() {
3030
getAnExportFromModule(any(PackageJSON pack | exists(pack.getPackageName())).getMainModule())
3131
or
3232
// module.exports.bar.baz = result;
33-
result = getAValueExportedByPackage().(DataFlow::PropWrite).getRhs()
33+
exists(DataFlow::PropWrite write |
34+
write = getAValueExportedByPackage() and
35+
write.getPropertyName() = publicPropertyName() and
36+
result = write.getRhs()
37+
)
3438
or
3539
// class Foo {
3640
// bar() {} // <- result
@@ -39,15 +43,15 @@ private DataFlow::Node getAValueExportedByPackage() {
3943
exists(DataFlow::SourceNode callee |
4044
callee = getAValueExportedByPackage().(DataFlow::NewNode).getCalleeNode().getALocalSource()
4145
|
42-
result = callee.getAPropertyRead("prototype").getAPropertyWrite().getRhs()
46+
result = callee.getAPropertyRead("prototype").getAPropertyWrite(publicPropertyName()).getRhs()
4347
or
44-
result = callee.(DataFlow::ClassNode).getAnInstanceMethod()
48+
result = callee.(DataFlow::ClassNode).getInstanceMethod(publicPropertyName())
4549
)
4650
or
4751
result = getAValueExportedByPackage().getALocalSource()
4852
or
4953
// Nested property reads.
50-
result = getAValueExportedByPackage().(DataFlow::SourceNode).getAPropertyReference()
54+
result = getAValueExportedByPackage().(DataFlow::SourceNode).getAPropertyReference(publicPropertyName())
5155
or
5256
// module.exports.foo = require("./other-module.js");
5357
exists(Module mod |
@@ -62,8 +66,8 @@ private DataFlow::Node getAValueExportedByPackage() {
6266
// constructor() {} // <- result
6367
// };
6468
exists(DataFlow::ClassNode cla | cla = getAValueExportedByPackage() |
65-
result = cla.getAnInstanceMethod() or
66-
result = cla.getAStaticMethod() or
69+
result = cla.getInstanceMethod(publicPropertyName()) or
70+
result = cla.getStaticMethod(publicPropertyName()) or
6771
result = cla.getConstructor()
6872
)
6973
or
@@ -120,7 +124,8 @@ private DataFlow::Node getAValueExportedByPackage() {
120124
or
121125
// Object.defineProperty
122126
exists(CallToObjectDefineProperty call |
123-
[call, call.getBaseObject()] = getAValueExportedByPackage()
127+
[call, call.getBaseObject()] = getAValueExportedByPackage() and
128+
call.getPropertyName() = publicPropertyName()
124129
|
125130
result = call.getPropertyDescriptor().getALocalSource().getAPropertyReference("value")
126131
or
@@ -164,9 +169,19 @@ private DataFlow::Node getAValueExportedByPackage() {
164169
* Gets an exported node from the module `mod`.
165170
*/
166171
private DataFlow::Node getAnExportFromModule(Module mod) {
167-
result = mod.getAnExportedValue(_)
172+
result = mod.getAnExportedValue(publicPropertyName())
168173
or
169174
result = mod.getABulkExportedNode()
170175
or
171176
result.analyze().getAValue() = TAbstractModuleObject(mod)
172177
}
178+
179+
/**
180+
* Gets a property name that we consider to be public.
181+
*
182+
* This only allows properties whose first character is a letter or number.
183+
*/
184+
bindingset[result]
185+
private string publicPropertyName() {
186+
result.regexpMatch("[a-zA-Z0-9].*")
187+
}

0 commit comments

Comments
 (0)