实战攻防中的50条代码审计技巧!
在攻防实战中,代码审计已成为防御体系的核心支柱。一次严谨的审计可能阻止一次灾难性的数据泄露,一条被忽视的漏洞可能让企业付出千万代价。攻击者不会停止寻找代码中的弱点,而专业的审计正是最坚固的防线。
一、建立审计思维框架
- 1. 明确审计目标: 优先聚焦高危模块(用户认证、权限控制、支付流程、外部输入处理)及历史漏洞频发区域
- 2. 理解应用架构: 绘制数据流图,明确组件交互(前端、后端API、数据库、微服务、第三方服务)
- 3. 版本信息至关重要: 精确记录所有第三方库、框架、中间件版本,比对已知漏洞库(如NVD、CVE)
- 4. 配置即代码: 严格审查配置文件(安全头、CORS、数据库连接、调试开关、密钥存储)
- 5. “攻击者视角”切换: 思考“如何破坏此功能?”而非“它应如何工作?”
- 6. 追踪用户可控输入: 从源头(HTTP请求参数、头、文件、Cookie、API、存储)至最终使用点(Sink)
- 7. 识别信任边界: 明确系统内外部数据交换点,此处必须严格校验与过滤
- 8. 敏感操作日志审计: 关键操作(登录、删改、支付)须记录完整、不可篡改的审计日志
- 9. 逆向思维验证: 针对防御代码(如WAF规则),尝试构造绕过Payload
- 10. 利用自动化初筛: SAST工具(如Fortify、Checkmarx、SonarQube)定位风险点,但绝不替代人工深挖
二、输入处理:筑起第一道防线
- 11. 白名单优于黑名单: 定义明确允许的字符集、格式、长度,而非仅过滤已知危险字符
- 12. 规范化解码再校验: 输入需先统一解码(如URL解码、UTF-8)再进行白名单校验,防止编码绕过
- 13. 类型强制转换陷阱: PHP的==弱类型比较需警惕,0e123456可能被当作科学计数法0;Java等强类型语言也需注意Integer边界
- 14. 文件上传多维防御:
- • 后缀名检查(结合MIME类型、文件头魔数校验)
- • 存储路径隔离(无执行权限)
- • 随机重命名防覆盖
- • 病毒扫描
- • 禁用服务器解析特定扩展名(如.php.)
- 15. XML解析器加固:
- • 禁用外部实体(XXE防御:setFeature("http://apache.org/xml/features/disallow-doctype-decl", true))
- • 禁用DTD
- • 使用安全解析器(如defusedxml)
- 16. JSON解析安全配置: 禁用类型转换(如Jackson的enableDefaultTyping())、限制反序列化类(白名单)
- 17. 正则表达式拒绝服务(ReDoS): 避免复杂回溯正则匹配不可控输入
- 18. 路径遍历防御: 使用规范路径函数(realpath()),检查路径是否在预期目录内,避免拼接
- 19. 命令注入终极法则: 避免直接拼接命令!使用参数化API(ProcessBuilder/subprocess)或严格白名单过滤
- 20. SQL注入深度防御:
- • 首选参数化查询(PreparedStatement)
- • 存储过程需避免动态拼接SQL
- • ORM框架注意其是否最终生成安全SQL
- • 最小权限原则配置数据库用户
- 21. NoSQL注入不容忽视: 检查MongoDB查询是否使用$where执行字符串、不当的JSON查询解析
- 22. 模版注入(SSTI)检测: 观察用户输入是否进入模版引擎(如Jinja2、Freemarker、Thymeleaf)的解析过程
- 23. HTTP头注入: 检查Location、Set-Cookie等头是否包含未过滤用户输入
- 24. 邮件头注入(CRLF): 过滤\r、\n,使用库安全构建邮件
- 25. 批量分配风险(Mass Assignment): 框架(如Spring MVC、Laravel、Rails)需显式定义允许绑定的模型属性(白名单)
三、核心安全机制:认证、会话、权限
- 26. 密码存储验证: 强哈希算法(Argon2、scrypt、bcrypt、PBKDF2)+ 随机盐,禁止MD5/SHA1
- 27. 认证流程完整性: 登录、登出、注册、密码重置各环节是否存在逻辑缺陷(如跳过验证)
- 28. 多因素认证(MFA)后端校验: MFA状态需在服务器端会话中强绑定并验证
- 29. 会话管理关键点:
- • 会话ID足够长且随机
- • Cookie设置HttpOnly、Secure、SameSite属性
- • 登录成功后更新会话ID(防会话固定)
- • 会话超时机制
- 30. 权限控制三原则:
- • 默认拒绝
- • 最小权限
- • 服务端执行(前端展示控制非安全边界)
- 31. 垂直越权检测: 普通用户能否访问仅管理员可见的功能/数据?检查每个功能入口的权限校验
- 32. 水平越权检测: 用户A能否操作(查看/修改/删除)用户B的数据?检查数据访问是否关联当前用户ID
- 33. 直接对象引用(IDOR)防御: 使用不可预测的引用(如GUID),或访问时校验数据归属
- 34. 功能级权限缺失: 后台管理URL是否可直接访问?API路由是否都配置了权限拦截器?
- 35. JWT安全配置:
- • 验证签名算法(防止alg: none攻击)
- • 校验iss(签发者)、aud(受众)、exp(过期时间)
- • 敏感数据不放在Token中
- • 密钥(Secret)强度与保护
四、输出处理与客户端安全
- 36. 上下文感知的编码:
- • HTML正文:HtmlEncode
- • HTML属性:AttributeEncode
- • JavaScript:JavaScriptEncode
- • URL参数:URLEncode
- • CSS:CSSEncode
- 37. 警惕innerHTML: 避免直接设置innerHTML,使用安全的文本节点操作或经过验证的安全HTML净化库(如DOMPurify)
- 38. CSP策略部署: 内容安全策略有效缓解XSS,配置default-src、script-src(禁用'unsafe-inline')、object-src 'none'等
- 39. XSS过滤器的误区: 浏览器内置或WAF过滤器可能被绕过,不能替代安全的输出编码
- 40. 点击劫持防御: 设置HTTP头X-Frame-Options: DENY或SAMEORIGIN,或使用CSP的frame-ancestors指令
- 41. CSRF Token机制验证:
- • Token需足够随机
- • 绑定用户会话
- • 关键操作强制验证(GET请求不应改变状态)
- • 检查Token存储位置(Cookie需配合自定义Header)
- 42. 安全重定向: 重定向目标需校验白名单或固定前缀,避免开放重定向漏洞
- 43. 错误信息泄露: 生产环境禁用详细栈跟踪、数据库错误信息,返回统一错误页面
- 44. CORS配置风险: 避免使用Access-Control-Allow-Origin: *处理敏感数据或操作,精确指定允许的来源域
- 45. 第三方脚本风险: 评估引入的外部JS库安全性,考虑子资源完整性(SRI)
五、纵深防御:加密、配置、依赖与逻辑
- 46. 加密算法与模式选择:
- • 对称加密:AES(128/256位)+ GCM模式(认证加密)
- • 非对称加密:RSA(2048+)/ECC
- • 避免:DES、RC4、ECB模式
- • 密钥管理:使用HSM或KMS,禁止硬编码
- 47. 配置敏感信息保护: 密码、API密钥、加密密钥等严禁硬编码在源码或配置文件中,使用环境变量或专用密钥管理服务
- 48. 依赖组件安全(SCA):
- • 持续监控依赖库漏洞(OWASP Dependency-Check、Snyk)
- • 及时升级修复版本
- • 移除未使用的依赖
- • 审核依赖的许可证
- 49. 业务逻辑漏洞深挖:
- • 并发竞争条件(如余额检查与扣款分离导致超买)
- • 负值处理(金额、数量)
- • 越界操作(如ID最大值、负数索引)
- • 工作流程绕过(跳过关键步骤)
- 50. 安全开发流程闭环: 将代码审计发现的问题系统化反馈至开发团队,推动安全编码规范、安全培训、SDL流程完善,建立安全左移机制
代码审计并非一蹴而就的任务,而是渗透于软件生命周期每个环节的持续性实践。
文章来源:HACK之道
华盟君