mirror of
https://github.com/github/codeql.git
synced 2025-12-22 03:36:30 +01:00
Added query for Cleartext Storage in Android Filesystem
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
public void fileSystemStorageUnsafe(String name, String password) {
|
||||
// BAD - sensitive data stored in plaintext
|
||||
FileWriter fw = new FileWriter("some_file.txt");
|
||||
fw.write(name + ":" + password);
|
||||
fw.close();
|
||||
}
|
||||
|
||||
public void filesystemStorageEncryptedFileSafe(Context context, String name, String password) {
|
||||
// GOOD - the whole file is encrypted with androidx.security.crypto.EncryptedFile
|
||||
File file = new File("some_file.txt");
|
||||
String masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC);
|
||||
EncryptedFile encryptedFile = new EncryptedFile.Builder(
|
||||
file,
|
||||
context,
|
||||
masterKeyAlias,
|
||||
EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
|
||||
).build();
|
||||
FileOutputStream encryptedOutputStream = encryptedFile.openFileOutput();
|
||||
encryptedOutputStream.write(name + ":" + password);
|
||||
}
|
||||
|
||||
public void fileSystemStorageSafe(String name, String password) {
|
||||
// GOOD - sensitive data is encrypted using a custom method
|
||||
FileWriter fw = new FileWriter("some_file.txt");
|
||||
fw.write(name + ":" + encrypt(password));
|
||||
fw.close();
|
||||
}
|
||||
|
||||
private static String encrypt(String cleartext) {
|
||||
// Use an encryption or strong hashing algorithm in the real world.
|
||||
// The example below just returns a SHA-256 hash.
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
||||
byte[] hash = digest.digest(cleartext.getBytes(StandardCharsets.UTF_8));
|
||||
String encoded = Base64.getEncoder().encodeToString(hash);
|
||||
return encoded;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>
|
||||
Android applications with the appropriate permissions can write files either to the device external storage or the application internal storage, depending on the application's needs. However, sensitive information should not be saved in cleartext. Otherwise it can be accessed by any process or user in rooted devices, or can be disclosed through chained vulnerabilities, like unexpected access to the private storage through exposed components.
|
||||
</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>
|
||||
Consider using the <code>EncryptedFile</code> class to work with files containing sensitive data. Alternatively, use encryption algorithms to encrypt the sensitive data being stored.
|
||||
</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
<p>
|
||||
In the first example, sensitive user information is stored in cleartext using a local file.
|
||||
</p>
|
||||
<p>
|
||||
In the second and third examples, the code encrypts sensitive information before saving it to the filesystem.
|
||||
</p>
|
||||
<sample src="CleartextStorageSharedPrefs.java" />
|
||||
</example>
|
||||
|
||||
<references>
|
||||
<li>
|
||||
Android Developers:
|
||||
<a href="https://developer.android.com/topic/security/data">Work with data more securely</a>
|
||||
</li>
|
||||
<li>
|
||||
Android Developers:
|
||||
<a href="https://developer.android.com/reference/androidx/security/crypto/EncryptedFile">EncryptedFile</a>
|
||||
</li>
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* @name Cleartext storage of sensitive information in the Android filesystem
|
||||
* @description Cleartext Storage of Sensitive Information the Android filesystem
|
||||
* allows access for users with root privileges or unexpected exposure
|
||||
* from chained vulnerabilities.
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @precision medium
|
||||
* @id java/android/cleartext-storage-filesystem
|
||||
* @tags security
|
||||
* external/cwe/cwe-312
|
||||
*/
|
||||
|
||||
import java
|
||||
import semmle.code.java.security.CleartextStorageAndroidFilesystemQuery
|
||||
|
||||
from SensitiveSource data, LocalFileOpenCall s, Expr input, Expr store
|
||||
where
|
||||
input = s.getAnInput() and
|
||||
store = s.getAStore() and
|
||||
data.flowsToCached(input)
|
||||
select store, "Local file $@ containing $@ is stored $@. Data was added $@.", s, s.toString(), data,
|
||||
"sensitive data", store, "here", input, "here"
|
||||
Reference in New Issue
Block a user