1010 */
1111
1212import javascript
13-
14- /**
15- * Provides heuristics for identifying names related to sensitive information.
16- *
17- * INTERNAL: Do not use directly.
18- */
19- module HeuristicNames {
20- /**
21- * Gets a regular expression that identifies strings that may indicate the presence of secret
22- * or trusted data.
23- */
24- string maybeSecret ( ) { result = "(?is).*((?<!is)secret|(?<!un|is)trusted).*" }
25-
26- /**
27- * Gets a regular expression that identifies strings that may indicate the presence of
28- * user names or other account information.
29- */
30- string maybeAccountInfo ( ) {
31- result = "(?is).*acc(ou)?nt.*" or
32- result = "(?is).*(puid|username|userid).*"
33- }
34-
35- /**
36- * Gets a regular expression that identifies strings that may indicate the presence of
37- * a password or an authorization key.
38- */
39- string maybePassword ( ) {
40- result = "(?is).*pass(wd|word|code|phrase)(?!.*question).*" or
41- result = "(?is).*(auth(entication|ori[sz]ation)?)key.*"
42- }
43-
44- /**
45- * Gets a regular expression that identifies strings that may indicate the presence of
46- * a certificate.
47- */
48- string maybeCertificate ( ) { result = "(?is).*(cert)(?!.*(format|name)).*" }
49-
50- /**
51- * Gets a regular expression that identifies strings that may indicate the presence
52- * of sensitive data, with `classification` describing the kind of sensitive data involved.
53- */
54- string maybeSensitive ( SensitiveExpr:: Classification classification ) {
55- result = maybeSecret ( ) and classification = SensitiveExpr:: secret ( )
56- or
57- result = maybeAccountInfo ( ) and classification = SensitiveExpr:: id ( )
58- or
59- result = maybePassword ( ) and classification = SensitiveExpr:: password ( )
60- or
61- result = maybeCertificate ( ) and classification = SensitiveExpr:: certificate ( )
62- }
63-
64- /**
65- * Gets a regular expression that identifies strings that may indicate the presence of data
66- * that is hashed or encrypted, and hence rendered non-sensitive, or contains special characters
67- * suggesting nouns within the string do not represent the meaning of the whole string (e.g. a URL or a SQL query).
68- */
69- string notSensitive ( ) {
70- result = "(?is).*([^\\w$.-]|redact|censor|obfuscate|hash|md5|sha|((?<!un)(en))?(crypt|code)).*"
71- }
72- }
73-
13+ import semmle.javascript.security.internal.SensitiveDataHeuristics
7414private import HeuristicNames
7515
7616/** An expression that might contain sensitive data. */
@@ -79,56 +19,44 @@ abstract class SensitiveExpr extends Expr {
7919 abstract string describe ( ) ;
8020
8121 /** Gets a classification of the kind of sensitive data this expression might contain. */
82- abstract SensitiveExpr :: Classification getClassification ( ) ;
22+ abstract SensitiveDataClassification getClassification ( ) ;
8323}
8424
85- module SensitiveExpr {
86- /**
87- * A classification of different kinds of sensitive data:
88- *
89- * - secret: generic secret or trusted data;
90- * - id: a user name or other account information;
91- * - password: a password or authorization key;
92- * - certificate: a certificate.
93- *
94- * While classifications are represented as strings, this should not be relied upon.
95- * Instead, use the predicates below to work with classifications.
96- */
97- class Classification extends string {
98- Classification ( ) { this = "secret" or this = "id" or this = "password" or this = "certificate" }
99- }
25+ /** DEPRECATED: Use `SensitiveDataClassification` and helpers instead. */
26+ deprecated module SensitiveExpr {
27+ /** DEPRECATED: Use `SensitiveDataClassification` instead. */
28+ deprecated class Classification = SensitiveDataClassification ;
10029
101- /** Gets the classification for secret or trusted data . */
102- Classification secret ( ) { result = " secret" }
30+ /** DEPRECATED: Use `SensitiveDataClassification:: secret` instead . */
31+ deprecated predicate secret = SensitiveDataClassification :: secret / 0 ;
10332
104- /** Gets the classification for user names or other account information . */
105- Classification id ( ) { result = "id" }
33+ /** DEPRECATED: Use `SensitiveDataClassification::id` instead . */
34+ deprecated predicate id = SensitiveDataClassification :: id / 0 ;
10635
107- /** Gets the classification for passwords or authorization keys . */
108- Classification password ( ) { result = " password" }
36+ /** DEPRECATED: Use `SensitiveDataClassification::password` instead . */
37+ deprecated predicate password = SensitiveDataClassification :: password / 0 ;
10938
110- /** Gets the classification for certificates . */
111- Classification certificate ( ) { result = " certificate" }
39+ /** DEPRECATED: Use `SensitiveDataClassification::certificate` instead . */
40+ deprecated predicate certificate = SensitiveDataClassification :: certificate / 0 ;
11241}
11342
11443/** A function call that might produce sensitive data. */
11544class SensitiveCall extends SensitiveExpr , InvokeExpr {
116- SensitiveExpr :: Classification classification ;
45+ SensitiveDataClassification classification ;
11746
11847 SensitiveCall ( ) {
11948 classification = this .getCalleeName ( ) .( SensitiveDataFunctionName ) .getClassification ( )
12049 or
12150 // This is particularly to pick up methods with an argument like "password", which
12251 // may indicate a lookup.
12352 exists ( string s | this .getAnArgument ( ) .mayHaveStringValue ( s ) |
124- s .regexpMatch ( maybeSensitive ( classification ) ) and
125- not s .regexpMatch ( notSensitive ( ) )
53+ nameIndicatesSensitiveData ( s , classification )
12654 )
12755 }
12856
12957 override string describe ( ) { result = "a call to " + getCalleeName ( ) }
13058
131- override SensitiveExpr :: Classification getClassification ( ) { result = classification }
59+ override SensitiveDataClassification getClassification ( ) { result = classification }
13260}
13361
13462/** An access to a variable or property that might contain sensitive data. */
@@ -152,13 +80,10 @@ abstract class SensitiveWrite extends DataFlow::Node { }
15280
15381/** A write to a variable or property that might contain sensitive data. */
15482private class BasicSensitiveWrite extends SensitiveWrite {
155- SensitiveExpr :: Classification classification ;
83+ SensitiveDataClassification classification ;
15684
15785 BasicSensitiveWrite ( ) {
158- exists ( string name |
159- name .regexpMatch ( maybeSensitive ( classification ) ) and
160- not name .regexpMatch ( notSensitive ( ) )
161- |
86+ exists ( string name | nameIndicatesSensitiveData ( name , classification ) |
16287 exists ( DataFlow:: PropWrite pwn |
16388 pwn .getPropertyName ( ) = name and
16489 pwn .getRhs ( ) = this
@@ -173,18 +98,16 @@ private class BasicSensitiveWrite extends SensitiveWrite {
17398 }
17499
175100 /** Gets a classification of the kind of sensitive data the write might handle. */
176- SensitiveExpr :: Classification getClassification ( ) { result = classification }
101+ SensitiveDataClassification getClassification ( ) { result = classification }
177102}
178103
179104/** An access to a variable or property that might contain sensitive data. */
180105private class BasicSensitiveVariableAccess extends SensitiveVariableAccess {
181- SensitiveExpr :: Classification classification ;
106+ SensitiveDataClassification classification ;
182107
183- BasicSensitiveVariableAccess ( ) {
184- name .regexpMatch ( maybeSensitive ( classification ) ) and not name .regexpMatch ( notSensitive ( ) )
185- }
108+ BasicSensitiveVariableAccess ( ) { nameIndicatesSensitiveData ( name , classification ) }
186109
187- override SensitiveExpr :: Classification getClassification ( ) { result = classification }
110+ override SensitiveDataClassification getClassification ( ) { result = classification }
188111}
189112
190113/** A function name that suggests it may be sensitive. */
@@ -199,16 +122,16 @@ abstract class SensitiveFunctionName extends string {
199122/** A function name that suggests it may produce sensitive data. */
200123abstract class SensitiveDataFunctionName extends SensitiveFunctionName {
201124 /** Gets a classification of the kind of sensitive data this function may produce. */
202- abstract SensitiveExpr :: Classification getClassification ( ) ;
125+ abstract SensitiveDataClassification getClassification ( ) ;
203126}
204127
205128/** A method that might return sensitive data, based on the name. */
206129class CredentialsFunctionName extends SensitiveDataFunctionName {
207- SensitiveExpr :: Classification classification ;
130+ SensitiveDataClassification classification ;
208131
209- CredentialsFunctionName ( ) { this . regexpMatch ( maybeSensitive ( classification ) ) }
132+ CredentialsFunctionName ( ) { nameIndicatesSensitiveData ( this , classification ) }
210133
211- override SensitiveExpr :: Classification getClassification ( ) { result = classification }
134+ override SensitiveDataClassification getClassification ( ) { result = classification }
212135}
213136
214137/**
@@ -240,11 +163,13 @@ class ProtectCall extends DataFlow::CallNode {
240163
241164/** An expression that might contain a clear-text password. */
242165class CleartextPasswordExpr extends SensitiveExpr {
243- CleartextPasswordExpr ( ) { this .( SensitiveExpr ) .getClassification ( ) = SensitiveExpr:: password ( ) }
166+ CleartextPasswordExpr ( ) {
167+ this .( SensitiveExpr ) .getClassification ( ) = SensitiveDataClassification:: password ( )
168+ }
244169
245170 override string describe ( ) { none ( ) }
246171
247- override SensitiveExpr :: Classification getClassification ( ) { none ( ) }
172+ override SensitiveDataClassification getClassification ( ) { none ( ) }
248173}
249174
250175/**
0 commit comments