Skip to content

Commit e2356d9

Browse files
authored
Merge pull request #16914 from owen-mc/java/android-app-detection
Java: Improve Android app detection
2 parents bf4a202 + db6cd18 commit e2356d9

File tree

10 files changed

+75
-10
lines changed

10 files changed

+75
-10
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: deprecated
3+
---
4+
* The predicate `isAndroid` from the module `semmle.code.java.security.AndroidCertificatePinningQuery` has been deprecated. Use `semmle.code.java.frameworks.android.Android::inAndroidApplication(File)` instead.

java/ql/lib/semmle/code/java/frameworks/android/Android.qll

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,20 @@
55
import java
66
private import semmle.code.xml.AndroidManifest
77

8+
/**
9+
* Holds if in `file`'s directory or some parent directory there is an `AndroidManifestXmlFile`
10+
* that defines at least one activity, service or contest provider, suggesting this file is
11+
* part of an android application.
12+
*/
13+
predicate inAndroidApplication(File file) {
14+
file.isSourceFile() and
15+
exists(AndroidManifestXmlFile amxf, Folder amxfDir |
16+
amxf.definesAndroidApplication() and amxfDir = amxf.getParentContainer()
17+
|
18+
file.getParentContainer+() = amxfDir
19+
)
20+
}
21+
822
/**
923
* Gets a reflexive/transitive superType
1024
*/

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import semmle.code.java.dataflow.TaintTracking
66
import semmle.code.java.frameworks.Networking
77
import semmle.code.java.security.Encryption
88
import semmle.code.java.security.HttpsUrls
9+
private import semmle.code.java.frameworks.android.Android
910

1011
/** An Android Network Security Configuration XML file. */
1112
class AndroidNetworkSecurityConfigFile extends XmlFile {
@@ -19,8 +20,12 @@ class AndroidNetworkSecurityConfigFile extends XmlFile {
1920
}
2021
}
2122

22-
/** Holds if this database is of an Android application. */
23-
predicate isAndroid() { exists(AndroidManifestXmlFile m) }
23+
/**
24+
* DEPRECATED. Use `semmle.code.java.frameworks.android.Android::inAndroidApplication` instead.
25+
*
26+
* Holds if this database contains an Android manifest file.
27+
*/
28+
deprecated predicate isAndroid() { exists(AndroidManifestXmlFile m) }
2429

2530
/** Holds if the given domain name is trusted by the Network Security Configuration XML file. */
2631
private predicate trustedDomainViaXml(string domainName) {
@@ -122,7 +127,7 @@ private module UntrustedUrlFlow = TaintTracking::Global<UntrustedUrlConfig>;
122127

123128
/** Holds if `node` is a network communication call for which certificate pinning is not implemented. */
124129
predicate missingPinning(MissingPinningSink node, string domain) {
125-
isAndroid() and
130+
inAndroidApplication(node.getLocation().getFile()) and
126131
exists(DataFlow::Node src | UntrustedUrlFlow::flow(src, node) |
127132
if trustedDomain(_) then domain = getDomain(src.asExpr()) else domain = ""
128133
)

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,15 @@
66
import java
77
import semmle.code.java.dataflow.DataFlow
88
import semmle.code.java.security.CleartextStorageQuery
9-
import semmle.code.xml.AndroidManifest
109
private import semmle.code.java.dataflow.ExternalFlow
1110
private import semmle.code.java.dataflow.FlowSinks
1211
private import semmle.code.java.dataflow.FlowSources
12+
private import semmle.code.java.frameworks.android.Android
1313

1414
private class AndroidFilesystemCleartextStorageSink extends CleartextStorageSink {
1515
AndroidFilesystemCleartextStorageSink() {
1616
filesystemInput(_, this.asExpr()) and
17-
// Make sure we are in an Android application.
18-
exists(AndroidManifestXmlFile manifest)
17+
inAndroidApplication(this.getLocation().getFile())
1918
}
2019
}
2120

java/ql/lib/semmle/code/xml/AndroidManifest.qll

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,21 @@ class AndroidManifestXmlFile extends XmlFile {
2323
* Holds if this Android manifest file is located in a build directory.
2424
*/
2525
predicate isInBuildDirectory() { this.getFile().getRelativePath().matches("%build%") }
26+
27+
/**
28+
* Holds if this file defines at least one activity, service or contest provider,
29+
* and so it corresponds to an android application rather than a library.
30+
*/
31+
predicate definesAndroidApplication() {
32+
exists(AndroidComponentXmlElement acxe |
33+
this.getManifestElement().getApplicationElement().getAComponentElement() = acxe and
34+
(
35+
acxe instanceof AndroidActivityXmlElement or
36+
acxe instanceof AndroidServiceXmlElement or
37+
acxe instanceof AndroidProviderXmlElement
38+
)
39+
)
40+
}
2641
}
2742

2843
/**
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 heuristic to enable certain Android queries has been improved. Now it ignores Android Manifests which don't define an activity, content provider or service. We also only consider files which are under a folder containing such an Android Manifest for these queries. This should remove some false positive alerts.

java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test1/AndroidManifest.xml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@
55
android:versionName="0.1" >
66

77
<application android:networkSecurityConfig="@xml/NetworkSecurityConfig">
8+
<activity android:name=".MainActivity">
9+
<intent-filter>
10+
<action android:name="android.intent.action.MAIN" />
11+
<category android:name="android.intent.category.LAUNCHER" />
12+
</intent-filter>
13+
</activity>
814
</application>
915

10-
</manifest>
16+
</manifest>

java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test2/AndroidManifest.xml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@
55
android:versionName="0.1" >
66

77
<application android:networkSecurityConfig="@xml/NetworkSecurityConfig">
8+
<activity android:name=".MainActivity">
9+
<intent-filter>
10+
<action android:name="android.intent.action.MAIN" />
11+
<category android:name="android.intent.category.LAUNCHER" />
12+
</intent-filter>
13+
</activity>
814
</application>
915

10-
</manifest>
16+
</manifest>

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@
55
android:versionName="0.1" >
66

77
<application android:networkSecurityConfig="@xml/NetworkSecurityConfig">
8+
<activity android:name=".MainActivity">
9+
<intent-filter>
10+
<action android:name="android.intent.action.MAIN" />
11+
<category android:name="android.intent.category.LAUNCHER" />
12+
</intent-filter>
13+
</activity>
814
</application>
915

10-
</manifest>
16+
</manifest>

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@
55
android:versionName="0.1" >
66

77
<application android:networkSecurityConfig="@xml/NetworkSecurityConfig">
8+
<activity android:name=".MainActivity">
9+
<intent-filter>
10+
<action android:name="android.intent.action.MAIN" />
11+
<category android:name="android.intent.category.LAUNCHER" />
12+
</intent-filter>
13+
</activity>
814
</application>
915

10-
</manifest>
16+
</manifest>

0 commit comments

Comments
 (0)