verifyos_cli/rules/
deprecated_api.rs1use 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}