Havenlon|安全讲人话(十):软件不能永远管住软件

Havenlon|安全讲人话(十):软件不能永远管住软件
当判断、审批和执行都在同一个软件世界里攻击者只需要攻破一个世界。先讲两件真事它们从两个方向说明了同一个问题。第一件2023 年 10 月的 Okta 事件。Okta 是全球无数企业的身份中枢——员工登录、权限校验、单点登录都靠它。攻击者并没有去逐个攻破 Okta 那些下游客户他们只做了一件事拿到了 Okta 客户支持系统里一个服务账号的凭证起因是一名员工把特权凭证存进了个人 Google 账户。就凭这一个点攻击者拿到了客户上传的会话令牌进而劫持了下游客户的合法会话——受害者里包括 1Password、Cloudflare 这样本身安全能力极强的公司。攻破一个身份控制面风险就顺着同一个世界级联到了成千上万个下游系统。第二件Stuxnet震网2009–2010。伊朗的核设施是物理隔离air-gap的不连公网。攻击者用 U 盘把蠕虫送进去精准识别西门子的工控软件和 PLC悄悄篡改离心机转速最终物理性地摧毁了约 1000 台离心机。而最阴森的一点是在离心机被一点点毁掉的同时PLC 向监控电脑报告一切正常。因为执行层和监控层活在同一个被攻陷的世界里系统在对自己撒谎。一件讲控制面一破、全线级联一件讲执行和监控同域、系统自欺。它们共同指向本篇的主题软件不能保护软件不是说软件没用而是说——软件不能永远只靠自己来证明自己没有被污染。这句话很容易被误解仿佛在否定密码学、权限系统、审批流、策略引擎、日志审计和云端治理。显然不是。现代企业离不开软件绝大多数安全能力也必须靠软件实现。真正的问题只有一个当所有判断、审批、策略和执行都位于同一个信任域时它们是否真的彼此独立一、层数很多不代表边界很多一个复杂系统通常有很多模块用户登录 → 身份系统校验权限 → 业务后台生成请求 → 策略引擎判断风险 → 审批系统多人确认 → 执行服务再次检查 → 日志平台记录全过程。架构图上这像是一层又一层防线。但真正该问的是——这些系统是否运行在相互独立的信任环境里它们是否依赖同一套云端账号是否共享同一套管理员权限是否由同一个控制面配置是否能被同一个后台远程更新是否最终都依赖同一个执行服务如果答案大多是是那么这些模块虽然功能不同却不一定构成真正独立的边界。它们更像同一栋楼里的不同房间门很多墙也很多但总电源、总钥匙、消防控制都在同一个地方。攻击者不必逐扇开门他只要控制总控室就能让整栋楼按他的意图运行。安全工程对此有一个精确的词叫共担命运shared fate / 相关性失效 correlated failure处于同一信任域的层会一起失效。真正的纵深防御Defense in Depth要求的是独立的失效域而很多系统的多层只是同一个世界里的多层界面。Okta 事件就是活生生的例子——那么多下游公司各有各的安全体系却共担了信任同一个身份控制面这一个命运。二、软件安全最容易高估逻辑独立软件极擅长制造逻辑上的分层服务 A 管身份服务 B 管审批服务 C 管策略服务 D 管执行各有各的接口、代码仓库、团队甚至部署在不同服务器上。这些分离确实能提高工程质量、减少普通故障的传播。但——逻辑独立和信任独立不是一回事。如果这些服务最终都受同一个云端控制面管理、都能被同一组管理员修改、都依赖同一条软件更新链、都跑在同一种可远程控制的环境里那么它们的最终命运仍可能被同一个主体改变控制了最高权限账号 → 可以修改策略控制了部署系统 → 可以替换执行代码控制了审批页面 → 可以改变人看到的内容控制了执行服务 → 可以让真实参数与审批参数不一致控制了日志系统 → 可以掩盖已经发生的变化。于是原本看起来相互制衡的多个软件层会在同一次高权限失陷中被一起重新解释。这在攻防里叫控制面攻陷control plane compromise——不打数据直接打那个能定义规则的地方。所以安全设计不能只看有几层还要看这些层是否真的不能被同一方同时改写。三、同一个软件世界最危险的不是没有规则而是规则也能被改传统安全大量依赖规则金额超阈值要多人审批、陌生地址禁止执行、非工作时间提高风险等级、生产变更必须额外确认、AI Agent 只能调白名单工具。这些规则都重要。但如果负责执行的人也能修改规则那规则本身就未必是最终边界。攻击者拿到管理员权限后往往不需要绕过系统他可以先合法地改配置调高高风险阈值 → 大额不再触发审批 把陌生地址加白名单 → 收款方合规了 多人审批改单人 → 自己就能批 危险工具进允许列表 → AI 可以调它了 异常时间标记为正常 → 风控不再告警 ────────────────────────────────── 最后走一条完全合规的流程完成执行从日志上看系统甚至没有发生明显绕过——所有动作都符合当时的配置。问题在于配置本身已经被攻击者重新定义了。只要规则、解释规则的人、执行规则的系统处于同一个可修改环境里安全就仍然依赖那个环境永远可信。而现实里没有任何大型软件环境配得上这种绝对假设。四、审批也可能只是同一个软件世界里的另一种表达很多系统把多人审批当作软件失陷后的最后防线即使某个业务服务被攻击只要审批人没同意动作就不执行。这个思路在一定条件下有效。但问题在于——审批人看到的内容通常也由软件生成。页面由软件渲染摘要由软件整理参数由软件读取审批状态由软件保存通过后的触发动作仍由软件完成。如果同一个攻击面能同时影响展示给人看的内容和最终交给机器执行的内容那么审批就会变成一个表面独立、实际受控的环节审批人看到的是 A系统记录他批准了 A最后执行的却是 B这正是前面几篇讲的 Bybit、地址投毒的共同形状。或者更隐蔽——摘要没有明显错误但省略了决定风险的关键字段人在真实、合法的情况下点了同意软件也真实记录了这个动作可整个审批仍然建立在一个被操纵的表达层上。这时问题不是审批人失职也不是审批流程不存在而是——展示、解释和执行都由同一个软件世界控制审批从没真正离开那个信任域。五、日志不能成为最后的独立性证明很多企业靠日志建立信任即使出问题事后总能靠日志还原谁做了什么。日志确实重要没有它组织没法审计和复盘。但日志通常仍由被记录的那个系统自己生成。攻击者权限足够高时可以关闭日志、删除日志、延迟上报、修改时间、只记录对自己有利的字段、让展示层和执行层产生不同记录。回想 Stuxnet 最恐怖的细节离心机在被摧毁PLC 却报告一切正常。执行层和监控层在同一个被攻陷的域里日志可以全部真实却系统性地说谎。更常见的情况是日志确实全真但它只能证明某账号在某时刻点了某按钮某服务随后执行了一条请求它证明不了这两件事之间没有发生语义替换。所以日志是证据的一部分却替代不了独立边界。一个只有事后说明能力、没有事前阻断能力的系统更像监控摄像头而不是门闩。第三篇讲过不可否认性 ≠ 可阻止性。六、为什么需要物理边界这里必须说句公道话物理边界不等于硬件天然正确硬件里也跑着固件也需要协议、更新和配置。把硬件说成绝对可信同样不现实——SGX 这类可信执行环境TEE出现过侧信道漏洞HSM 也被发现过缺陷。所以物理边界的价值从来不是硬件不会错。它真正的价值只有一句它能让最终执行不再完全服从原来那个软件控制面。也就是说即使业务系统、AI Agent、云端 SaaS、审批页面和普通管理员都在同一个软件世界里最后仍然存在一个不同的执行域对这些上游请求做独立约束。这个域可能用独立设备、独立密钥、独立通信路径、独立本地状态、独立策略收敛、独立的最终签名或执行能力。重点不是它是一块硬件而是——上游软件不能在一次远程失陷中同时改写它的判断、它的状态、它的最终执行。用第一节的话说它必须是一个独立的失效域。当攻击者被迫要跨越两个不同的信任域攻击难度和灾难半径就都变了。七、硬件的价值不是更聪明而是更难被一起说服一个独立执行边界不需要比云端更聪明。它不需要理解全部业务不需要跑最复杂的 AI也不需要成为组织的大脑。恰恰相反它应该尽量克制。分工可以很清楚云端理解业务背景AI 分析自然语言审批人判断例外业务系统组织流程而独立边界只守少量关键事实——最终对象是谁金额和参数是什么当前本地状态是否允许治理条件是否满足关键内容是否与原始意图一致是否存在冲突或不确定它的价值不在于知道得更多而在于不容易和上游一起失陷。当所有软件系统都说可以它仍然有能力根据自己的约束说不。这就是独立裁决层真正的意义。这其实又回到了第七篇的引用监视器和第九篇的拜占庭容错——系统的安全不该建立在每一层都不被攻破上而该建立在至少有一个域不会和其它域一起沦陷上。八、物理边界不能只是软件流程的外壳当然不是所有带硬件的系统都构成真正的物理边界。如果设备只是接收云端给的最终结果、然后机械执行那它只是远程软件的一个外设如果云端可以修改全部本地规则、远程关闭检查、强制进入放行模式那硬件只是让指令多走了一步如果管理员能通过后台重置设备、替换状态并立即执行那最终权力根本没离开原来的控制面。所以判断一个硬件边界真不真不能只看有没有芯片、有没有安全元件、有没有独立盒子而要看这几条它能不能拒绝上游它的拒绝能不能被同一个远程系统取消第八篇无远程后门关键状态是否独立保存最终执行是否必须穿过它第七篇完全仲裁、不可绕过是否存在绕过它的其它执行路径设备失联或状态不确定时是收缩能力还是自动开放第八篇Fail-Secure这些条件决定了硬件究竟是一道门闩还是一颗更昂贵的确认按钮。九、物理隔离不是为了消灭软件而是为了限制软件权力软件仍然该承担大量工作——它更适合快速迭代、处理复杂业务、与用户交互、组织审批协同策略分析。物理边界不是要把软件赶出系统它的目的是让软件不再同时拥有所有权力。软件可以建议、可以发起、可以审批、可以协调、可以记录但不应该仅凭自己内部的一致结论就直接定义现实已经允许发生。这其实和现实组织的职责分离是同一种智慧财务系统能生成付款申请但不能直接决定银行账户里的钱一定转出运营能提出生产变更但不能因为工单通过就绕过所有现场约束董事会能定战略但某些重大执行仍需独立程序。不是因为前面的角色没价值而是因为任何一个角色都不该同时握有提议 判断 不可逆执行的全部能力。十、独立边界解决的不是永不出错而是不要一起出错没有任何系统能保证永远安全。硬件会故障固件会有漏洞本地策略会配错通信会中断。物理边界不是魔法它真正改善的是失效模式failure mode。当所有机制都在同一个软件世界里一次高权限失陷可能让所有层同时失效共担命运。当最终执行被拆到独立边界后攻击者即使控制了上游仍要面对另一个不同的约束域。┌───────────── 同一个软件世界共担命运─────────────┐ │ 身份 → 审批 → 策略 → 执行 → 日志 │ 一次攻陷 │ 同一控制面 / 同一批管理员 / 同一条更新链 │ ── 全部失效 └──────────────────────────────────────────────────────┘ ​ ┌────── 软件世界 ──────┐ ┌──── 独立执行域 ────┐ │ 身份·审批·策略·日志 │ 请求 │ 门闩 / 裁决层 │ 攻陷上游 │ 可被远程改写 │ ────▶ │ 不被同一次失陷带走│ ── ≠ 攻陷这里 └──────────────────────┘ └────────────────────┘这不意味着攻击绝不可能成功而意味着攻击不能再轻易通过一个控制面接管整条链。安全系统真正需要的不一定是每一层永远正确而是当某一层出错时其他层不要和它一起出错。这就是分层不信任的核心。十一、物理边界尤其适合守住不可逆动作不是所有软件动作都需要物理边界。改一段草稿、发一条低风险通知、重新生成一份报告——这些通常可撤销、可重试。如果什么都要独立硬件参与系统会笨重到不可用。真正适合独立执行边界的是那些一旦发生就难以逆转、灾难半径大的动作高价值资产转移、关键权限提升、敏感数据大规模导出、生产环境核心配置变更、物理设备控制、AI Agent 对真实账户/基础设施/外部系统的高风险调用。它们的共同点是——事后补救成本极高。Stuxnet 毁掉的离心机换不回来一笔链上转账追不回来一次大规模数据外泄收不回来。正因为不能把所有事都塞进物理边界系统才更需要识别关键路径第七篇海狸只守水真正冲出去的地方。物理边界不是为了控制全部软件活动而是为了守住软件判断真正变成现实后果的那几个位置。十二、软件不能永远管住软件这句话真正想说的不是软件无用而是——软件不能永远只依赖自己来证明自己没有被污染。当业务请求、AI 判断、审批页面、策略配置、管理员权限、最终执行和事后日志都位于同一个可远程修改的信任域里系统看起来可能有很多层实际上仍然缺少一个真正独立的最后裁决。攻击者不需要逐层战胜所有机制他只需要进入那个能够重新定义所有机制的软件世界——Okta 事件是这么级联的Stuxnet 是这么自欺的。物理边界的价值就是把最终执行从这个世界里拆出一部分不是为了否定软件而是为了限制软件的最终权力不是为了寻找绝对可信的硬件而是为了避免所有安全机制在一次软件失陷中同时倒下。Havenlon 强调的从来不是硬件比软件更高贵而是一个更朴素的工程判断当判断、审批和执行都在同一个世界里所谓的多层安全可能只是同一个世界里的多层界面。真正的边界必须让最后那个动作不能仅凭这个世界自己的结论就发生。因为一套系统是否安全不只取决于它有多少规则、多少审批、多少日志。更取决于一个终极问题当整个软件世界都被说服时是否还有一个不属于它的地方能够拒绝。这是《Havenlon安全讲人话》系列的第十篇。接下来两篇我们分别看清这道独立边界的两半为什么云端 SaaS 可以协同治理、却不该成为最终裁判下一篇以及硬件到底扮演什么角色——不是为了更高级而是为了更难被绕过。参考来源本文引用的真实事件与技术概念Unauthorized Access to Oktas Support Case Management System: Root Cause — Okta SecurityHackers Stole Access Tokens from Oktas Support Unit — Krebs on SecurityStuxnet explained: The first known cyberweapon — CSO OnlineStuxnet — Wikipedia