核心是白名单授权、剥夺交互式登录、目录级ACL三者组合:用/etc/sudoers精确指定绝对路径命令,/sbin/nologin禁用SSH登录,setfacl控制特定目录写入权限。

核心是让代码只能访问它“该访问”的路径,不能越界读取配置、日志或系统文件。这不是靠一两个函数调用就能解决的,而是从路径构造、文件操作、权限边界三方面同步收紧。
路径构造阶段:杜绝用户输入直接拼接
攻击者常通过../或绝对路径绕过限制。一旦允许用户控制路径片段,风险就已埋下。
- 禁止将
$_GET['file']、request.args.get('path')等原始参数直接传给open()、file_get_contents()或include - 用白名单映射代替路径解析:比如用户请求
type=avatar,后端查表确认对应/uploads/avatars/,再拼接文件名,不暴露真实路径结构 - 若必须接受路径参数,先用
realpath()(PHP)或os.path.realpath()(Python)标准化,再检查是否落在预设根目录内。例如:if not real_path.startswith('/var/www/html/static/'):raise PermissionError("Access denied")
文件操作阶段:限定读写执行权限分离
即使路径合法,也要防止误操作导致敏感文件被覆盖或执行。
- 静态资源目录(如
/static/)只赋予rx(读+执行),禁写;上传目录(如/uploads/)只给rw-(读+写),严禁执行权限 - PHP中禁用
allow_url_include=On,关闭phar://等协议支持,防止通过伪协议加载恶意文件 - Java应用避免使用
FileInputStream直接读取用户传入路径,改用ServletContext.getRealPath()获取受控路径后再校验 - Node.js中慎用
fs.readFile(path, ...),优先使用path.join(__dirname, 'safe', filename)限定父目录范围
运行环境阶段:账号权限与目录隔离双保险
代码逻辑再严谨,若运行账号权限过大,仍可能突破沙箱。
- Web服务进程(Nginx/Apache/Python WSGI)必须以专用低权账号运行(如
www-data),且该账号shell设为/usr/sbin/nologin,无法交互登录 - 网站根目录归属
root:www-data,权限设为755;上传目录归属www-data:www-data,权限750;配置文件由root独占,www-data无读写权 - Linux下用
setfacl或chattr +a进一步锁定关键目录,例如对/etc/nginx/禁止www-data任何访问 - 容器部署时,通过
USER www-data指令指定运行身份,并挂载卷时设置uid/gid匹配,避免权限错位
验证与兜底:加一层运行时防护
加固不是一次配置完就结束,需有可验证手段和应急屏障。
- 在关键文件读取前插入日志记录:记录请求路径、标准化后的真实路径、调用栈,便于回溯异常访问
- Nginx中针对常见敏感路径加
location拦截:location ~* \.(conf|ini|log|sh|sql)$ { return 404; }location ^~ /etc/ { return 403; } - 启用WAF规则识别
%2e%2e/、..%2f等编码绕过,同时开启ModSecurity的REQUEST-930-APPLICATION-ATTACK-LFI规则集 - 定期用
find /var/www -type f -perm -111扫描可执行文件,及时清理意外写入的脚本











