本文目录导读:

代码执行漏洞(通常指远程代码执行,RCE)是Web安全中风险最高的漏洞之一,因为它允许攻击者在服务器上执行任意命令,防御此类漏洞需要从代码层面、系统层面、架构层面进行纵深防御。
以下是核心的防御策略与最佳实践:
核心原则:最小化与禁用
-
尽量避免动态执行代码
- 这是最根本的防御,不要使用
eval()、exec()、assert()、system()、popen()、call_user_func()等函数去执行用户输入或拼接的代码。 - 对于PHP、Python、Java等语言,优先使用静态调用或反射机制,避免动态构造字符串并执行。
- 这是最根本的防御,不要使用
-
禁用危险函数
- 在php.ini中禁用
exec、system、passthru、shell_exec、proc_open、popen、eval等函数。 - 在Python中避免使用
pickle.loads()(从不可信源)、exec()、compile()。 - 在Node.js中避免使用
eval()、new Function()。
- 在php.ini中禁用
输入与数据验证(第一道防线)
-
严格的输入验证(白名单优于黑名单)
- 拒绝一切不可信数据进入危险函数,如果只需要一个整数ID,使用
is_numeric()或正则^\d+$进行校验,而不是过滤 或cat。 - 如果必须接收路径,使用白名单限制(如
allowed_dirs = ['/app/upload'])。
- 拒绝一切不可信数据进入危险函数,如果只需要一个整数ID,使用
-
输出编码/上下文转义
- 如果用户输入必须拼接在字符串中(例如构造一条shell命令),使用参数化或转义函数。
- 命令注入场景:使用
escapeshellarg()(PHP)或shlex.quote()(Python)对每个参数进行转义。永远不要直接拼接命令字符串。
-
反序列化安全
- 永远不要反序列化来自用户或不可信来源的数据。
- 如果必须使用,使用安全的序列化格式(如JSON、MessagePack),并确保数据完整性(如签名验证)。
运行时与系统加固(第二道防线)
-
最小权限原则
- Web应用运行用户(如
www-data)应只有只读权限,不能写入系统目录,更不能拥有sudo权限。 - 数据库连接使用专用低权限用户,限制只能操作特定库。
- Web应用运行用户(如
-
沙箱/容器化
- 使用Docker容器隔离应用进程,即使RCE发生,攻击者也无法直接访问宿主机。
- 对于极度危险的操作(如在线代码编辑器),使用 Firejail、gVisor 或 OpenBSD的pledge/unveil 限制系统调用。
-
限制系统调用
- 使用 Seccomp(Linux安全模块)限制应用可使用的系统调用,禁用
execve、fork等。 - 对于PHP,启用 disable_functions 和 open_basedir。
- 使用 Seccomp(Linux安全模块)限制应用可使用的系统调用,禁用
-
文件系统保护
- 挂载文件系统为只读(
ro)。 - 使用
chroot或jail将应用限制在特定目录。
- 挂载文件系统为只读(
开发与测试实践(第三道防线)
-
代码审查与静态分析
- 使用工具检测危险函数调用:
- SAST:SonarQube、Checkmarx、Fortify
- PHP:PHPStan(严格模式)、RIPS
- Python:Bandit
- Java:FindBugs/SpotBugs
- 在CI/CD流程中集成扫描,自动阻止含危险函数的代码合并。
- 使用工具检测危险函数调用:
-
WAF(Web应用防火墙)
- 部署WAF(如ModSecurity、Cloudflare WAF、长亭SafeLine)作为紧急防护层,但不要依赖WAF作为主要防御——攻击者总能绕过规则。
-
日志与监控
- 记录所有
eval/exec等敏感函数的调用日志。 - 监控异常进程启动(如突然执行
/bin/sh)、系统调用异常、文件写入系统目录等行为。
- 记录所有
特定场景防御策略
| 攻击向量 | 防御措施 |
|---|---|
| 命令注入 | 避免使用shell命令处理输入,2. 使用 escapeshellarg(),3. 使用语言原生API(如PHP的 is_file() 替代 shell_exec("ls"))。 |
| 模板引擎注入 | 使用沙箱模式模板引擎(如Twig的沙箱扩展),2. 设置 auto_escape=true,3. 禁止在模板中调用危险函数。 |
| 反序列化 | 使用JSON替代原生序列化,2. 对序列化内容加签(HMAC),3. 使用 java.rmi.server.useCodebaseOnly=true。 |
| SSRF(服务端请求伪造) | 阻止向内部IP(127.0.0.1, 10.x.x.x等)请求,2. 限制文件协议(如禁用 file://、gopher://)。 |
一句话核心防御
“永远不要信任用户输入,禁用所有可能执行代码的函数,如果必须执行,放在沙箱里,用最低权限运行,并严格限制参数。”
推荐的防御强度优先级(从强到弱):
- 根本避免 > 2. 参数化/转义 > 3. 沙箱/容器 > 4. WAF/监控