A journey using Android static source code analysis tools

Introduction

In a decade, mobile applications became a daily tool simplifying people’s lives worldwide (from accessing bank account to watching movies etc.). This trend has brought to light a new attack surface and vulnerabilities began to arise due to the huge amount of functionalities offered by the mobile OS.

This blog post aims to present and compare open source tools to see their ability to detect complex vulnerabilities.

Performing a source code analysis helps to detect security holes in a more exhaustive and proactive way than a penetration test, which might leave out some aspects. This kind of audit is mainly done in two ways :

  • using automatic and static source code analysis tools;
  • diving into the source code and searching for vulnerabilities in core security features (authentication etc.).

This post will be structured in the following way :

  • list of some tools available on Github;
  • list of the vulnerabilities we would like those tools be able to detect;
  • comparison of the tools (how and what they analyse);
    • testing them against InsecureShop, an intentionally vulnerable Android app developed in Kotlin by hax0rgb (thanks to him).

Before starting, we have to keep in mind that tools are not meant to be perfect. At the time of writing, none of them can claim that and security researchers should not just rely on tools without double-checking the results they give. Beyond that, a source code audit must be based on an in-depth understanding of how the application works (what an automatic tool is unable to do).

Tools

Among the open source tools available on GitHub, many are no longer maintained (sometimes for more than 10 years). The below list gathers the majority of them :

Vulnerabilities we want to detect

The InsecureShop application has 19 vulnerabilities but here are the ones we want all the previous tools to be tested against :

  • insufficient URL validation;
  • weak host validation check;
  • unprotected data uris;
  • intent redirection;
  • theft of arbitrary files;
  • use of implicit intent to send a broadcast with sensitive data;
  • insecure implementation of SetResult in exported Activity.

We chose them as they are exploitable without having root access on the device.

Analysing the tools’ detection capacity

androwarn

This tool was not developed to find vulnerabilities but to detect potential malicious behaviours in Android apps (with the help of the androguard library). We will not analyze it here.

ApkAnalyzer

Simply too old (last commit was 10 years ago) and not relevant to analyze.

apkinspector

Simply too old (last commit was 10 years ago) and not relevant to analyze.

StaCoAn

Not maintained anymore.

AndroBugs_Framework

This project doesn’t seem to be maintained anymore. Conversations between users and its author suggest it could be reactivated but nothing new since then. Moreover, a lot of tests consist in checking if the target application is vulnerable to CVEs found back in 2013…

ApkAnalyser

This tool just collects data to quickly analyse an APK (AndroidManifest.xml, certificate, resources etc.). All source code files related to those functionnalities are gathered here in the official Github repo. As an example, please see the extract below which is used to retrieve infomation in AndroidManifest.xml

// This code was developed by MartinStyk (thanks to him)
private boolean processUsingDecompilation() {

    boolean isSuccess;

    logger.trace(apkNameMarker + "Using Apktool decompilation method");

    try {

        manifestFile = new File(apkFile.getDecompiledDirectoryWithDecompiledData(), "AndroidManifest.xml");
        document = XmlParsingHelper.getNormalizedDocument(manifestFile);

        getManifestTagData();
        getAppComponents();
        getUsedPermissions();
        getUsedLibraries();
        getUsedFeatures();
        getDefinedPermissions();
        getUsesSdk();
        getSupportScreens();

        isSuccess = true;

    } catch (Exception e) {
        logger.error(apkNameMarker + e.toString());
        isSuccess = false;
    } finally {
        document = null;
    }
    return isSuccess;
}

[...]

private void getUsedPermissions() {
    List<String> result = XmlParsingHelper.getListOfTagAttributeValues(document, "uses-permission", "android:name");
    manifestData.setUsesPermissions(result);
}

[...]

It works exactly the same way for parsing certificate data, etc. However, it cannot highlight the vulnerabilities we were interested in as it was not developed to.

  • pro(s)

    • Get all information about an APK.
  • con(s)

    • not created to detect vulnerabilities and unable to find the ones we were interested in;
    • not maintained anymore;
    • java application.

ReverseAPK

ReverseAPK comes as a single bash script. According to its author, it “quickly analyze and reverse engineer Android applications”. Its main feature consists in doing static source code analysis for common vulnerabilities and behaviors like :

  • Command execution;
  • SQLite usage;
  • Logging functions usage;
  • Components (providers, receivers etc.) references;
  • Hardcoded secrets;
  • Network connections;
  • SSL;
  • Webview.

After reading the source code, it’s just a grep-based script designed to detect the components listed above. As an example, here is an extract :

# This code was developed by 1N3 (thanks to him)

################## INTENT REFERENCES

echo -e "$OKRED Searching for android.intent references..."
echo -e "$OKRED=====================================================================$RESET"
for a in `find $PWD/$1-jadx | egrep -i .java`; do egrep -nH 'android\.intent' $a --color=auto 2>/dev/null; done;

echo -e "$OKRED Searching for Intent references..."
echo -e "$OKRED=====================================================================$RESET"
for a in `find $PWD/$1-jadx | egrep -i .java`; do egrep -nH 'intent\.' $a --color=auto 2>/dev/null; done;

[...]

################# SQLITE REFERENCES

echo -e "$OKRED Searching for SQLiteDatabase references..."
echo -e "$OKRED=====================================================================$RESET"
for a in `find $PWD/$1-jadx | egrep -i .java`; do egrep -nH 'SQLiteDatabase' $a --color=auto 2>/dev/null; done;

[...]

Unfortunately, it cannot identify any of the vulnerabilities we were interested in.

NB: The Runtime.getRuntime().exec() function prevents command injections. If your goal is to find this type of vulnerability, looking for this pattern in the source code (as this tool does) is not necessarily relevant.

  • con(s)
    • not created to detect vulnerabilities and unable to find the ones we were interested in.

mariana-trench

mariana-trench is a security focused static source code analysis tool based on source/sink behavioral detection. It means that it can detect where a data comes from (source), track it and know where it lands (sink). That’s a very effective method to get our hands on complex vulnerabilities in massive projects.

Its source code is quite complex (and will not be explained here) but overall, the interesting features seem to be located here and there. More precisely those json files contain and define the sources and sinks.

After having followed the installation steps, here are the commands to analyze the InsecureShop application and parse the results.

# Analyze
mariana-trench \
  --system-jar-configuration-path=$ANDROID_SDK/platforms/android-31/android.jar \
  --model-generator-configuration-paths=configuration/default_generator_config.json \
  --lifecycles-paths=configuration/lifecycles.json \
  --rules-paths=configuration/rules.json \
  --apk-path=~/Documents/Article/InsecureShop.apk \
  --source-root-directory=~/Documents/Article/InsecureShop/app/src/main/java \
  --model-generator-search-paths=configuration/model-generators/
  
[...]

2023-02-16 14:09:39 INFO Analyzed 88744 models in 27.23s. Found 10 issues!
2023-02-16 14:09:39 INFO Augmenting positions...
2023-02-16 14:09:39 INFO Augmented positions in 0.11s.
2023-02-16 14:09:39 INFO Writing models to `/home/s1ren/Documents/Article/mariana-trench/`.
2023-02-16 14:09:41 INFO Wrote models to 9 shards.
2023-02-16 14:09:41 INFO Wrote models in 2.17s.
2023-02-16 14:09:41 INFO Writing metadata to `/home/s1ren/Documents/Article/mariana-trench/metadata.json`.
  
  
# Parse results
sapp --tool=mariana-trench analyze .
sapp --database-name=sapp.db server --source-directory=~/Documents/Article/InsecureShop/app/src/main/java

An interesting metadata.json file has been created. It basically contains information about the analysis but also describes the five types of vulnerabilities involving a source/sink behavioral detection with their associated code.

Thus, mariana-trench is able to detect the following :

{
  "codes" : 
  {
    "1" : "User input flows into code execution sink (RCE)",
    "2" : "User input flows into file resolver",
    "3" : "User input flows into implicitly launched intent",
    "4" : "User input flows into raw SQL statement",
    "5" : "User input flows into WebView load"
  },
  "filename_spec" : "model@*.json",
  "repo_root" : "/home/s1ren/Documents/Article/mariana-trench/",
  "root" : "/home/s1ren/Documents/Article/InsecureShop/app/src/main/java/",
"[...]"

Using SAPP, another Facebook tool, we get access to a local python Flask server to play with HTML formatted results.

Results

Upon completion of the analysis, the following 10 vulnerabilities were detected.

Vulnerability 1

The first vulnerability matches the “Theft of arbitrary files” one.

vuln1

The exported ChooserActivity.kt activity takes a user controllable file URI and creates a copy of that file on the external storage when the EXTRA_STREAM implicit intent is received. This could be used by another installed application to access any file in the InsecureShop sandboxed environment located in /data/data/com.insecureshop/*.

The associated source code is the following : (mariana-trench highlights [1])

class ChooserActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_chooser)
        if (intent.extras != null) {
            var uri = intent.getParcelableExtra<Parcelable>("android.intent.extra.STREAM") as Uri
            uri = Uri.fromFile(File(uri.toString())) // [1] 
            makeTempCopy(uri, getFilename(uri)) // [2]
        }

    }
    private fun makeTempCopy(fileUri: Uri, original_filename: String?): Uri? {
        try {
            val path : String = Environment.getExternalStorageDirectory().absolutePath + File.separator + "insecureshop";
            val directory =
                File(path)
            if (!directory.exists()) {
                val directoryBoolean = directory.mkdirs()
            }
            val fileTemp = File(path, original_filename)
            val fileBoolean = fileTemp.createNewFile()
            val out = Uri.fromFile(fileTemp)

            val inputStream: InputStream? = contentResolver.openInputStream(fileUri)
            val outputStream: OutputStream? = contentResolver.openOutputStream(out)
            val buffer = ByteArray(8192)
            while (true) {
                val len: Int? = inputStream?.read(buffer)
                if (len != -1) {
                    len?.let { outputStream?.write(buffer, 0, it) }
                }
            }
            return out
        } catch (e: Exception) {
            return null
        }
    }
  }
Vulnerability 2

It appears to be the same as the previous one but this time highlighting [2], which is actually the second vulnerable line.

Vulnerabilities 3 & 4

Those are just false positives because the source/sink location does not match any source code file of the application. Furthermore, the delete function is not called by the InsecureShop application.

vuln3

vuln4

Vulnerability 5

The fifth vulnerability matches the “Insufficient URL validation” one.

vuln5

It stems from the exported WebViewActivity.kt activity, which uses a WebView component and does not validate the user controllable url parameter’s content before passing it to the loadUrl function. This results in the ability to load any arbitrary URL in that WebView.

The associated source code is as follows :

class WebViewActivity : AppCompatActivity() {

    val USER_AGENT =
        "Mozilla/5.0 (Linux; Android 4.1.1; Galaxy Nexus Build/JRO03C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.65 Mobile Safari/537.36"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_webview)
        setSupportActionBar(toolbar)
        title = getString(R.string.webview)

        val webview = findViewById<WebView>(R.id.webview)

        [...]

        val uri : Uri? = intent.data
        uri?.let {
            var data: String? = null
            if (uri.path.equals("/web")) {
                data = intent.data?.getQueryParameter("url")
            }

            [...]

            if (data == null) {
                finish()
            }
            webview.loadUrl(data) // [1]
            Prefs.getInstance(this).data = data
        }

    }
}
Vulnerability 6

The sixth vulnerability matches the “Unprotected data Uris” one. It’s the same category as the previous one, when an unvalidated and unsafe URL is passed to the loadUrl function (see [1] in the associated source code below).

vuln6

The associated source code is as follows :

class WebView2Activity : AppCompatActivity() {

    val USER_AGENT =
        "Mozilla/5.0 (Linux; Android 4.1.1; Galaxy Nexus Build/JRO03C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.65 Mobile Safari/537.36"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_webview)
        setSupportActionBar(toolbar)
        title = getString(R.string.webview)

        val extraIntent = intent.getParcelableExtra<Intent>("extra_intent")
        if (extraIntent != null) {
            startActivity(extraIntent) // [4]
            finish()
            return
        }

        val webview = findViewById<WebView>(R.id.webview)

        webview.settings.javaScriptEnabled = true
        webview.settings.loadWithOverviewMode = true
        webview.settings.useWideViewPort = true
        webview.settings.allowUniversalAccessFromFileURLs = true
        webview.settings.userAgentString = USER_AGENT
        if (!intent.dataString.isNullOrBlank()) {
            webview.loadUrl(intent.dataString) // [1]
        } else if (!intent.data?.getQueryParameter("url").isNullOrBlank()) {
            webview.loadUrl(intent.data?.getQueryParameter("url")) // [2]
        } else if(!intent.extras?.getString("url").isNullOrEmpty()){
            webview.loadUrl(intent.extras?.getString("url")) // [3]
        }
    }
}

However, this extract has another vulnerability (not detected by this tool) which actually matches the “Intent redirection” one (located in [4])

According to oversecured, “This vulnerability looks like Open Redirect in web security. Since class Intent is Parcelable, objects belonging to this class can be passed as extra data in another Intent object”.

Here, the exported WebView2Activity activity has an intent being passed in the extra part of another intent and uses that to start an activity without any sanitization. An attacker could therefore access and start any unexported application component, bypassing the Android system’s built-in restrictions.

Vulnerabilities 7 & 8

They appear to be the same as the previous one but this time highlighting [2] and [3] which are respectively the second and the third vulnerable line associated with this vulnerability.

Vulnerability 9

Same as vulnerabilities 5 and 6.

vuln9

Vulnerability 10

vuln10

This is just a false positive because the source/sink location does not match any source code files of the application.

To conclude, only 3 out of 7 vulnerabilities have been detected but mariana-trench is a pretty powerful tool which should be used during a source code analysis.

  • pro(s)

    • uses source/sink behavioral detection;
    • relatively precise and intelligible results.
  • con(s)

    • not easily extensible;
    • not easy to use (many parameters in the commande line).

SUPER Android Analyzer

According to its author, SUPER Android Analyzer which stands for Secure, Unified, Powerful and Extensible Rust Android Analyzer, has been developed to be easily extensible. There is no mention of its detection capabilities, but the README.md refers to a rules.json file which gathers all rules to be checked.

Unfortunately, it’s just a regex-based script with no “intelligence” over the top.

Here is an extract of this file :

[{
    "regex": "(?:(?:ftp|http)s?:\/\/|www\\.)[\\w\\.-]+\\.[[:alpha:]]{2,6}(?:\/[\\w\\.\/-]*)?",
    "whitelist": [
        "schemas.android.com",
        "www.w3.org",
        "www.apache.org/licenses",
        "play.google.com/store/apps",
        "dev.twitter.com/docs",
        "api.twitter.com",
        "crashlytics.com/spi/v\\d",
        "com.android.calendar/events",
        "www.googleapis.com/auth",
        "market://details",
        "developers.facebook.com/docs",
        "content://.*"
    ],
    "label": "URL Disclosure",
    "description": "The decompilation of the source code could lead to the disclosure of private URLs.",
    "criticality": "warning"
}, {
    "regex": "catch\\s*\\(\\s*(?:(?:\\s*\\|?\\s*\\w+)*\\s*\\|)?\\s*Exception|SystemException|ApplicationException\\s*(?:(?:\\s*\\|\\s*\\w+)*)?\\s+\\w+\\s*\\)",
    "criticality": "low",
    "label": "Generic Exception in catch",
    "description": "Exception catching should be specific. Generic Exception type could not be safe and lead to silent error suppresion",
    "include_file_regex": ".java$"
}
"[...]"

However, and although it is no longer maintained, it turns out some elements are interesting and the regular expressions are very well written.

  • pro(s)

    • easily extensible with new regex;
    • well written regex improving detection accuracy.
  • con(s)

    • unable to detect complex vulnerabilities;
    • not maintained anymore.

MobSF

MobSF stands for Mobile Security Framework. It’s a powerful tool able to conduct static and dynamic analysis but here, we will just focus on the static part. As the source code is pretty big (and this blog post is starting to be too) we will not analyze what it can detect and how it does.

To simplify the installation process I decided to locally deploy the web instance using the following docker commands :

docker pull opensecurity/mobile-security-framework-mobsf
# Static Analysis Only
docker run -it --rm -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest

We have now access to a web page in which we just drag & drop our compiled APK binary.

After a long waiting time, the analysis is done and the results are presented within different categories :

  • Network
  • Certificate
  • Manifest
  • Code
  • Binary
  • NIAP
  • File

Here we will only be interested in the “Code” one because the vulnerabilities of interest directly stem for coding errors.

And… what a disappointment seeing that only five vulnerabilities have been reported and none of them are in our list.

MobSF_1

MobSF_2

MobSF_3

MobSF_4

MobSF_5

  • pro(s)

    • static and dynamic analysis;
    • complete and categorized HTML formatted results.
  • con(s)

    • unable to detect complex vulnerabilities;
    • not easily extensible.

Qark

Qark is a LinkedIn team’s tool which has been designed to detect multiple vulnerabilities as indicate in the README.md. The source code files associated with those detection capabilities are located here but none match the vulnerabilities we are interested in.

Furthermore, this tool is not maintained anymore and only works with python 2.7.13 and 3.6, both having reached end of life.

As I currently use an Ubuntu 22.04 machine, those versions cannot be installed via apt.

If you still want to play with this tool, you can use the following commands :

sudo apt-get install -y git build-essential libbz2-dev 
sudo apt-get install -y libssl-dev libreadline-dev libffi-dev libsqlite3-dev tk-dev

curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash

echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init -)"' >> ~/.bashrc

echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.profile
echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.profile
echo 'eval "$(pyenv init -)"' >> ~/.profile

exec "$SHELL"

pyenv install 3.6.0

pyenv virtualenv 3.6.0 qark
pyenv activate qark

pip install --upgrade pip

# qark installation steps (see the README.md)
  • con(s)
    • unable to detect complex vulnerabilities;
    • not easily extensible;
    • not maintained anymore.

CodeQL

According to the official documentation, “CodeQL is the analysis engine used by developers to automate security checks, and by security researchers to perform variant analysis. In CodeQL, code is treated like data. Security vulnerabilities, bugs, and other errors are modeled as queries that can be executed against databases extracted from code”

Extracting a database from the source code files implies the ability to compile the entire project. To do this, CodeQL supports multiple languages and compilers (but only Gradle will be used here).

Compile the InsecureShop application

The InsecureShop application can be compiled with the below procedure :

# install CodeQL
export VERSION=v2.12.2
wget https://github.com/github/codeql-cli-binaries/releases/download/$VERSION/codeql-linux64.zip
sudo unzip -d /opt codeql-linux64.zip
echo 'export PATH=$PATH:/opt/codeql' >> ~/.bashrc
exec $SHELL
codeql

# get the Gradle version used by the application in gradle-wrapper.properties file and install it
export VERSION=gradle-5.6.4
wget https://services.gradle.org/distributions/$VERSION-all.zip
sudo unzip -d /opt gradle-5.6.4-all.zip
echo 'export PATH=$PATH:/opt/gradle' >> ~/.bashrc
exec $SHELL

# clone CodeQL rules databases
git clone https://github.com/github/codeql.git

# install java and javac packages (which also includes the JRE)
sudo apt install default-jdk

# create an environment variable that points to the SDK
export ANDROID_HOME=~/Android/Sdk

# create an environment variable that points to the JDK
export JAVA_HOME=$(readlink -f /usr/bin/java | sed "s:bin/java::")

# create the database
codeql database create insecureShop --language=java --command=' /opt/gradle-5.6.4/bin/gradle --no-daemon clean test'

Unfortunately, an error occured because javax/xml/bind/JAXBException was not found. After some research, it turns out JABX was removed in Java 9 and higher. This can be fixed by uninstalling default-jdk* and default-jre* and replacing it with openjdk-8-jdk.

Finally, we get a BUILD SUCCESSFUL !

[...]
[2023-02-22 17:07:43] [build-stdout] BUILD SUCCESSFUL in 1m 5s
[2023-02-22 17:07:43] [build-stdout] 42 actionable tasks: 42 executed
Finalizing database at /home/s1ren/Documents/Article/InsecureShop/insecureShop.
[2023-02-22 17:07:46] [build-stderr] Scanning for files in /home/s1ren/Documents/Article/InsecureShop...
[2023-02-22 17:07:47] [build-stderr] /home/s1ren/Documents/Article/InsecureShop/insecureShop: Indexing files in in /home/s1ren/Documents/Article/InsecureShop...
[2023-02-22 17:07:47] [build-stderr] Running command in /home/s1ren/Documents/Article/InsecureShop: [/opt/codeql/codeql/xml/tools/index-files.sh, /home/s1ren/Documents/Article/InsecureShop/insecureShop/working/files-to-index13482138099735382297.list]
Successfully created database at /home/s1ren/Documents/Article/InsecureShop/insecureShop.

Analyze the InsecureShop application

The analysis can then be performed with the simple command below :

codeql database analyze insecureShop/ ../codeql/java/ql/src/Security/ --format=csv --output=test4

Running queries.
Compiling query plan for /home/s1ren/Documents/Article/codeql/java/ql/src/Security/CWE/CWE-078/ExecTainted.ql.
[1/119] Found in cache: /home/s1ren/Documents/Article/codeql/java/ql/src/Security/CWE/CWE-078/ExecTainted.ql.
Compiling query plan for /home/s1ren/Documents/Article/codeql/java/ql/src/Security/CWE/CWE-078/ExecUnescaped.ql.
[2/119] Found in cache: /home/s1ren/Documents/Article/codeql/java/ql/src/Security/CWE/CWE-078/ExecUnescaped.ql.

[...]

ImproperIntentVerification.ql: [112/117 eval 32ms] Results written to codeql/java-queries/Security/CWE/CWE-925/ImproperIntent...
ContentProviderIncompletePermissions.ql: [113/117 eval 15ms] Results written to codeql/java-queries/Security/CWE/CWE-926/ContentProvide...
ImplicitlyExportedAndroidComponent.ql: [114/117 eval 47ms] Results written to codeql/java-queries/Security/CWE/CWE-926/ImplicitlyExpo...
ImplicitPendingIntents.ql: [115/117 eval 162ms] Results written to codeql/java-queries/Security/CWE/CWE-927/ImplicitPendi...

Shutting down query evaluator.
Interpreting results.
A fatal error occurred: Could not process query metadata for /home/s1ren/Documents/Article/codeql/java/ql/src/Security/CWE/CWE-020/ExternalAPIsUsedWithUntrustedData.ql.
Error was: Unknown kind "Table". [UNSUPPORTED_KIND]

Removing the CWE-020 directory allows to fix the error and finally get some results:

cat test4
"Application backup allowed","Allowing application backups may allow an attacker to extract sensitive data.","recommendation","Backups are allowed in this Android application.","/app/src/main/AndroidManifest.xml","12","5","96","19"

"Implicitly exported Android component","Android components with an '<intent-filter>' and no 'android:exported' attribute are implicitly exported, which can allow for improper access to the components themselves and to their data.","warning","This component is implicitly exported.","/app/src/main/AndroidManifest.xml","21","9","44","20"

"Implicitly exported Android component","Android components with an '<intent-filter>' and no 'android:exported' attribute are implicitly exported, which can allow for improper access to the components themselves and to their data.","warning","This component is implicitly exported.","/app/src/main/AndroidManifest.xml","57","9","67","20"

"Implicitly exported Android component","Android components with an '<intent-filter>' and no 'android:exported' attribute are implicitly exported, which can allow for improper access to the components themselves and to their data.","warning","This component is implicitly exported.","/app/src/main/AndroidManifest.xml","68","9","74","20"

"Missing read or write permission in a content provider","Android content providers which do not configure both read and write permissions can allow permission bypass.","warning","Exported provider has incomplete permissions.","/app/src/main/AndroidManifest.xml","82","9","86","73"

However, it’s not what we would expect. For instance, the “Intent Redirection vulnerability” was not detected. This lack of accuracy could be explained because kotlin support is in beta since december 2022. Furthermore, a Github issue goes along those lines, indicating there might be some problems with this language.

To validate this assumption, we will performed the same analysis against the ovaa application (developed in Java by oversecured).

Compile & analyze the Oversecured Vulnerable Android App (ovaa)

Having installed the NDK and Cmake (the ovaa application uses c++ files) we downloaded gradle 6.1.1 to get the following results :

cat test3
"Executing a command with a relative path","Executing a command with a relative path is vulnerable to malicious changes in the PATH environment variable.","warning","Command with a relative path 'logcat' is executed.","/app/src/main/java/oversecured/ovaa/services/InsecureLoggerService.java","41","63","41","73"

"Application backup allowed","Allowing application backups may allow an attacker to extract sensitive data.","recommendation","Backups are allowed in this Android application.","/app/src/main/AndroidManifest.xml","7","5","56","19"

"Failure to use HTTPS URLs","Non-HTTPS connections can be intercepted by third parties.","recommendation","URL may have been constructed with HTTP protocol, using [[""this HTTP URL""|""relative:///app/src/main/java/oversecured/ovaa/network/RetrofitInstance.java:8:44:8:72""]].","/app/src/main/java/oversecured/ovaa/network/RetrofitInstance.java","13","30","13","37"
"Android Intent redirection","Starting Android components with user-provided Intents can provide access to internal components of the application, increasing the attack surface and potentially causing unintended effects.","error","Arbitrary Android activities or services can be started from a [[""user-provided value""|""relative:///app/src/main/java/oversecured/ovaa/activities/LoginActivity.java:78:33:78:43""]].","/app/src/main/java/oversecured/ovaa/activities/LoginActivity.java","80","27","80","40"

"Intent URI permission manipulation","Returning an externally provided Intent via 'setResult' may allow a malicious application to access arbitrary content providers of the vulnerable application.","error","This Intent can be set with arbitrary flags from a [[""user-provided value""|""relative:///app/src/main/java/oversecured/ovaa/activities/DeeplinkActivity.java:67:70:67:90""]], and used to give access to internal content providers.","/app/src/main/java/oversecured/ovaa/activities/DeeplinkActivity.java","70","35","70","38"

"Implicitly exported Android component","Android components with an '<intent-filter>' and no 'android:exported' attribute are implicitly exported, which can allow for improper access to the components themselves and to their data.","warning","This component is implicitly exported.","/app/src/main/AndroidManifest.xml","8","9","15","20"

"Implicitly exported Android component","Android components with an '<intent-filter>' and no 'android:exported' attribute are implicitly exported, which can allow for improper access to the components themselves and to their data.","warning","This component is implicitly exported.","/app/src/main/AndroidManifest.xml","22","9","27","20"

"Implicitly exported Android component","Android components with an '<intent-filter>' and no 'android:exported' attribute are implicitly exported, which can allow for improper access to the components themselves and to their data.","warning","This component is implicitly exported.","/app/src/main/AndroidManifest.xml","34","9","39","20"

"Implicitly exported Android component","Android components with an '<intent-filter>' and no 'android:exported' attribute are implicitly exported, which can allow for improper access to the components themselves and to their data.","warning","This component is implicitly exported.","/app/src/main/AndroidManifest.xml","46","9","50","19"

"Leaking sensitive information through an implicit Intent","An Android application uses implicit Intents containing sensitive data in a way that exposes it to arbitrary applications on the device.","warning","This call may leak [[""sensitive information""|""relative:///app/src/main/java/oversecured/ovaa/objects/LoginData.java:12:22:12:26""]].

This call may leak [[""sensitive information""|""relative:///app/src/main/java/oversecured/ovaa/objects/LoginData.java:13:25:13:32""]].","/app/src/main/java/oversecured/ovaa/activities/MainActivity.java","47","31","47","31"

"Leaking sensitive information through an implicit Intent","An Android application uses implicit Intents containing sensitive data in a way that exposes it to arbitrary applications on the device.","warning","This call may leak [[""sensitive information""|""relative:///app/src/main/java/oversecured/ovaa/activities/MainActivity.java:56:67:56:71""]].","/app/src/main/java/oversecured/ovaa/activities/MainActivity.java","58","31","58","31"

"Uncontrolled data used in path expression","Accessing paths influenced by users can allow an attacker to access unexpected resources.","error","This path depends on a [[""user-provided value""|""relative:///app/src/main/java/oversecured/ovaa/providers/TheftOverwriteProvider.java:47:42:47:57""]].","/app/src/main/java/oversecured/ovaa/providers/TheftOverwriteProvider.java","48","21","48","97"

"Android missing certificate pinning","Network connections that do not use certificate pinning may allow attackers to eavesdrop on communications.","warning","This network call does not implement certificate pinning. (no explicitly trusted domains)","/app/src/main/java/oversecured/ovaa/network/RetrofitInstance.java","13","30","13","37"

"Hard-coded credential in API call","Using a hard-coded credential in a call to a sensitive Java API may compromise security.","error","Hard-coded value flows to [[""sensitive API call""|""relative:///app/src/main/java/oversecured/ovaa/utils/WeakCrypto.java:16:61:16:74""]].","/app/src/main/java/oversecured/ovaa/utils/WeakCrypto.java","9","39","9","72"

"Android WebSettings file access","Enabling access to the file system in a WebView allows attackers to view sensitive information.","warning","WebView setting setAllowFileAccessFromFileURLs may allow for unauthorized access of sensitive information.","/app/src/main/java/oversecured/ovaa/activities/WebViewActivity.java","27","9","27","66"

"Android WebView settings allows access to content links","Access to content providers in a WebView can allow access to protected information by loading content:// links.","warning","Sensitive information may be exposed via a malicious link due to access to content:// links being allowed in this WebView.","/app/src/main/java/oversecured/ovaa/activities/WebViewActivity.java","18","27","18","52"

"Android WebView JavaScript settings","Enabling JavaScript execution in a WebView can result in cross-site scripting attacks.","warning","JavaScript execution enabled in WebView.","/app/src/main/java/oversecured/ovaa/activities/WebViewActivity.java","26","9","26","56"

And this time the “Intent redirection vulnerability” is detected in LoginActivity line 76.

  • pro(s)

    • strongly accurate results;
    • really extensible (creating new rules).
  • con(s)

    • requires to be able to compile the project.

Conclusion

Throughout this blog post we fully demonstrated that there is plenty of open source tools designed to analyse Android applications, but only a few of them are maintained and provide relevant results. As you can see, only mariana-trench and CodeQL have found some of the vulnerabilities we wanted to detect.

More than ever, an in-depth understanding of the application, the use of several static analysis tools and a thorough manual analysis are therefore necessary to successfully carry out a code audit. We at Stackered can assess the security of your mobile applications (Android & iOS) by accurately identifying the attack surface and hot spots of your product.