Complete Android parity and security audit (#111)
Android ARM verification / rust (push) Failing after 50m14s
Android ARM verification / android (push) Failing after 8s
Dependency security audit / rustsec (push) Failing after 23s

This commit is contained in:
hugo committed 2026-10-15 13:40:50 +02:00
1 parent 45d78aa5b3
commit b54636b7bc
14 files changed
+498 -75

No files matched your search

+56
View File
@@ -30,6 +30,33 @@ pub fn manifest(manifest: &Path, backup: &Path, extraction: &Path) -> Result<(),
Ok(())
}
pub fn release_manifest(path: &Path) -> Result<(), Box<dyn Error>> {
release_manifest_text(&fs::read_to_string(path)?)?;
println!("Verified release cannot be debugged, profiled or installed as test-only");
Ok(())
}
fn release_manifest_text(source: &str) -> Result<(), Box<dyn Error>> {
let document = Document::parse(source)?;
let application = document
.root_element()
.children()
.find(|node| node.has_tag_name("application"))
.ok_or("application missing")?;
for name in ["debuggable", "testOnly"] {
if !matches!(application.attribute((ANDROID, name)), None | Some("false")) {
return Err(format!("unsafe release application flag: {name}").into());
}
}
if application
.children()
.any(|node| node.has_tag_name("profileable"))
{
return Err("profiling is restricted to benchmark/profile builds".into());
}
Ok(())
}
fn manifest_text(source: &str) -> Result<(), Box<dyn Error>> {
let document = Document::parse(source)?;
let root = document.root_element();
@@ -489,6 +516,35 @@ fn android_license<'a>(
mod tests {
use super::*;
#[test]
fn release_rejects_debug_test_and_profile_access() {
let source = format!(r#"<manifest xmlns:android="{ANDROID}"><application/></manifest>"#);
assert!(release_manifest_text(&source).is_ok());
for flag in ["debuggable", "testOnly"] {
assert!(
release_manifest_text(&source.replace(
"<application/>",
&format!(r#"<application android:{flag}="false"/>"#)
))
.is_ok()
);
assert!(
release_manifest_text(&source.replace(
"<application/>",
&format!(r#"<application android:{flag}="true"/>"#)
))
.is_err()
);
}
assert!(
release_manifest_text(&source.replace(
"<application/>",
r#"<application><profileable android:shell="true"/></application>"#
))
.is_err()
);
assert!(release_manifest_text("<manifest/>").is_err());
}
#[test]
fn manifest_rejects_backup_permissions_and_exports() {
let source = format!(
r#"<manifest xmlns:android="{ANDROID}" package="de.rfc1437.ironstorage"><application android:allowBackup="false" android:usesCleartextTraffic="false" android:fullBackupContent="@xml/backup_rules" android:dataExtractionRules="@xml/data_extraction_rules"><activity android:name="de.rfc1437.ironstorage.MainActivity" android:exported="true"><intent-filter><action android:name="android.intent.action.MAIN"/><category android:name="android.intent.category.LAUNCHER"/></intent-filter></activity><provider android:name="fixture" android:exported="false"/></application></manifest>"#
+4 -1
View File
@@ -52,6 +52,9 @@ fn main() -> Result<(), Box<dyn Error>> {
[_, command, directory] if command == "audit-native" => {
native::audit_directory(Path::new(directory))?
}
[_, command, manifest] if command == "audit-release-manifest" => {
gates::release_manifest(Path::new(manifest))?;
}
[_, command, manifest, backup, extraction] if command == "audit-manifest" => {
gates::manifest(
Path::new(manifest),
@@ -85,7 +88,7 @@ fn main() -> Result<(), Box<dyn Error>> {
}
_ => {
return Err(
"usage: ironstorage-android-build <fixtures output.kt | check android-dir | prepare-bindings input output | package-native input output | audit-elf path abi | audit-native jniLibs | audit-apk-split apk abi | audit-package apk-or-aab | audit-release apk symbols | audit-manifest manifest.xml backup.xml extraction.xml | sbom android.json rust.txt Cargo.lock policy.json output.json | safe-reports input-dir output.json | check-toolchain cargo rust ndk ndk-version cargo-ndk-version>".into(),
"usage: ironstorage-android-build <fixtures output.kt | check android-dir | prepare-bindings input output | package-native input output | audit-elf path abi | audit-native jniLibs | audit-apk-split apk abi | audit-package apk-or-aab | audit-release apk symbols | audit-release-manifest manifest.xml | audit-manifest manifest.xml backup.xml extraction.xml | sbom android.json rust.txt Cargo.lock policy.json output.json | safe-reports input-dir output.json | check-toolchain cargo rust ndk ndk-version cargo-ndk-version>".into(),
);
}
}