run method
Executes the audit.
Implementation
@override
Future<AuditResult> run(ProjectContext context) async {
final issues = <SecurityIssue>[];
final manifest = await AndroidManifestHelper.load(context);
if (manifest == null) {
return AuditResult(issues: issues);
}
final applications = manifest.findAllElements('application');
if (applications.isEmpty) {
return AuditResult(issues: issues);
}
final application = applications.first;
final allowBackup = application.getAttribute(
'allowBackup',
namespace: _androidNamespace,
);
final fullBackupContent = application.getAttribute(
'fullBackupContent',
namespace: _androidNamespace,
);
final dataExtractionRules = application.getAttribute(
'dataExtractionRules',
namespace: _androidNamespace,
);
if (allowBackup == 'false') {
return AuditResult(issues: issues);
}
if (fullBackupContent == null) {
issues.add(
SecurityIssue(
id: 'android.backup_rules.missing_full_backup_content',
severity: Severity.medium,
title: 'Missing Backup Rules',
description:
'Backups are enabled but no fullBackupContent configuration is specified.',
recommendation:
'Specify android:fullBackupContent or disable backups if not required.',
file: context.androidManifest.path,
),
);
} else {
_validateXmlReference(
context: context,
reference: fullBackupContent,
issueId: 'android.backup_rules.missing_backup_rules_file',
title: 'Missing Backup Rules File',
issues: issues,
);
}
if (dataExtractionRules != null) {
_validateXmlReference(
context: context,
reference: dataExtractionRules,
issueId: 'android.backup_rules.missing_data_extraction_rules',
title: 'Missing Data Extraction Rules',
issues: issues,
);
}
return AuditResult(issues: issues);
}