软件项目开发全流程 · 第 32 课 · 安全与合规维护
1、上线不是终点,安全是持续的过程
第 23 课我们讲过"性能与安全测试",但那是上线前的一次性检查。上线之后呢?
现实是:
- 你依赖的某个库,今天被爆出一个高危漏洞;
- 某个攻击手法(比如某类注入)三年前还没人用,现在已成常规武器;
- 法规更新了,你的数据处理方式忽然不合规了。
安全不是一个"做完就勾掉"的任务,而是一项需要长期维护的能力。
很多团队把安全当"上线前跑一次扫描",结果系统上线半年,依赖里躺着一堆已知 CVE(公开漏洞编号)。本课要讲清:系统进入维护期后,安全与合规该怎么持续做。
2、补丁与依赖管理:你 90% 的代码不是你写的
现代软件的真相:
你的项目里,自己写的代码可能只占 10%,其余 90% 是第三方依赖。
一个普通 Node.py 项目,node_modules 动辄几万个文件。这意味着:你的安全边界,等于所有依赖安全的总和。 一颗依赖的"地雷",能炸掉整个系统。
危险从哪来:
| 风险 | 说明 |
|---|---|
| 已知漏洞 | 依赖被公开了 CVE,攻击者按编号打 |
| 停止维护 | 作者弃坑,漏洞无人修("僵尸依赖") |
| 恶意投毒 | 包被劫持,更新里塞后门(供应链攻击) |
| 过度依赖 | 为了一个小功能引入几百 KB 的库,攻击面膨胀 |
补丁(Patch)管理的纪律:
- 定期扫描:用工具(
npm audit、pip-audit、Dependabot、Snyk 等)扫描依赖漏洞。 - 分级修复:高危/严重漏洞立即修;低危排入常规版本(呼应第 31 课"排期")。
- 自动更新:让机器人提 PR(如 Dependabot),人工评审合并——别让升级攒成大工程。
- 锁定版本:提交 lock 文件(
package-lock.json/poetry.lock),保证构建可复现(呼应第 24 课)。
💡 升级依赖是"预防性维护"(第 29 课)。平时小步升级,成本很低;攒到不可收拾再升,就是一场灾难。
3、供应链安全:SBOM 与依赖漏洞扫描
近几年最响的安全事件,多不是"系统被攻破",而是供应链被投毒——你没写错代码,但依赖里藏了坏东西。
防御的核心抓手是 SBOM(Software Bill of Materials,软件物料清单):
一份列出你软件里所有组件及其版本的"配料表"。
有了 SBOM,当某个组件爆出漏洞(比如日志库、加密库),你能秒级回答:"我们哪些产品用了它?用在哪?"——而不是翻遍所有仓库干着急。
落地建议:
- 用工具自动生成 SBOM(如 Syft、CycloneDX 格式)。
- 每次构建都生成并归档,随制品一起保存。
- 收到 CVE 通报时,用 SBOM 反查影响面。
供应链安全的另外两条纪律:
- 最小权限:CI 的令牌、部署密钥只给必需的权限范围。
- 锁定可信源:只从官方仓库拉依赖,校验哈希/签名,防止中间人篡改。
4、许可证合规:开源 ≠ 免费随便用
开源代码可以免费"用",但不代表可以随便"商用、闭源、再发布"。每个开源项目都附带一份许可证(License),它规定了你能做什么、不能做什么。
常见许可证速览(务必理解差异):
| 许可证 | 类型 | 商用 | 修改后必须开源? | 一句话 |
|---|---|---|---|---|
| MIT / Apache-2.0 | 宽松 | ✅ | ❌ | 随便用,保留版权声明即可 |
| BSD | 宽松 | ✅ | ❌ | 类似 MIT |
| LGPL | 弱 copyleft | ✅ | 部分 | 动态链接通常可闭源 |
| GPL / AGPL | 强 copyleft | ✅ | ✅ 必须 | 传染性强,闭源产品慎用 |
| 商业许可 | 专有 | 需付费 | — | 看清楚条款 |
合规红线:
把 GPL/AGPL 代码混进闭源商业产品,是重大法律风险。
怎么做:
- 扫描许可证:用工具(如
license-checker、FOSSA、ScanCode)列出所有依赖的许可证。 - 建立白名单:明确哪些许可证允许、哪些禁止、哪些需法务审批。
- 保留声明:宽松许可证也要求保留版权和许可声明,别删人家的 LICENSE 文件。
- CI 卡点:在流水线里自动检查,引入"黑名单许可证"直接失败。
5、数据隐私与合规:用户的数据不是你的资产
现代社会,软件处理的用户数据受法律严格约束。中国的《个人信息保护法》(个保法)、欧盟的 GDPR,都是硬性要求。核心原则其实很朴素:
| 原则 | 含义 |
|---|---|
| 最小必要 | 只收集业务真正需要的数据,别"顺手都存了" |
| 目的限定 | 收集的数据只能用于当初告知的目的 |
| 用户知情 | 说清楚收集什么、怎么用,获得同意 |
| 可删除 | 用户有权要求删除其数据("被遗忘权") |
| 安全保障 | 存储、传输要加密,访问要有控制 |
| 可携带 | 用户能导出自己的数据 |
工程上对应的能力:
- 数据加密:传输用 TLS,敏感字段存储加密(如身份证、手机号)。
- 脱敏与最小化:日志里不打完整手机号/密码/卡号。
- 删除与导出接口:为"用户注销"和"数据导出"做好实现(这是合规硬性要求,不是可选项)。
- 数据留存策略:定好数据保存多久,到期自动清理。
⚠️ 合规不是"法务的事"。很多要求(能删除、能导出、要加密)必须由工程实现。开发团队是合规的第一责任人。
6、访问控制与审计日志
安全和隐私,最终都落到一个问题上:谁能访问什么,以及有没有留下痕迹?
访问控制的关键实践:
- 最小权限原则:每个账号/服务只给完成工作所必需的权限。
- 定期清理:离职员工账号、废弃的服务密钥,必须及时回收("幽灵账号"是重灾区)。
- 多因素认证(MFA):管理后台、服务器、数据库,务必开启。
- 密钥管理:密钥不写死在代码里,用密钥管理服务(KMS)/环境变量注入(呼应第 13 课
.gitignore)。
审计日志(Audit Log):记录"谁、在什么时间、做了什么敏感操作"。
- 记录:登录、权限变更、数据导出/删除、配置修改。
- 保护:审计日志本身不可篡改,且要异地留存(防内部作案后删日志)。
- 用途:出了问题能溯源、能定责、能证明合规。
"没有日志"等于"安全裸奔"。 出事后你连"被谁、从哪进去的"都说不清。
7、安全事件响应
再严密的防御也可能被攻破。关键是被攻破之后怎么办——这跟第 28 课的"事故响应与复盘"是同一套机制,只是多了安全维度:
- 发现:监控告警、外部报告、漏洞披露。
- 遏制:先止血——断掉入口、禁用被泄密钥、隔离受影响系统。
- 根除:定位并修复漏洞,清除后门。
- 恢复:从可信备份恢复数据与服务。
- 通报:涉及用户数据泄露的,法律有强制通报时限,必须及时告知用户和监管。
- 复盘:无指责复盘,改进流程(呼应第 28 课)。
预先准备好安全事件响应预案(谁负责、怎么联系、怎么上报),比事发时手忙脚乱强一百倍。
8、常见误区
- "小项目没人攻击,不用管安全":自动化扫描机器人遍历全网,没有"太小而不被攻击"的系统。
- "依赖多所以漏洞多,是正常成本":这是懒,不是命。定期升级 + 扫描能消掉 90% 风险。
- "开源随便用,反正不要钱":忽视许可证,可能埋下法律炸弹(尤其 GPL 传染)。
- "合规等客户要求了再说":法规要求是上线即适用的,等被投诉就晚了。
- "安全是安全团队的职责":安全要"左移"——每个开发者都是安全的第一道防线。
9、动手实验 🎯
任务:给「Team Todo」做一次"安全与合规体检"。
- 依赖扫描:在你项目的语言生态里跑一次依赖漏洞扫描(如
npm audit/pip-audit),记下高危项和处理计划。 - 生成 SBOM:用工具或手工列出一份依赖清单(组件名 + 版本 + 用途),保存到仓库。
- 许可证盘点:列出你的直接依赖各自的许可证,标出是否有"传染性"(GPL/AGPL)。
合规三问:检查你的项目是否具备——
- (a) 用户数据删除能力;
- (b) 用户数据导出能力;
- (c) 敏感字段加密存储。
缺哪条,写出补做方案。
- 审计日志审查:列出你认为必须记录审计日志的 5 个操作(如"删除全部任务""导出用户数据")。
- 响应预案:写一页《安全事件响应卡》:发现→遏制→根除→恢复→通报,各步谁负责。
10、今天你带走的三句话
- 你的安全性 = 所有依赖安全性的交集;定期盘查依赖、生成 SBOM,是维护期的基本功。
- 开源免费 ≠ 随便用;许可证(尤其 GPL/AGPL)的合规红线,必须写进 CI 卡点。
- 合规和审计不是法务的事,是工程能力——能删除、能导出、能加密、有日志,才算真正合规。