SECURE CODING · 攻防 / 编码红线

安全编码速查

从注入防御、XSS 与 CSRF,到认证会话、敏感数据、依赖配置与文件反序列化,安全编码红线逐条成表,写代码与评审时对照即查。

8速查小节 52速查条目 3种 XSS 类型 5个安全响应头

📖 速查表

点击展开各小节

💉 注入类防御
攻击类型成因防御要点
SQL 注入 用户输入被拼进 SQL 语句,改变原语句语义 预编译与参数化(PreparedStatement / #{} 占位符);数据库账号最小权限,禁止字符串拼接 红线
MyBatis ${} 陷阱 ${} 是字符串直接替换,输入照单全收 传参一律 #{};动态表名 / 排序字段走白名单映射 易错
命令注入 拼接字符串调用 shell,分号 / 管道符注入额外命令 避免拼接执行系统命令;ProcessBuilder 参数数组传参 + 可执行项白名单 高危
SSTI 模板注入 用户输入被当作模板内容渲染执行 模板与数据分离:用户输入只作变量值,永不作模板源
XXE XML 解析器允许外部实体与 DTD,读取文件或发起内网请求 关闭 DTD 与外部实体(disallow-doctype-decl 等特性);非必要不解析 XML
通用红线 一切外部输入(参数 / Header / 文件)默认不可信 白名单校验 + 参数化传递;错误信息不回显 SQL 与堆栈细节
安全编码流程
安全编码顺序感:入口收紧校验,中间按语境处理,出口编码,全程脱敏留痕
🧨 XSS 与 CSRF
XSS 类型注入位置防御要点
存储型 XSS 恶意脚本入库(评论 / 昵称),他人浏览页面时触发,影响面最大 入库校验 + 输出编码;富文本走白名单过滤,只保留安全标签
反射型 XSS 参数携带脚本被服务端原样回显到页面 输出编码 + 参数严格校验,URL 参数不直接写入 HTML
DOM 型 XSS 前端脚本把不可信数据写入 innerHTML 或经 eval 执行 textContent 赋值,禁用 evaldocument.write
手段说明要点
输出编码(按上下文) HTML 正文 / 属性 / JS / URL 各用对应编码器 OWASP Java Encoder;数据拼接进页面前一律编码
CSP 响应头 限制脚本与资源来源,注入成功也难以执行 script-src 'self' + nonce;是兜底手段,不能替代输出编码
HttpOnly Cookie 会话 Cookie 禁止 JS 读取 配合 Secure;XSS 即便得手也偷不走会话凭证
CSRF Token 表单 / 请求头携带随机 Token,服务端比对一致性 Token 与会话绑定;POST / PUT / DELETE 全覆盖
SameSite Cookie 限制跨站请求携带 Cookie,从源头削弱 CSRF Strict 最严格,Lax 兼容大多数跳转场景
关键操作二次确认 转账 / 改密等敏感操作要求验证码或原密码 同时缓解 CSRF 与会话被劫持后的破坏面 推荐
🔑 认证与会话
认证是系统的正门:正门守不住,后面所有防御都在裸奔。
措施正确做法常见错误
密码存储 bcrypt / argon2 慢哈希 + 随机盐,成本可调 用 MD5 / SHA1 甚至明文存库 红线
会话固定防护 登录成功后重建并轮换 SessionId 沿用登录前旧 SessionId,给会话固定攻击留门
水平越权 IDOR 服务端校验资源归属:订单 / 资料 ID 是否属于当前用户 只靠前端隐藏入口,改 ID 即可越权 高频漏洞
垂直越权 按角色统一鉴权,拦截器 / 注解收口,默认拒绝 仅前端隐藏管理菜单,接口裸奔
登录限流 失败计数 + 图形 / 短信验证码,账号与 IP 双维度限制 对暴力破解完全不设防
JWT 安全 短有效期 + refresh token 轮换 + 注销黑名单 把敏感信息放 payload——Base64 只是编码不是加密
多因素认证 高价值操作叠加 OTP / 短信因子 单一密码保护支付类账号 建议
🗄️ 敏感数据
场景要求
传输加密 全站 HTTPS,禁明文 HTTP;内网服务间调用同样加密,防链路嗅探
存储加密与密钥管理 身份证 / 银行卡等字段级加密(AES-GCM);密钥交 KMS 或配置中心托管,禁止硬编码进代码库
最小化收集 只收集业务必需字段,超期即删;展示层默认脱敏,明文只在必要节点短暂出现
日志脱敏清单规则示例
手机号 保留前 3 后 4 138****5678
身份证号 保留前 6 后 4 110101********1234
银行卡号 仅保留后 4 位 ************1234
邮箱 用户名打码,保留域名 a***@domain.com
Token / 密码 / 密钥 一律不打日志;异常对象先脱敏再 toString 日志出现 Bearer eyJ... 即为事故 红线
📦 依赖与配置
主题要点
依赖漏洞扫描 OWASP Dependency-Check / npm audit / Snyk 接入 CI,高危依赖阻断合并并及时升级
默认配置风险 修改中间件默认口令(Redis / Druid / MQ 管理台),关闭示例页面与匿名访问 常见突破口
调试端点暴露 生产关闭 Swagger / Actuator / Druid 监控,或加鉴权并限内网访问
错误信息泄露 统一异常处理返回通用错误码,不外抛堆栈、SQL、内网路径与版本信息
安全响应头作用示例值
Strict-Transport-Security 强制浏览器后续访问走 HTTPS max-age=31536000; includeSubDomains
X-Frame-Options 防点击劫持,禁止被 iframe 嵌套 DENYSAMEORIGIN
X-Content-Type-Options 禁止 MIME 嗅探,按声明类型处理响应 nosniff
Referrer-Policy 限制 referer 携带的来源信息 strict-origin-when-cross-origin
Permissions-Policy 收敛摄像头 / 定位等浏览器敏感能力 camera=(), geolocation=()
📤 文件与反序列化
文件上传与反序列化是 RCE 高发地:默认全部不可信,白名单先行。
风险点防御要点
上传类型校验 校验文件魔数(文件头)而非只看后缀与 Content-Type;类型走白名单 红线
大小与数量限制 单文件与请求体设上限;压缩包防 zip bomb 解压爆炸
存储隔离 随机重命名 + 独立域名 / OSS 托管;上传目录禁执行权限,防脚本被解析
下载与路径安全 固定根目录并校验规范化路径(realpath),防 ../ 目录穿越读取任意文件
Java 原生反序列化 禁止 ObjectInputStream 处理不可信数据;升级组件修复已知 gadget 利用链
JSON 自动化绑定 多态反序列化收紧 type 白名单;Jackson 开 defaultTyping 必须配校验器兜底
SSRF 防御 协议白名单(仅 http/https)、禁内网网段与云元数据地址、禁跟随重定向;DNS 解析后复检目标 IP
🔐 Java 安全编码片段
三段可直接抄进项目的高频安全写法:预编译防注入、真随机数、防 ReDoS 的正则
// ① 防注入:PreparedStatement 预编译,用户输入永远走占位符 String sql = "SELECT id, name FROM user WHERE phone = ? AND status = ?"; try (PreparedStatement ps = conn.prepareStatement(sql)) { ps.setString(1, phone); // 输入只作参数值,不参与 SQL 语义拼接 ps.setInt(2, STATUS_NORMAL); ResultSet rs = ps.executeQuery(); } // 对应 MyBatis:传参一律 #{};${} 仅限白名单映射的表名 / 排序字段 // ② 真随机:Token / 验证码 / 盐必须用 SecureRandom,禁止 java.util.Random SecureRandom random = new SecureRandom(); byte[] bytes = new byte[32]; random.nextBytes(bytes); String token = Base64.getUrlEncoder().withoutPadding().encodeToString(bytes); // Random 是线性同余算法,观测几个输出即可预测后续,验证码形同虚设 // ③ 防 ReDoS:正则避免嵌套量词,白名单字符集 + 长度上限双保险 // ❌ (a+)+$ 、(a|a)*$ —— 嵌套量词,恶意输入触发指数级回溯,CPU 被打满 Pattern SAFE_NAME = Pattern.compile("^[a-zA-Z0-9_\\-]{1,64}$"); if (!SAFE_NAME.matcher(username).matches()) { throw new IllegalArgumentException("用户名格式非法"); }
🧨 供应链投毒防范
投毒攻击盯的是「你不看的东西」:传递依赖、构建脚本、陌生新包;五道防线层层设卡
防线做法要点
锁版本 + lockfile 审查 提交并锁定 lockfile / 固定版本号,diff 中出现依赖变更必须人工审查 重点盯冒出来的陌生传递依赖:谁引入的、为何升级 第一道闸
依赖最小化 能用 JDK / 框架自带能力就不引第三方包,定期清理不再使用的依赖 每个依赖都是攻击面与维护成本:少一个依赖少一份风险
私服白名单 构件只从公司私服(Nexus / Artifactory)拉取,私服仅代理白名单公共仓库 禁直连公共源;本地开发也统一走私服,杜绝绕行
CI 跑依赖漏洞扫描 OWASP Dependency-Check / Snyk 接入流水线,高危 CVE 阻断合并 告警必须闭环:升级修复,或在 suppress 文件里写明理由 门禁
新包先查履历 引入前查发布历史、维护者数量、下载量与 issue 响应活跃度 刚发布就蹭热点、单一维护者、名字仿冒热门包 = 高危信号 查三代