实战攻防中的50条代码审计技巧!

华盟原创文章投稿奖励计划

在攻防实战中,代码审计已成为防御体系的核心支柱。一次严谨的审计可能阻止一次灾难性的数据泄露,一条被忽视的漏洞可能让企业付出千万代价。攻击者不会停止寻找代码中的弱点,而专业的审计正是最坚固的防线。

一、建立审计思维框架

  1. 1. 明确审计目标: 优先聚焦高危模块(用户认证、权限控制、支付流程、外部输入处理)及历史漏洞频发区域
  2. 2. 理解应用架构: 绘制数据流图,明确组件交互(前端、后端API、数据库、微服务、第三方服务)
  3. 3. 版本信息至关重要: 精确记录所有第三方库、框架、中间件版本,比对已知漏洞库(如NVD、CVE)
  4. 4. 配置即代码: 严格审查配置文件(安全头、CORS、数据库连接、调试开关、密钥存储)
  5. 5. 攻击者视角”切换: 思考“如何破坏此功能?”而非“它应如何工作?”
  6. 6. 追踪用户可控输入: 从源头(HTTP请求参数、头、文件、Cookie、API、存储)至最终使用点(Sink)
  7. 7. 识别信任边界: 明确系统内外部数据交换点,此处必须严格校验与过滤
  8. 8. 敏感操作日志审计: 关键操作(登录、删改、支付)须记录完整、不可篡改的审计日志
  9. 9. 逆向思维验证: 针对防御代码(如WAF规则),尝试构造绕过Payload
  10. 10. 利用自动化初筛: SAST工具(如Fortify、Checkmarx、SonarQube)定位风险点,但绝不替代人工深挖

二、输入处理:筑起第一道防线

  1. 11. 白名单优于黑名单: 定义明确允许的字符集、格式、长度,而非仅过滤已知危险字符
  2. 12. 规范化解码再校验: 输入需先统一解码(如URL解码、UTF-8)再进行白名单校验,防止编码绕过
  3. 13. 类型强制转换陷阱: PHP的==弱类型比较需警惕,0e123456可能被当作科学计数法0;Java等强类型语言也需注意Integer边界
  4. 14. 文件上传多维防御:
    • • 后缀名检查(结合MIME类型、文件头魔数校验)
    • • 存储路径隔离(无执行权限)
    • • 随机重命名防覆盖
    • • 病毒扫描
    • • 禁用服务器解析特定扩展名(如.php.
  5. 15. XML解析器加固:
    • • 禁用外部实体(XXE防御:setFeature("http://apache.org/xml/features/disallow-doctype-decl", true)
    • • 禁用DTD
    • • 使用安全解析器(如defusedxml
  6. 16. JSON解析安全配置: 禁用类型转换(如Jackson的enableDefaultTyping())、限制反序列化类(白名单)
  7. 17. 正则表达式拒绝服务(ReDoS): 避免复杂回溯正则匹配不可控输入
  8. 18. 路径遍历防御: 使用规范路径函数(realpath()),检查路径是否在预期目录内,避免拼接
  9. 19. 命令注入终极法则: 避免直接拼接命令!使用参数化API(ProcessBuilder/subprocess)或严格白名单过滤
  10. 20. SQL注入深度防御:
    • • 首选参数化查询(PreparedStatement)
    • • 存储过程需避免动态拼接SQL
    • • ORM框架注意其是否最终生成安全SQL
    • • 最小权限原则配置数据库用户
  11. 21. NoSQL注入不容忽视: 检查MongoDB查询是否使用$where执行字符串、不当的JSON查询解析
  12. 22. 模版注入(SSTI)检测: 观察用户输入是否进入模版引擎(如Jinja2、Freemarker、Thymeleaf)的解析过程
  13. 23. HTTP头注入: 检查LocationSet-Cookie等头是否包含未过滤用户输入
  14. 24. 邮件头注入(CRLF): 过滤\r\n,使用库安全构建邮件
  15. 25. 批量分配风险(Mass Assignment): 框架(如Spring MVC、Laravel、Rails)需显式定义允许绑定的模型属性(白名单)

三、核心安全机制:认证、会话、权限

  1. 26. 密码存储验证: 强哈希算法(Argon2、scrypt、bcrypt、PBKDF2)+ 随机盐,禁止MD5/SHA1
  2. 27. 认证流程完整性: 登录、登出、注册、密码重置各环节是否存在逻辑缺陷(如跳过验证)
  3. 28. 多因素认证(MFA)后端校验: MFA状态需在服务器端会话中强绑定并验证
  4. 29. 会话管理关键点:
    • • 会话ID足够长且随机
    • • Cookie设置HttpOnlySecureSameSite属性
    • • 登录成功后更新会话ID(防会话固定)
    • • 会话超时机制
  5. 30. 权限控制三原则:
    • • 默认拒绝
    • • 最小权限
    • • 服务端执行(前端展示控制非安全边界)
  6. 31. 垂直越权检测: 普通用户能否访问仅管理员可见的功能/数据?检查每个功能入口的权限校验
  7. 32. 水平越权检测: 用户A能否操作(查看/修改/删除)用户B的数据?检查数据访问是否关联当前用户ID
  8. 33. 直接对象引用(IDOR)防御: 使用不可预测的引用(如GUID),或访问时校验数据归属
  9. 34. 功能级权限缺失: 后台管理URL是否可直接访问?API路由是否都配置了权限拦截器?
  10. 35. JWT安全配置:
    • • 验证签名算法(防止alg: none攻击
    • • 校验iss(签发者)、aud(受众)、exp(过期时间)
    • • 敏感数据不放在Token中
    • • 密钥(Secret)强度与保护

四、输出处理与客户端安全

  1. 36. 上下文感知的编码:
    • • HTML正文:HtmlEncode
    • • HTML属性:AttributeEncode
    • • JavaScript:JavaScriptEncode
    • • URL参数:URLEncode
    • • CSS:CSSEncode
  2. 37. 警惕innerHTML 避免直接设置innerHTML,使用安全的文本节点操作或经过验证的安全HTML净化库(如DOMPurify)
  3. 38. CSP策略部署: 内容安全策略有效缓解XSS,配置default-srcscript-src(禁用'unsafe-inline')、object-src 'none'
  4. 39. XSS过滤器的误区: 浏览器内置或WAF过滤器可能被绕过,不能替代安全的输出编码
  5. 40. 点击劫持防御: 设置HTTP头X-Frame-Options: DENYSAMEORIGIN,或使用CSP的frame-ancestors指令
  6. 41. CSRF Token机制验证:
    • • Token需足够随机
    • • 绑定用户会话
    • • 关键操作强制验证(GET请求不应改变状态)
    • • 检查Token存储位置(Cookie需配合自定义Header)
  7. 42. 安全重定向: 重定向目标需校验白名单或固定前缀,避免开放重定向漏洞
  8. 43. 错误信息泄露: 生产环境禁用详细栈跟踪、数据库错误信息,返回统一错误页面
  9. 44. CORS配置风险: 避免使用Access-Control-Allow-Origin: *处理敏感数据或操作,精确指定允许的来源域
  10. 45. 第三方脚本风险: 评估引入的外部JS库安全性,考虑子资源完整性(SRI)

五、纵深防御:加密、配置、依赖与逻辑

  1. 46. 加密算法与模式选择:
    • • 对称加密:AES(128/256位)+ GCM模式(认证加密)
    • • 非对称加密:RSA(2048+)/ECC
    • • 避免:DES、RC4、ECB模式
    • • 密钥管理:使用HSM或KMS,禁止硬编码
  2. 47. 配置敏感信息保护: 密码、API密钥、加密密钥等严禁硬编码在源码或配置文件中,使用环境变量或专用密钥管理服务
  3. 48. 依赖组件安全(SCA):
    • • 持续监控依赖库漏洞(OWASP Dependency-Check、Snyk)
    • • 及时升级修复版本
    • • 移除未使用的依赖
    • • 审核依赖的许可证
  4. 49. 业务逻辑漏洞深挖:
    • • 并发竞争条件(如余额检查与扣款分离导致超买)
    • • 负值处理(金额、数量)
    • • 越界操作(如ID最大值、负数索引)
    • • 工作流程绕过(跳过关键步骤)
  5. 50. 安全开发流程闭环: 将代码审计发现的问题系统化反馈至开发团队,推动安全编码规范、安全培训、SDL流程完善,建立安全左移机制

代码审计并非一蹴而就的任务,而是渗透于软件生命周期每个环节的持续性实践。


文章来源:HACK之道

本文来源HACK之道,经授权后由华盟君发布,观点不代表华盟网的立场,转载请联系原作者。

发表回复