Skip to content

Commit 9446249

Browse files
authored
Merge pull request #15012 from atorralba/atorralba/java/fix-missing-pinning-fp
Java: Fix FPs in Missing certificate pinning
2 parents 020a049 + bd8f35b commit 9446249

File tree

7 files changed

+77
-33
lines changed

7 files changed

+77
-33
lines changed

java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,9 @@ private class MissingPinningSink extends DataFlow::Node {
108108
/** Configuration for finding uses of non trusted URLs. */
109109
private module UntrustedUrlConfig implements DataFlow::ConfigSig {
110110
predicate isSource(DataFlow::Node node) {
111-
trustedDomain(_) and
112111
exists(string lit | lit = node.asExpr().(CompileTimeConstantExpr).getStringValue() |
113112
lit.matches("%://%") and // it's a URL
113+
not lit.regexpMatch("^(classpath|file|jar):.*") and // discard non-network URIs
114114
not exists(string dom | trustedDomain(dom) and lit.matches("%" + dom + "%"))
115115
)
116116
}
@@ -121,16 +121,10 @@ private module UntrustedUrlConfig implements DataFlow::ConfigSig {
121121
private module UntrustedUrlFlow = TaintTracking::Global<UntrustedUrlConfig>;
122122

123123
/** Holds if `node` is a network communication call for which certificate pinning is not implemented. */
124-
predicate missingPinning(DataFlow::Node node, string domain) {
124+
predicate missingPinning(MissingPinningSink node, string domain) {
125125
isAndroid() and
126-
node instanceof MissingPinningSink and
127-
(
128-
not trustedDomain(_) and domain = ""
129-
or
130-
exists(DataFlow::Node src |
131-
UntrustedUrlFlow::flow(src, node) and
132-
domain = getDomain(src.asExpr())
133-
)
126+
exists(DataFlow::Node src | UntrustedUrlFlow::flow(src, node) |
127+
if trustedDomain(_) then domain = getDomain(src.asExpr()) else domain = ""
134128
)
135129
}
136130

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* The query `java/android/missing-certificate-pinning` should no longer alert about requests pointing to the local filesystem.
Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,24 @@
11
import java.net.URL;
22
import java.net.URLConnection;
33

4-
class Test{
4+
class Test {
55
URLConnection test1() throws Exception {
66
return new URL("https://good.example.com").openConnection();
77
}
88

99
URLConnection test2() throws Exception {
1010
return new URL("https://bad.example.com").openConnection(); // $hasUntrustedResult
1111
}
12-
}
12+
13+
URLConnection test3() throws Exception {
14+
return new URL("classpath:example/directory/test.class").openConnection();
15+
}
16+
17+
URLConnection test4() throws Exception {
18+
return new URL("file:///example/file").openConnection();
19+
}
20+
21+
URLConnection test5() throws Exception {
22+
return new URL("jar:file:///C:/example/test.jar!/test.xml").openConnection();
23+
}
24+
}
Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,20 @@
11
import java.net.URL;
22
import java.net.URLConnection;
33

4-
class Test{
4+
class Test {
55
URLConnection test2() throws Exception {
66
return new URL("https://example.com").openConnection(); // $hasNoTrustedResult
77
}
8-
}
8+
9+
URLConnection test3() throws Exception {
10+
return new URL("classpath:example/directory/test.class").openConnection();
11+
}
12+
13+
URLConnection test4() throws Exception {
14+
return new URL("file:///example/file").openConnection();
15+
}
16+
17+
URLConnection test5() throws Exception {
18+
return new URL("jar:file:///C:/example/test.jar!/test.xml").openConnection();
19+
}
20+
}

java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test3/Test.java

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,21 @@
22
import okhttp3.CertificatePinner;
33
import okhttp3.Request;
44

5-
class Test{
5+
class Test {
66
void test1() throws Exception {
7-
CertificatePinner certificatePinner = new CertificatePinner.Builder()
8-
.add("good.example.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")
9-
.build();
10-
OkHttpClient client = new OkHttpClient.Builder()
11-
.certificatePinner(certificatePinner)
12-
.build();
7+
CertificatePinner certificatePinner = new CertificatePinner.Builder()
8+
.add("good.example.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")
9+
.build();
10+
OkHttpClient client =
11+
new OkHttpClient.Builder().certificatePinner(certificatePinner).build();
1312

14-
client.newCall(new Request.Builder().url("https://good.example.com").build()).execute();
15-
client.newCall(new Request.Builder().url("https://bad.example.com").build()).execute(); // $hasUntrustedResult
13+
client.newCall(new Request.Builder().url("https://good.example.com").build()).execute();
14+
client.newCall(new Request.Builder().url("https://bad.example.com").build()).execute(); // $hasUntrustedResult
15+
client.newCall(new Request.Builder().url("classpath:example/directory/test.class").build())
16+
.execute();
17+
client.newCall(new Request.Builder().url("file:///example/file").build()).execute();
18+
client.newCall(
19+
new Request.Builder().url("jar:file:///C:/example/test.jar!/test.xml").build())
20+
.execute();
1621
}
17-
}
22+
}

java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/Test.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,20 @@
88
import javax.net.ssl.SSLContext;
99
import android.content.res.Resources;
1010

11-
class Test{
11+
class Test {
1212
void test1(Resources resources) throws Exception {
1313
KeyStore keyStore = KeyStore.getInstance("BKS");
1414
keyStore.load(resources.openRawResource(R.raw.cert), null);
1515

16-
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
16+
TrustManagerFactory tmf =
17+
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
1718
tmf.init(keyStore);
1819

1920
SSLContext sslContext = SSLContext.getInstance("TLS");
2021
sslContext.init(null, tmf.getTrustManagers(), null);
2122

2223
URL url = new URL("http://www.example.com/");
23-
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
24+
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
2425

2526
urlConnection.setSSLSocketFactory(sslContext.getSocketFactory());
2627
}
@@ -29,4 +30,4 @@ void test2() throws Exception {
2930
URL url = new URL("http://www.example.com/");
3031
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection(); // $hasNoTrustedResult
3132
}
32-
}
33+
}

java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/Test.java

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@
99
import javax.net.ssl.SSLContext;
1010
import android.content.res.Resources;
1111

12-
class Test{
12+
class Test {
1313
void init(Resources resources) throws Exception {
1414
KeyStore keyStore = KeyStore.getInstance("BKS");
1515
keyStore.load(resources.openRawResource(R.raw.cert), null);
1616

17-
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
17+
TrustManagerFactory tmf =
18+
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
1819
tmf.init(keyStore);
1920

2021
SSLContext sslContext = SSLContext.getInstance("TLS");
@@ -25,11 +26,26 @@ void init(Resources resources) throws Exception {
2526

2627
URLConnection test1() throws Exception {
2728
URL url = new URL("http://www.example.com/");
28-
return url.openConnection();
29+
return url.openConnection();
2930
}
3031

3132
InputStream test2() throws Exception {
3233
URL url = new URL("http://www.example.com/");
33-
return url.openStream();
34+
return url.openStream();
3435
}
35-
}
36+
37+
InputStream test3() throws Exception {
38+
URL url = new URL("classpath:example/directory/test.class");
39+
return url.openStream();
40+
}
41+
42+
InputStream test4() throws Exception {
43+
URL url = new URL("file:///example/file");
44+
return url.openStream();
45+
}
46+
47+
InputStream test5() throws Exception {
48+
URL url = new URL("jar:file:///C:/example/test.jar!/test.xml");
49+
return url.openStream();
50+
}
51+
}

0 commit comments

Comments
 (0)