Skip to content

Commit a91cc9b

Browse files
committed
Convert the query to path-problem
1 parent 7f911f0 commit a91cc9b

File tree

2 files changed

+41
-93
lines changed

2 files changed

+41
-93
lines changed

java/ql/src/experimental/Security/CWE/CWE-522/InsecureBasicAuth.qhelp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<qhelp>
33

44
<overview>
5-
<p>Basic authentication only obfuscates username/password in Base64 encoding, which can be easily recognized and reversed, thus it cannot be transmitted over the cleartext HTTP channel. Transmission of sensitive information not in HTTPS is vulnerable to packet sniffing.</p>
5+
<p>Basic authentication only obfuscates username/password in Base64 encoding, which can be easily recognized and reversed, thus it must not be transmitted over the cleartext HTTP channel. Transmission of sensitive information not in HTTPS is vulnerable to packet sniffing.</p>
66
</overview>
77

88
<recommendation>

java/ql/src/experimental/Security/CWE/CWE-522/InsecureBasicAuth.ql

Lines changed: 40 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
22
* @name Insecure basic authentication
33
* @description Basic authentication only obfuscates username/password in Base64 encoding, which can be easily recognized and reversed. Transmission of sensitive information not over HTTPS is vulnerable to packet sniffing.
4-
* @kind problem
4+
* @kind path-problem
55
* @id java/insecure-basic-auth
66
* @tags security
77
* external/cwe-522
@@ -19,8 +19,10 @@ import DataFlow::PathGraph
1919
*/
2020
class ApacheHttpRequest extends RefType {
2121
ApacheHttpRequest() {
22-
hasQualifiedName("org.apache.http.client.methods", "HttpRequestBase") or
23-
hasQualifiedName("org.apache.http.message", "BasicHttpRequest")
22+
this
23+
.getASourceSupertype*()
24+
.hasQualifiedName("org.apache.http.client.methods", "HttpRequestBase") or
25+
this.getASourceSupertype*().hasQualifiedName("org.apache.http.message", "BasicHttpRequest")
2426
}
2527
}
2628

@@ -42,7 +44,9 @@ class URLConstructor extends ClassInstanceExpr {
4244
* The type `java.net.URLConnection`.
4345
*/
4446
class TypeHttpUrlConnection extends RefType {
45-
TypeHttpUrlConnection() { hasQualifiedName("java.net", "HttpURLConnection") }
47+
TypeHttpUrlConnection() {
48+
this.getASourceSupertype*().hasQualifiedName("java.net", "HttpURLConnection")
49+
}
4650
}
4751

4852
/**
@@ -118,25 +122,6 @@ predicate builtFromBasicAuthStringConcat(Expr expr) {
118122
)
119123
}
120124

121-
/**
122-
* The methods `addHeader()` and `setHeader` declared in ApacheHttpRequest invoked for basic authentication.
123-
*/
124-
class AddBasicAuthHeaderMethodAccess extends MethodAccess {
125-
AddBasicAuthHeaderMethodAccess() {
126-
this.getMethod().getDeclaringType() instanceof ApacheHttpRequest and
127-
(this.getMethod().hasName("addHeader") or this.getMethod().hasName("setHeader")) and
128-
this.getArgument(0).(CompileTimeConstantExpr).getStringValue() = "Authorization" and
129-
builtFromBasicAuthStringConcat(this.getArgument(1)) and
130-
exists(VarAccess request, VariableAssign va, ConstructorCall cc, Expr arg0 |
131-
this.getQualifier() = request and // Constructor call like HttpPost post = new HttpPost("http://www.example.com/rest/endpoint.do"); and BasicHttpRequest post = new BasicHttpRequest("POST", uriStr);
132-
va.getDestVar() = request.getVariable() and
133-
va.getSource() = cc and
134-
cc.getAnArgument() = arg0 and
135-
builtFromHttpStringConcat(arg0)
136-
)
137-
}
138-
}
139-
140125
/** The `openConnection` method of Java URL. Not to include `openStream` since it won't be used in this query. */
141126
class HttpURLOpenMethod extends Method {
142127
HttpURLOpenMethod() {
@@ -145,84 +130,47 @@ class HttpURLOpenMethod extends Method {
145130
}
146131
}
147132

148-
/**
149-
* Tracks the flow of data from parameter of URL constructor to the url instance.
150-
*/
151-
class URLConstructorTaintStep extends TaintTracking::AdditionalTaintStep {
152-
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
153-
exists(URLConstructor u |
154-
node1.asExpr() = u.stringArg() and
155-
node2.asExpr() = u
156-
)
157-
}
158-
}
133+
class BasicAuthFlowConfig extends TaintTracking::Configuration {
134+
BasicAuthFlowConfig() { this = "InsecureBasicAuth::BasicAuthFlowConfig" }
159135

160-
/**
161-
* Tracks the flow of data from `openConnection` method to the connection object.
162-
*/
163-
class OpenHttpURLTaintStep extends TaintTracking::AdditionalTaintStep {
164-
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
165-
exists(MethodAccess ma, VariableAssign va |
136+
override predicate isSource(DataFlow::Node src) {
137+
exists(ConstructorCall cc |
138+
(
139+
cc.getConstructedType() instanceof ApacheHttpRequest and
140+
cc = src.asExpr() and
141+
builtFromHttpStringConcat(cc.getAnArgument())
142+
)
143+
)
144+
or
145+
exists(MethodAccess ma |
166146
ma.getMethod() instanceof HttpURLOpenMethod and
167-
ma.getQualifier() = node1.asExpr() and
147+
ma = src.asExpr() and
168148
(
169-
ma = va.getSource()
170-
or
171-
exists(CastExpr ce |
172-
ce.getExpr() = ma and
173-
ce = va.getSource() and
174-
ce.getControlFlowNode().getASuccessor() = va //With a type cast like HttpURLConnection conn = (HttpURLConnection) url.openConnection();
149+
builtFromHttpStringConcat(ma.getQualifier().(URLConstructor).stringArg()) or
150+
exists(URLConstructor uc, VarAccess va |
151+
uc = va.getVariable().getAnAssignedValue() and
152+
ma.getQualifier() = va and
153+
builtFromHttpStringConcat(uc.stringArg())
175154
)
176-
) and
177-
node2.asExpr() = va.getDestVar().getAnAccess()
155+
)
178156
)
179157
}
180-
}
181-
182-
class HttpStringToHttpURLOpenMethodFlowConfig extends TaintTracking::Configuration {
183-
HttpStringToHttpURLOpenMethodFlowConfig() {
184-
this = "InsecureBasicAuth::HttpStringToHttpURLOpenMethodFlowConfig"
185-
}
186-
187-
override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof HttpString }
188158

189159
override predicate isSink(DataFlow::Node sink) {
190-
sink.asExpr().(VarAccess).getVariable().getType() instanceof TypeUrlConnection or
191-
sink.asExpr().(VarAccess).getVariable().getType() instanceof TypeHttpUrlConnection // TypeHttpUrlConnection isn't instance of TypeUrlConnection
192-
}
193-
194-
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
195-
exists(DataFlow::Node nodem |
196-
any(URLConstructorTaintStep uts).step(node1, nodem) and
197-
any(OpenHttpURLTaintStep ots).step(nodem, node2)
198-
)
199-
}
200-
201-
override predicate isSanitizer(DataFlow::Node node) {
202-
node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType
203-
}
204-
}
205-
206-
/**
207-
* The method `setRequestProperty()` declared in URL Connection invoked for basic authentication.
208-
*/
209-
class SetBasicAuthPropertyMethodAccess extends MethodAccess {
210-
SetBasicAuthPropertyMethodAccess() {
211-
this.getMethod().getDeclaringType() instanceof TypeUrlConnection and
212-
this.getMethod().hasName("setRequestProperty") and
213-
this.getArgument(0).(CompileTimeConstantExpr).getStringValue() = "Authorization" and
214-
builtFromBasicAuthStringConcat(this.getArgument(1)) and
215-
exists(VarAccess conn, DataFlow::PathNode source, DataFlow::PathNode sink, HttpString s |
216-
this.getQualifier() = conn and //HttpURLConnection conn = (HttpURLConnection) url.openConnection();
217-
source.getNode().asExpr() = s and
218-
sink.getNode().asExpr() = conn.getVariable().getAnAccess() and
219-
any(HttpStringToHttpURLOpenMethodFlowConfig c).hasFlowPath(source, sink)
160+
exists(MethodAccess ma |
161+
sink.asExpr() = ma.getQualifier() and
162+
(
163+
ma.getMethod().hasName("addHeader") or
164+
ma.getMethod().hasName("setHeader") or
165+
ma.getMethod().hasName("setRequestProperty")
166+
) and
167+
ma.getArgument(0).(CompileTimeConstantExpr).getStringValue() = "Authorization" and
168+
builtFromBasicAuthStringConcat(ma.getArgument(1))
220169
)
221170
}
222171
}
223172

224-
from MethodAccess ma
225-
where
226-
ma instanceof AddBasicAuthHeaderMethodAccess or
227-
ma instanceof SetBasicAuthPropertyMethodAccess
228-
select ma, "Insecure basic authentication"
173+
from DataFlow::PathNode source, DataFlow::PathNode sink, BasicAuthFlowConfig config
174+
where config.hasFlowPath(source, sink)
175+
select sink.getNode(), source, sink, "Insecure basic authentication from $@.", source.getNode(),
176+
"this user input"

0 commit comments

Comments
 (0)