Skip to main content

verifyos_cli/rules/
deprecated_api.rs

1use crate::rules::core::{
2    AppStoreRule, ArtifactContext, RuleCategory, RuleError, RuleReport, RuleStatus, Severity,
3};
4
5pub struct DeprecatedApiRule;
6
7impl AppStoreRule for DeprecatedApiRule {
8    fn id(&self) -> &'static str {
9        "RULE_DEPRECATED_API"
10    }
11
12    fn name(&self) -> &'static str {
13        "Deprecated API Usage"
14    }
15
16    fn category(&self) -> RuleCategory {
17        RuleCategory::Other
18    }
19
20    fn severity(&self) -> Severity {
21        Severity::Error
22    }
23
24    fn recommendation(&self) -> &'static str {
25        "Remove usages of deprecated APIs (e.g., UIWebView). Use WKWebView instead."
26    }
27
28    fn evaluate(&self, artifact: &ArtifactContext) -> Result<RuleReport, RuleError> {
29        let executable_path = match artifact.executable_path_for_bundle(artifact.app_bundle_path) {
30            Some(path) => path,
31            None => {
32                return Ok(RuleReport {
33                    status: RuleStatus::Skip,
34                    message: Some("No executable found in bundle".to_string()),
35                    evidence: None,
36                })
37            }
38        };
39
40        if !executable_path.exists() {
41            return Ok(RuleReport {
42                status: RuleStatus::Skip,
43                message: Some("Executable file not found".to_string()),
44                evidence: None,
45            });
46        }
47
48        let bytes = std::fs::read(&executable_path).map_err(|e| {
49            RuleError::MachO(crate::parsers::macho_parser::MachOError::ParseError(
50                Box::new(apple_codesign::AppleCodesignError::Io(e)),
51            ))
52        })?;
53
54        let target = b"UIWebView";
55        let found = bytes.windows(target.len()).any(|window| window == target);
56
57        if found {
58            return Ok(RuleReport {
59                status: RuleStatus::Fail,
60                message: Some("Deprecated API UIWebView detected in binary.".to_string()),
61                evidence: Some("Executable contains 'UIWebView'".to_string()),
62            });
63        }
64
65        Ok(RuleReport {
66            status: RuleStatus::Pass,
67            message: None,
68            evidence: None,
69        })
70    }
71}