|
1 | 1 | /** |
2 | | - * Provides a dataflow tracking configuration for reasoning about clear-text logging of sensitive information. |
| 2 | + * Provides a dataflow tracking configuration for reasoning about |
| 3 | + * clear-text logging of sensitive information. |
| 4 | + * |
| 5 | + * Note, for performance reasons: only import this file if |
| 6 | + * `CleartextLogging::Configuration` is needed, otherwise |
| 7 | + * `CleartextLoggingCustomizations` should be imported instead. |
3 | 8 | */ |
4 | 9 |
|
5 | 10 | import javascript |
6 | | -private import semmle.javascript.dataflow.InferredTypes |
7 | | -private import semmle.javascript.security.SensitiveActions::HeuristicNames |
8 | 11 |
|
9 | 12 | module CleartextLogging { |
10 | | - /** |
11 | | - * A data flow source for clear-text logging of sensitive information. |
12 | | - */ |
13 | | - abstract class Source extends DataFlow::Node { |
14 | | - /** Gets a string that describes the type of this data flow source. */ |
15 | | - abstract string describe(); |
16 | | - } |
17 | | - |
18 | | - /** |
19 | | - * A data flow sink for clear-text logging of sensitive information. |
20 | | - */ |
21 | | - abstract class Sink extends DataFlow::Node { } |
22 | | - |
23 | | - /** |
24 | | - * A barrier for clear-text logging of sensitive information. |
25 | | - */ |
26 | | - abstract class Barrier extends DataFlow::Node { } |
| 13 | + import CleartextLoggingCustomizations::CleartextLogging |
27 | 14 |
|
28 | 15 | /** |
29 | 16 | * A dataflow tracking configuration for clear-text logging of sensitive information. |
@@ -57,122 +44,4 @@ module CleartextLogging { |
57 | 44 | ) |
58 | 45 | } |
59 | 46 | } |
60 | | - |
61 | | - /** |
62 | | - * An argument to a logging mechanism. |
63 | | - */ |
64 | | - class LoggerSink extends Sink { |
65 | | - LoggerSink() { this = any(LoggerCall log).getAMessageComponent() } |
66 | | - } |
67 | | - |
68 | | - /** |
69 | | - * A data flow node that does not contain a clear-text password, according to its syntactic name. |
70 | | - */ |
71 | | - private class NameGuidedNonCleartextPassword extends NonCleartextPassword { |
72 | | - NameGuidedNonCleartextPassword() { |
73 | | - exists(string name | name.regexpMatch(notSensitive()) | |
74 | | - this.asExpr().(VarAccess).getName() = name |
75 | | - or |
76 | | - this.(DataFlow::PropRead).getPropertyName() = name |
77 | | - or |
78 | | - this.(DataFlow::InvokeNode).getCalleeName() = name |
79 | | - ) |
80 | | - or |
81 | | - // avoid i18n strings |
82 | | - this |
83 | | - .(DataFlow::PropRead) |
84 | | - .getBase() |
85 | | - .asExpr() |
86 | | - .(VarRef) |
87 | | - .getName() |
88 | | - .regexpMatch("(?is).*(messages|strings).*") |
89 | | - } |
90 | | - } |
91 | | - |
92 | | - /** |
93 | | - * A data flow node that is definitely not an object. |
94 | | - */ |
95 | | - private class NonObject extends NonCleartextPassword { |
96 | | - NonObject() { |
97 | | - forall(AbstractValue v | v = analyze().getAValue() | not v.getType() = TTObject()) |
98 | | - } |
99 | | - } |
100 | | - |
101 | | - /** |
102 | | - * A data flow node that receives flow that is not a clear-text password. |
103 | | - */ |
104 | | - private class NonCleartextPasswordFlow extends NonCleartextPassword { |
105 | | - NonCleartextPasswordFlow() { |
106 | | - any(NonCleartextPassword other).(DataFlow::SourceNode).flowsTo(this) |
107 | | - } |
108 | | - } |
109 | | - |
110 | | - /** |
111 | | - * A call that might obfuscate a password, for example through hashing. |
112 | | - */ |
113 | | - private class ObfuscatorCall extends Barrier, DataFlow::InvokeNode { |
114 | | - ObfuscatorCall() { getCalleeName().regexpMatch(notSensitive()) } |
115 | | - } |
116 | | - |
117 | | - /** |
118 | | - * A data flow node that does not contain a clear-text password. |
119 | | - */ |
120 | | - abstract private class NonCleartextPassword extends DataFlow::Node { } |
121 | | - |
122 | | - /** |
123 | | - * An object with a property that may contain password information |
124 | | - * |
125 | | - * This is a source since `console.log(obj)` will show the properties of `obj`. |
126 | | - */ |
127 | | - private class ObjectPasswordPropertySource extends DataFlow::ValueNode, Source { |
128 | | - string name; |
129 | | - |
130 | | - ObjectPasswordPropertySource() { |
131 | | - exists(DataFlow::PropWrite write | |
132 | | - name.regexpMatch(maybePassword()) and |
133 | | - not name.regexpMatch(notSensitive()) and |
134 | | - write = this.(DataFlow::SourceNode).getAPropertyWrite(name) and |
135 | | - // avoid safe values assigned to presumably unsafe names |
136 | | - not write.getRhs() instanceof NonCleartextPassword |
137 | | - ) |
138 | | - } |
139 | | - |
140 | | - override string describe() { result = "an access to " + name } |
141 | | - } |
142 | | - |
143 | | - /** An access to a variable or property that might contain a password. */ |
144 | | - private class ReadPasswordSource extends DataFlow::ValueNode, Source { |
145 | | - string name; |
146 | | - |
147 | | - ReadPasswordSource() { |
148 | | - // avoid safe values assigned to presumably unsafe names |
149 | | - not this instanceof NonCleartextPassword and |
150 | | - name.regexpMatch(maybePassword()) and |
151 | | - ( |
152 | | - this.asExpr().(VarAccess).getName() = name |
153 | | - or |
154 | | - exists(DataFlow::SourceNode base | |
155 | | - this = base.getAPropertyRead(name) and |
156 | | - // avoid safe values assigned to presumably unsafe names |
157 | | - exists(DataFlow::SourceNode baseObj | baseObj.flowsTo(base) | |
158 | | - not base.getAPropertyWrite(name).getRhs() instanceof NonCleartextPassword |
159 | | - ) |
160 | | - ) |
161 | | - ) |
162 | | - } |
163 | | - |
164 | | - override string describe() { result = "an access to " + name } |
165 | | - } |
166 | | - |
167 | | - /** A call that might return a password. */ |
168 | | - private class CallPasswordSource extends DataFlow::ValueNode, DataFlow::InvokeNode, Source { |
169 | | - string name; |
170 | | - |
171 | | - CallPasswordSource() { |
172 | | - name = getCalleeName() and |
173 | | - name.regexpMatch("(?is)getPassword") |
174 | | - } |
175 | | - |
176 | | - override string describe() { result = "a call to " + name } |
177 | | - } |
178 | 47 | } |
0 commit comments