@@ -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,17 @@ 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 ( ) ) and
49+ not isPrivateMethodDeclaration ( result )
4550 )
4651 or
4752 result = getAValueExportedByPackage ( ) .getALocalSource ( )
4853 or
4954 // Nested property reads.
50- result = getAValueExportedByPackage ( ) .( DataFlow:: SourceNode ) .getAPropertyReference ( )
55+ result =
56+ getAValueExportedByPackage ( ) .( DataFlow:: SourceNode ) .getAPropertyReference ( publicPropertyName ( ) )
5157 or
5258 // module.exports.foo = require("./other-module.js");
5359 exists ( Module mod |
@@ -61,9 +67,12 @@ private DataFlow::Node getAValueExportedByPackage() {
6167 // static baz() {} // <- result
6268 // constructor() {} // <- result
6369 // };
64- exists ( DataFlow:: ClassNode cla | cla = getAValueExportedByPackage ( ) |
65- result = cla .getAnInstanceMethod ( ) or
66- result = cla .getAStaticMethod ( ) or
70+ exists ( DataFlow:: ClassNode cla |
71+ cla = getAValueExportedByPackage ( ) and
72+ not isPrivateMethodDeclaration ( result )
73+ |
74+ result = cla .getInstanceMethod ( publicPropertyName ( ) ) or
75+ result = cla .getStaticMethod ( publicPropertyName ( ) ) or
6776 result = cla .getConstructor ( )
6877 )
6978 or
@@ -120,7 +129,8 @@ private DataFlow::Node getAValueExportedByPackage() {
120129 or
121130 // Object.defineProperty
122131 exists ( CallToObjectDefineProperty call |
123- [ call , call .getBaseObject ( ) ] = getAValueExportedByPackage ( )
132+ [ call , call .getBaseObject ( ) ] = getAValueExportedByPackage ( ) and
133+ call .getPropertyName ( ) = publicPropertyName ( )
124134 |
125135 result = call .getPropertyDescriptor ( ) .getALocalSource ( ) .getAPropertyReference ( "value" )
126136 or
@@ -164,9 +174,31 @@ private DataFlow::Node getAValueExportedByPackage() {
164174 * Gets an exported node from the module `mod`.
165175 */
166176private DataFlow:: Node getAnExportFromModule ( Module mod ) {
167- result = mod .getAnExportedValue ( _ )
177+ result = mod .getAnExportedValue ( publicPropertyName ( ) )
168178 or
169179 result = mod .getABulkExportedNode ( )
170180 or
171181 result .analyze ( ) .getAValue ( ) = TAbstractModuleObject ( mod )
172182}
183+
184+ /**
185+ * Gets a property name that we consider to be public.
186+ *
187+ * This only allows properties whose first character is a letter or number.
188+ */
189+ bindingset [ result ]
190+ private string publicPropertyName ( ) { result .regexpMatch ( "[a-zA-Z0-9].*" ) }
191+
192+ /**
193+ * Holds if the given function is part of a private (or protected) method declaration.
194+ */
195+ private predicate isPrivateMethodDeclaration ( DataFlow:: FunctionNode func ) {
196+ exists ( MethodDeclaration decl |
197+ decl .getBody ( ) = func .getFunction ( ) and
198+ (
199+ decl .isPrivate ( )
200+ or
201+ decl .isProtected ( )
202+ )
203+ )
204+ }
0 commit comments