Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions java/ql/lib/change-notes/2024-06-12-isandroid-deprecated.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
category: deprecated
---
* The predicate `isAndroid` from the module `semmle.code.java.security.AndroidCertificatePinningQuery` has been deprecated. Use `semmle.code.java.frameworks.android.Android::inAndroidApplication(File file)` instead.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* The predicate `isAndroid` from the module `semmle.code.java.security.AndroidCertificatePinningQuery` has been deprecated. Use `semmle.code.java.frameworks.android.Android::inAndroidApplication(File file)` instead.
* The predicate `isAndroid` from the module `semmle.code.java.security.AndroidCertificatePinningQuery` has been deprecated. Use `semmle.code.java.frameworks.android.Android::inAndroidApplication(File)` instead.

19 changes: 19 additions & 0 deletions java/ql/lib/semmle/code/java/frameworks/android/Android.qll
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,25 @@
import java
private import semmle.code.xml.AndroidManifest

/**
* There is an android manifest file which defines an activity, service or
* content provider (so it corresponds to an android application rather than a
* library), and `file` is in a subfolder of the folder that contains it.
*/
predicate inAndroidApplication(File file) {
file.isSourceFile() and
exists(AndroidComponentXmlElement acxe, AndroidManifestXmlFile amxf |
amxf.getManifestElement().getApplicationElement().getAComponentElement() = acxe and
(
acxe instanceof AndroidActivityXmlElement or
acxe instanceof AndroidServiceXmlElement or
acxe instanceof AndroidProviderXmlElement
)
|
file.getParentContainer+() = amxf.getParentContainer()
)
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/**
* There is an android manifest file which defines an activity, service or
* content provider (so it corresponds to an android application rather than a
* library), and `file` is in a subfolder of the folder that contains it.
*/
predicate inAndroidApplication(File file) {
file.isSourceFile() and
exists(AndroidComponentXmlElement acxe, AndroidManifestXmlFile amxf |
amxf.getManifestElement().getApplicationElement().getAComponentElement() = acxe and
(
acxe instanceof AndroidActivityXmlElement or
acxe instanceof AndroidServiceXmlElement or
acxe instanceof AndroidProviderXmlElement
)
|
file.getParentContainer+() = amxf.getParentContainer()
)
}
/**
* Holds if `amxf` defines at least one activity, service or contest provider,
* and so it corresponds to an android application rather than a library.
*/
private predicate definesAndroidApplication(AndroidManifestXmlFile amxf) {
exists(AndroidComponentXmlElement acxe |
amxf.getManifestElement().getApplicationElement().getAComponentElement() = acxe and
(
acxe instanceof AndroidActivityXmlElement or
acxe instanceof AndroidServiceXmlElement or
acxe instanceof AndroidProviderXmlElement
)
)
}
/**
* Holds if in `file`'s directory or some parent directory there is an `AndroidManifestXmlFile`
* that defines at least one activity, service or contest provider, suggesting this file is
* part of an android application.
*/
predicate inAndroidApplication(File file) {
file.isSourceFile() and
exists(AndroidManifestXmlFile amxf, Folder amxfDir |
definesAndroidApplication(amxf) and amxfDir = amxf.getParentContainer()
|
file.getParentContainer+() = amxfDir
)
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(rewords the comment to use Holds if, and splits it into two predicates)

/**
* Gets a reflexive/transitive superType
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.frameworks.Networking
import semmle.code.java.security.Encryption
import semmle.code.java.security.HttpsUrls
private import semmle.code.java.frameworks.android.Android

/** An Android Network Security Configuration XML file. */
class AndroidNetworkSecurityConfigFile extends XmlFile {
Expand All @@ -19,8 +20,12 @@ class AndroidNetworkSecurityConfigFile extends XmlFile {
}
}

/** Holds if this database is of an Android application. */
predicate isAndroid() { exists(AndroidManifestXmlFile m) }
/**
* DEPRECATED. Use `semmle.code.java.frameworks.android.Android::inAndroidApplication` instead.
*
* Holds if this database contains an Android manifest file.
*/
deprecated predicate isAndroid() { exists(AndroidManifestXmlFile m) }

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

/** Holds if `node` is a network communication call for which certificate pinning is not implemented. */
predicate missingPinning(MissingPinningSink node, string domain) {
isAndroid() and
inAndroidApplication(node.getLocation().getFile()) and
exists(DataFlow::Node src | UntrustedUrlFlow::flow(src, node) |
if trustedDomain(_) then domain = getDomain(src.asExpr()) else domain = ""
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,15 @@
import java
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.security.CleartextStorageQuery
import semmle.code.xml.AndroidManifest
private import semmle.code.java.dataflow.ExternalFlow
private import semmle.code.java.dataflow.FlowSinks
private import semmle.code.java.dataflow.FlowSources
private import semmle.code.java.frameworks.android.Android

private class AndroidFilesystemCleartextStorageSink extends CleartextStorageSink {
AndroidFilesystemCleartextStorageSink() {
filesystemInput(_, this.asExpr()) and
// Make sure we are in an Android application.
exists(AndroidManifestXmlFile manifest)
inAndroidApplication(this.getLocation().getFile())
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* 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.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
android:versionName="0.1" >

<application android:networkSecurityConfig="@xml/NetworkSecurityConfig">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>
</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
android:versionName="0.1" >

<application android:networkSecurityConfig="@xml/NetworkSecurityConfig">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>
</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
android:versionName="0.1" >

<application android:networkSecurityConfig="@xml/NetworkSecurityConfig">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>
</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
android:versionName="0.1" >

<application android:networkSecurityConfig="@xml/NetworkSecurityConfig">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>
</manifest>