Skip to content

Commit 17348fb

Browse files
Add android certificate pinning query
1 parent 357e460 commit 17348fb

File tree

2 files changed

+73
-0
lines changed

2 files changed

+73
-0
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import java
2+
import semmle.code.xml.AndroidManifest
3+
import semmle.code.java.dataflow.TaintTracking
4+
import HttpsUrls
5+
6+
class AndroidNetworkSecurityConfigFile extends XmlFile {
7+
AndroidNetworkSecurityConfigFile() {
8+
exists(AndroidApplicationXmlElement app, AndroidXmlAttribute confAttr, string confName |
9+
confAttr.getElement() = app and
10+
confAttr.getValue() = "@xml/" + confName and
11+
this.getRelativePath() = "res/xml/" + confName + ".xml" and
12+
this.getARootElement().getName() = "network-security-config"
13+
)
14+
}
15+
}
16+
17+
predicate isAndroid() { exists(AndroidManifestXmlFile m) }
18+
19+
predicate trustedDomain(string domainName) {
20+
exists(
21+
AndroidNetworkSecurityConfigFile confFile, XmlElement domConf, XmlElement domain,
22+
XmlElement trust
23+
|
24+
domConf.getFile() = confFile and
25+
domConf.getName() = "domain-config" and
26+
domain.getParent() = domConf and
27+
domain.getName() = "domain" and
28+
domain.getACharactersSet().getCharacters() = domainName and
29+
trust.getParent() = domConf and
30+
trust.getName() = ["trust-anchors", "pin-set"]
31+
)
32+
}
33+
34+
private class UntrustedUrlConfig extends TaintTracking::Configuration {
35+
UntrustedUrlConfig() { this = "UntrustedUrlConfig" }
36+
37+
override predicate isSource(DataFlow::Node node) {
38+
exists(string d | trustedDomain(d)) and
39+
exists(string lit | lit = node.asExpr().(CompileTimeConstantExpr).getStringValue() |
40+
lit.matches("%://%") and // it's a URL
41+
not exists(string dom | trustedDomain(dom) and lit.matches("%" + dom + "%"))
42+
)
43+
}
44+
45+
override predicate isSink(DataFlow::Node node) { node instanceof UrlOpenSink }
46+
}
47+
48+
predicate missingPinning(DataFlow::Node node) {
49+
isAndroid() and
50+
node instanceof UrlOpenSink and
51+
(
52+
not exists(string s | trustedDomain(s))
53+
or
54+
exists(UntrustedUrlConfig conf | conf.hasFlow(_, node))
55+
)
56+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/**
2+
* @name Android Missing Certificate Pinning
3+
* @description Network communication should use certificate pinning.
4+
* @kind problem
5+
* @problem.severity warning
6+
* @precision medium
7+
* @id java/android/missingcertificate-pinning
8+
* @tags security
9+
* external/cwe/cwe-295
10+
*/
11+
12+
import java
13+
import semmle.code.java.security.AndroidCertificatePinningQuery
14+
15+
from DataFlow::Node node
16+
where missingPinning(node)
17+
select node, "This network call does not implement certificate pinning."

0 commit comments

Comments
 (0)