This repository contains custom lint checks for Android development. These lint checks are by nature more security-focused and experimental than the built-in lint checks within Android Studio, and are intended for more security-conscious developers.
These lint checks are based on guidance from the Android Application Security Knowledge Base that the Android Vulnerability Research team has developed, and common recurring vulnerabilities that the team spots in the wild.
Visit the official Android Lint Github Repo for guidance on writing your own custom lint checks.
This library uses the Apache license, as is Google's default.
-
Add the dependency to the app directory's
build.gradle
file:dependencies { lintChecks 'com.android.security.lint:lint:<version>' }
If using Kotlin instead of Groovy, add the dependency to the app directory's
build.gradle.kts
file:dependencies { lintChecks("com.android.security.lint:lint:<version>") }
-
Run
./gradlew lint
to see the results. Please file an issue if these instructions do not work for you.
Lint Issue ID | Detector | Risk |
---|---|---|
ExposedRootPath |
MisconfiguredFileProviderDetector |
Allowing the root directory of the device in the configuration provides arbitrary access to files and folders for attackers. |
SensitiveExternalPath |
MisconfiguredFileProviderDetector |
Sensitive info like PII should not be stored outside of the application container or system credential storage facilities. |
LogInfoDisclosure |
LogcatDetector |
Logging potentially sensitive information to logcat can leak it. |
DotPathAttribute |
MisconfiguredFileProviderDetector |
Sharing broad path ranges can expose sensitive files by mistake. |
SlashPathAttribute |
MisconfiguredFileProviderDetector |
Sharing broad path ranges can expose sensitive files by mistake. |
HardcodedAbsolutePath |
MisconfiguredFileProviderDetector |
Sharing broad path ranges can expose sensitive files by mistake. |
Lint Issue ID | Detector | Risk |
---|---|---|
VulnerableCryptoAlgorithm |
BadCryptographyUsageDetector |
Using weak or broken cryptographic hash functions may allow an attacker to reasonably determine the original input. |
UnsafeCryptoAlgorithmUsage |
BadCryptographyUsageDetector |
Using insecure modes and paddings with cryptographic algorithms is unsafe and vulnerable to attacks. |
WeakPrng |
WeakPrngDetector |
Using non-cryptographically secure PRNGs in security contexts like authentication allows attackers to guess the randomly-generated numbers. |
Lint Issue ID | Detector | Risk |
---|---|---|
DefaultCleartextTraffic |
MissingNetworkSecurityConfigDetector |
On API level 27 and below, the default network security config trusts cleartext traffic and needs to be explicitly opted out by the application to only use secure connections. |
DefaultTrustedUserCerts |
MissingNetworkSecurityConfigDetector |
On API level 23 and below, the default network security config trusts user-added CA certificates. In practice, it is better to limit the set of trusted CAs so only trusted CAs are used for an app's secure connections. |
DisabledAllSafeBrowsing |
SafeBrowsingDetector |
Safe Browsing is a service to help applications check URLs against a known list of unsafe web resources. We recommend keeping Safe Browsing enabled at all times and designing your app around any constraints this causes. |
InsecureDnsSdkLevel |
DnsConfigDetector |
Custom DNS configurations can be insecure, making an application susceptible to DNS spoofing attacks. We recommend instead making use of Android OS's built-in transport security on SDK levels 28 and above. |
Lint Issue ID | Detector | Risk |
---|---|---|
TapjackingVulnerable |
TapjackingDetector |
Views without the filterTouchesWhenObscured attribute are susceptible to tapjacking attacks by other apps obscuring the UI to trick the user into performing certain actions. |
StrandhoggVulnerable |
StrandhoggDetector |
Android previously had a bug in task reparenting in earlier versions, allowing malicious applications to hijack legitimate user actions and trick users into providing credentials to malicious apps. |
MissingAutoVerifyAttribute |
CustomSchemeDetector |
Exporting sensitive functionality via custom URL schemes should be properly protected by making use of app link verification. |
InsecureStickyBroadcastsPermission |
StickyBroadcastsDetector |
Sticky broadcasts provide no security as they can be accessed, sent, and modified by anyone. |
InsecureStickyBroadcastsMethod |
StickyBroadcastsDetector |
Sticky broadcasts provide no security as they can be accessed, sent, and modified by anyone. |
Lint Issue ID | Detector | Risk |
---|---|---|
InsecurePermissionProtectionLevel |
PermissionDetector |
Custom permissions should have a signature protectionLevel or higher. |
UnintendedExposedUrl |
UnintendedExposedUrlDetector |
URLs that look intended for debugging and development purposes only are exposed in the application, allowing attackers to gain access to parts of the application and server that should be kept secure. |
UnintendedPrivateIpAddress |
UnintendedExposedUrlDetector |
Private IP addresses are referenced that may have been intended only for debugging and development, and should not be exposed publicly. |
UnsanitizedContentProviderFilename |
UnsafeFilenameDetector |
Trusting ContentProvider filenames without sanitization may lead to unintended file writes. This lint check will be built into Android Studio starting Jan 2025, under the issue ID UnsanitizedFilenameFromContentProvider . |
ExtendedBluetoothDiscoveryDuration |
BluetoothAdapterDetector |
An overly long discovery time can increase the timeframe in which attackers can conduct Bluetooth attacks. |
ZeroBluetoothDiscoveryDuration |
BluetoothAdapterDetector |
A discovery time of zero causes the device to be discoverable as long as the application is running in the background or foreground. |
For questions, comments or feature requests, please file an issue or start a discussion on GitHub. We would love to hear from you.