news 2026/7/20 18:41:05

【Bug已解决】macOS detects Codex Computer Use.app as malware and deletes it! 解决方案

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【Bug已解决】macOS detects Codex Computer Use.app as malware and deletes it! 解决方案

【Bug已解决】macOS detects Codex Computer Use.app as malware and deletes it! 解决方案

原始报错:macOS detects Codex Computer Use.app as malware and deletes it! 场景:用户下载并打开Codex Computer Use.app,macOS 的 Gatekeeper / XProtect 把它判定为恶意软件,直接删除(或 quarantine 后阻止运行并提示"已移动至废纸篓")。应用根本起不来。 关键词:macOS 应用包、Gatekeeper、XProtect、代码签名、公证(notarization)、隔离属性(quarantine)、应用包结构。

一、现象长什么样

用户操作:

  1. 从网页/渠道拿到Codex Computer Use.app(一个.appbundle);
  2. 双击打开,macOS 弹出"无法打开,因为 Apple 无法检查其是否包含恶意软件",或直接由 XProtect 删掉;
  3. 应用消失在废纸篓,无法运行;
  4. codesign --verify检查发现签名无效或不完整,或根本没签名。

对最终用户来说,这就是"我的 Mac 把应用当病毒删了"。对开发者来说,根因几乎都在签名/公证链条不完整隔离属性没清掉

二、背景:macOS 怎么判定一个 .app 是否安全

macOS 对从网络下载的应用有多道防线,针对的是.appbundle 整体:

  • 代码签名(Code Signing).app/Contents/MacOS/里的可执行文件、框架、资源都要用开发者证书签名,且签名要覆盖整个 bundle(含Contents/_CodeSignature/CodeResources清单)。
  • 公证(Notarization):开发者把 app 上传 Apple 扫描,拿到"ticket",用xcrun stapler staple把 ticket 钉进 app。用户打开时 Gatekeeper 校验 ticket。
  • 隔离属性(quarantine):从浏览器下载的 app 会被打上com.apple.quarantine扩展属性,首次打开必经 Gatekeeper 检查。
  • XProtect:系统级恶意软件特征库,命中即删。

.appbundle 比单个 CLI 二进制复杂:它是一个目录树,签名必须递归覆盖每一层(可执行文件、dylib、嵌套 framework、资源),任何一层漏签或哈希不符,整个 bundle 的校验就失败。

三、根因:签名/公证链有缺口

根因拆解(针对 app bundle):

  1. 整体未签名或部分签名:只签了主可执行文件,没签嵌套的 dylib / framework,bundle 校验失败。
  2. 未公证:有签名但没上传 Apple 拿 ticket,Gatekeeper 在较新 macOS 上直接拦。
  3. quarantine 未清:用户用curl/浏览器下载后没清com.apple.quarantine,打开即触发检查。
  4. entitlements 不匹配:app 需要的权限(如屏幕录制、辅助功能,Computer Use 类应用常需)在签名时没声明,运行时被拒或特征异常引 XProtect 误判。
  5. 签名在打包后破损:签名后又改了 bundle 内文件(改 Info.plist、替换资源),签名失效。

下面用最小模型复现"带 quarantine 且签名无效导致校验失败",再给修复。

四、最小可运行复现(校验逻辑模拟)

用 Python 模拟"校验一个 app bundle":检查签名清单是否完整、是否带 quarantine。

import hashlib, os, json class AppBundleVerifier: def __init__(self, bundle_root): self.root = bundle_root def has_quarantine(self) -> bool: # 模拟读取 com.apple.quarantine 扩展属性 qp = os.path.join(self.root, ".quarantine") return os.path.exists(qp) def signature_intact(self, code_resources: dict, actual_files: list) -> bool: # code_resources 是签名时记录的哈希清单 for rel in actual_files: recorded = code_resources.get(rel) if recorded is None: return False # 清单没覆盖该文件 -> 签名不完整 live = hashlib.sha256( open(os.path.join(self.root, rel), "rb").read()).hexdigest()[:8] if live != recorded: return False # 哈希不符 -> 签名破损 return True if __name__ == "__main__": # 假设某文件不在签名清单里 verifier = AppBundleVerifier("/tmp/Codex.app") code_resources = {"Contents/MacOS/Codex": "abc123"} # 漏了嵌套 framework actual = ["Contents/MacOS/Codex", "Contents/Frameworks/Helper.framework/Helper"] print("签名完整?", verifier.signature_intact(code_resources, actual)) # False

运行输出False——嵌套 framework 没进签名清单,bundle 校验失败,这正是 Gatekeeper 拒绝/删除的根因之一。

五、方案:递归签名整个 app bundle

第一层:签名必须覆盖 bundle 内每一层。用codesign --deep --force --sign递归签所有可执行组件(真实命令,注释说明,不在 Python 内编造):

import subprocess, shlex def sign_app_bundle(bundle_path: str, identity: str) -> int: """递归签名整个 .app bundle。真实调用 codesign。""" cmd = [ "codesign", "--deep", "--force", "--sign", identity, bundle_path, ] print("执行:", shlex.join(cmd)) # 真实环境运行: return subprocess.call(cmd) def verify_app(bundle_path: str) -> int: """校验签名。真实调用 codesign --verify --verbose。""" cmd = ["codesign", "--verify", "--verbose=2", bundle_path] print("执行:", shlex.join(cmd)) return subprocess.call(cmd) if __name__ == "__main__": # 演示调用(不会真跑,需真实证书与 app) print("签名命令示例已生成;实际需有效的 Developer ID Application 证书") sign_app_bundle("/Applications/Codex Computer Use.app", "Developer ID Application: Acme") verify_app("/Applications/Codex Computer Use.app")

--deep保证嵌套的 framework / dylib 都被签,消除"清单漏项"。

六、方案:公证并 staple ticket

第二层:签名后上传 Apple 公证,拿到 ticket 钉进 app,让用户离线也能过 Gatekeeper:

def notarize_and_staple(bundle_path: str, keychain_profile: str) -> int: # 1) 上传公证 submit = [ "xcrun", "notarytool", "submit", bundle_path, "--keychain-profile", keychain_profile, "--wait", ] rc = subprocess.call(submit) if rc != 0: return rc # 2) 把 ticket 钉进 app(stapler) staple = ["xcrun", "stapler", "staple", bundle_path] return subprocess.call(staple) if __name__ == "__main__": print("公证流程:notarytool submit -> stapler staple") notarize_and_staple("/Applications/Codex Computer Use.app", "my-profile")

stapler 把 ticket 嵌入 app 内部,用户首次打开无需联网查 Apple,Gatekeeper 直接放行。

七、方案:清除隔离属性 + 校验 entitlements

第三层:分发时清掉 quarantine(或指导用户用xattr -dr清),并确保 entitlements 覆盖应用所需权限(Computer Use 类常需屏幕录制等):

def remove_quarantine(bundle_path: str) -> int: """清除 com.apple.quarantine 扩展属性。""" cmd = ["xattr", "-dr", "com.apple.quarantine", bundle_path] print("执行:", shlex.join(cmd)) return subprocess.call(cmd) def check_entitlements(bundle_path: str, required: list) -> list: """检查 app 的 entitlements 是否声明了所需权限。""" out = subprocess.run( ["codesign", "-d", "--entitlements", ":-", bundle_path], capture_output=True, text=True, ) missing = [e for e in required if e not in out.stdout] return missing if __name__ == "__main__": remove_quarantine("/Applications/Codex Computer Use.app") needed = [ "com.apple.security.cs.allow-jit", "com.apple.security.screen-capture", # 屏幕类应用常需 ] missing = check_entitlements("/Applications/Codex Computer Use.app", needed) print("缺失的 entitlements:", missing)

清 quarantine 让"首次打开"不再触发 Gatekeeper 拦;entitlements 检查确保运行时权限与签名一致,避免异常行为招来 XProtect 误判。

八、验证:本地校验脚本(交付前自检)

def self_check(bundle_path: str) -> dict: import os report = {} # 1. quarantine 应已清 report["quarantine_cleared"] = not os.path.exists( os.path.join(bundle_path, ".quarantine")) # 2. 签名可校验 report["signature_ok"] = (verify_app(bundle_path) == 0) # 3. entitlements 覆盖所需 report["entitlements_missing"] = check_entitlements( bundle_path, ["com.apple.security.screen-capture"]) return report if __name__ == "__main__": rep = self_check("/Applications/Codex Computer Use.app") print("交付前自检:", rep) # 全绿才发布:签名 ok + quarantine 清 + entitlements 齐

self_check放进发布流水线,签名/公证/entitlements 任一缺失都不发布,从源头杜绝"用户下载即被删"。

九、排查清单(".app 被当恶意软件删除"按顺序查)

  1. 签名完整性:bundle 内每一层(可执行、dylib、framework、资源)是否都签了?codesign -vvv是否通过?
  2. 公证:是否上传 Apple 拿到 ticket 并stapler staple?新 macOS 无 ticket 会被拦。
  3. quarantine:从网络下载后com.apple.quarantine是否清除?
  4. entitlements:应用所需权限(屏幕录制/辅助功能等)是否在签名时声明?
  5. 打包后改动:签名后是否又改过 bundle 内文件?改动会废掉签名。
  6. XProtect 误判:是否因行为异常(如缺权限导致古怪行为)触发特征库?补全 entitlements 通常缓解。
  7. 证书有效:用的 Developer ID 证书是否仍在有效期内、未被吊销?

十、小结

"macOS 把 .app 当恶意软件删除"是签名/公证/隔离属性链条有缺口导致的 Gatekeeper/XProtect 拦截。区别于单文件二进制,.app是目录树,签名必须递归覆盖每一层。修复三层:

  • 递归签名codesign --deep覆盖可执行、dylib、framework、资源,清单不漏项;
  • 公证 + staple:上传 Apple 拿 ticket 并钉进 app,离线可过 Gatekeeper;
  • 清 quarantine + 齐 entitlements:分发时清隔离属性,签名时声明应用所需权限。

核心原则:.app的安全校验看的是整个 bundle 的完整性,不是主可执行文件一个。递归签名、公证、正确的 entitlements,三者齐备,用户下载打开才不会被系统当成恶意软件删掉。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/20 18:39:55

鸿蒙Flutter Center与Align:组件对齐方式

作者:马振显(YM52e) 仓库地址:https://gitcode.com/feng8403000/FlutterfromBeginnertoAdvancedForHarmonyOS.git 联系邮箱:372699828qq.com 引言 在Flutter开发中,Center和Align是两个用于控制子组件对齐…

作者头像 李华
网站建设 2026/7/20 18:39:07

如何用Path of Building 2精准规划PoE2角色构建?3大核心功能深度解析

如何用Path of Building 2精准规划PoE2角色构建?3大核心功能深度解析 【免费下载链接】PathOfBuilding-PoE2 项目地址: https://gitcode.com/GitHub_Trending/pa/PathOfBuilding-PoE2 你是否曾花费数小时计算角色的伤害输出,却发现实际游戏中的表…

作者头像 李华
网站建设 2026/7/20 18:35:59

逆变器芯片失效分析与防护设计实践

1. 故障现象深度解析:小芯片失效引发的逆变器级联损坏当逆变器中的控制芯片发生击穿短路时,往往会导致灾难性的级联故障。具体到本次案例,故障发展路径非常典型:控制芯片首先因过压或过流发生物理性烧毁,其失效产生的异…

作者头像 李华
网站建设 2026/7/20 18:34:44

AI数据基础设施预计有1984亿规模?爱分析拆解七大细分市场构成

内容来源:《2026爱分析AI数据基础设施市场规模报告》 发布时间:2026年7 月 发布机构:爱分析ifenxi 关键词:AI数据基础设施、AI产业研究、七大细分市场、市场规模、本体平台、AI数据库、DataOps、多模态数据管理 摘要&#xff…

作者头像 李华
网站建设 2026/7/20 18:33:39

163MusicLyrics:跨平台云音乐歌词获取与处理工具的深度解析

163MusicLyrics:跨平台云音乐歌词获取与处理工具的深度解析 【免费下载链接】163MusicLyrics 云音乐歌词获取处理工具【网易云、QQ音乐】 项目地址: https://gitcode.com/GitHub_Trending/16/163MusicLyrics 163MusicLyrics是一款功能强大的跨平台云音乐歌词…

作者头像 李华
网站建设 2026/7/20 18:31:03

旧款Mac免费升级macOS终极指南:用OpenCore Legacy Patcher重获新生

旧款Mac免费升级macOS终极指南:用OpenCore Legacy Patcher重获新生 【免费下载链接】OpenCore-Legacy-Patcher Experience macOS just like before 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 你是否还在使用被苹果官方&quo…

作者头像 李华