4.2 服务端输入边界:注入、路径与文件处理
注入发生在一个解释器无法区分“应用编写的语法”和“外部提供的数据”时。SQL 只是最熟悉的一种;shell、模板、LDAP、日志查询和表达式语言都有相同结构。
参数化查询把值与语法分开
危险代码:
"SELECT * FROM users WHERE email = '" + email + "'"正确方向是使用数据库 driver 的 bind parameter:
SELECT id, password_hash
FROM users
WHERE email = ?参数只代表值,不能改变查询结构。参数化通常不能绑定表名、列名和排序方向;这些结构性选项应由服务端 enum 映射:
sort=recent → ORDER BY created_at DESC
sort=name → ORDER BY display_name ASC不要对用户传入的列名做“转义后拼接”。存储过程只有在内部也不动态拼 SQL 时才安全,ORM 也可能通过 raw query、字符串 filter 或不安全 escape hatch 重新引入注入。
数据库账户还应最小权限:读接口不使用 schema owner,报表任务不拥有写权限,应用不能读取其他租户 schema。WAF 可以挡住部分已知 payload,但无法替代码与数据分离。
Shell 命令优先不经过 Shell
危险:
shell("convert " + uploadedPath + " output.png")优先使用库 API;必须调用进程时,用参数数组并关闭 shell 解析:
execve("/usr/bin/convert", ["convert", validatedInput, outputPath], cleanEnv)参数数组降低命令分隔符注入,却不自动保证目标程序的参数安全。以 - 开头的文件名可能被当选项,某些工具支持从 URL、配置或响应文件读取更多输入。应使用 -- 终止选项、服务端生成路径、严格 allowlist,并以低权限 sandbox 执行。
模板要区分展示模板与代码模板
把用户输入作为模板数据通常可以安全转义;让用户控制模板源码则可能形成 Server-Side Template Injection,读取进程对象、环境变量甚至执行命令。
render(trustedTemplate, { displayName: untrustedValue }) ✓
render(untrustedTemplateSource, model) 高风险确需用户模板时,使用为不可信模板设计的受限语言、固定函数集合、资源限制与进程隔离。仅删除几个危险关键字不能建立沙箱。
路径规范化不能靠字符串前缀
下载接口常见问题:
/download?file=../../etc/passwd安全设计优先让客户端提交不透明对象 ID,由服务端数据库映射到存储对象,而不是接受文件系统路径。若必须处理相对路径,应:
- 对输入做一次明确解码,拒绝 NUL 和非法形式;
- 在固定根目录下解析 canonical path;
- 确认结果仍在根目录内,注意路径分隔符与大小写规则;
- 防止符号链接与检查后替换的 TOCTOU;
- 使用目录 fd 和安全 open flags 等平台能力缩短竞态。
简单的字符串 startsWith(root) 会把 /srv/uploads-evil 误当成 /srv/uploads 内部路径。
文件上传是内容处理管线
扩展名和浏览器 Content-Type 都由客户端控制。上传服务应组合:
- 限制大小、数量、压缩展开比和处理时间;
- 检查允许类型的 magic bytes 与完整解析;
- 服务端生成对象名,存到 Web root 之外或独立对象存储;
- 下载时设置安全
Content-Type、Content-Disposition与nosniff; - 图片、文档和媒体转码放入低权限、有限资源的 sandbox;
- 恶意软件扫描作为附加信号,不作为唯一安全边界;
- 对公开内容使用独立 origin,避免上传 HTML 获得主站权限。
Zip Slip、解压炸弹和解析器漏洞说明“只存文件不执行”并不等于安全。
不可信反序列化会恢复行为
某些对象序列化格式可以指定类型、构造器或 gadget chain。不要反序列化来自 Cookie、队列、缓存或上传文件的不可信原生对象图。优先使用只表达数据的 schema 格式,显式允许字段与类型,并限制深度、长度和重复结构。
签名只能证明数据来自持有密钥的一方;如果多个低信任服务共享签名密钥,其中任一服务仍可能构造危险对象。安全格式和最小解析能力不能由签名替代。
异常路径也要保持边界
解析失败时不要回退到“兼容模式”执行原字符串,也不要把数据库错误、命令 stderr、绝对路径和 stack trace 返回给外部用户。记录内部 correlation ID,向客户端提供稳定错误模型,并对异常率告警。
OWASP Top 10:2025 把 Mishandling of Exceptional Conditions 单列为 A10,提醒安全设计不能只覆盖成功路径。
参考资料
- OWASP, SQL Injection Prevention Cheat Sheet
- OWASP, OS Command Injection Defense
- OWASP, File Upload Cheat Sheet
- OWASP, Top 10:2025