PHP接口参数校验需建立输入可信边界,所有外部输入默认不可信,须在控制器前统一校验,结合filter_var、正则、白名单分层防御,并同步防护SQL、函数调用、文件操作及输出环节。

PHP接口参数未校验是多数安全问题的起点,修复核心不是“加一层判断”,而是建立输入可信边界:所有外部输入(GET、POST、Header、路由变量、文件名等)默认不可信,必须显式声明合法范围并强制执行。
明确校验位置与时机
校验不能只在业务逻辑里做,必须前置到请求进入控制器之前。ThinkPHP 5/6 中推荐在中间件或基类控制器的 initialize() 方法中统一处理;原生 PHP 可在入口文件(如 index.php)或路由分发前插入校验逻辑。
- 对关键操作接口(如登录、支付、删除),必须校验用户身份+权限+参数格式三重条件
- 禁止在 model 层或数据库操作前才做校验,避免绕过控制器直调方法
- URL 路径参数(如 /user/123 中的 123)也要校验,不能只信 POST 数据
用 filter_var + 正则 + 白名单组合校验
单一过滤手段易被绕过。例如仅用 intval() 会静默截断字符串,而仅用正则可能忽略编码变形。应分层防御:
- 基础类型转换:filter_var($id, FILTER_VALIDATE_INT) 比 (int) 更严格,失败返回 false
- 长度与格式限制:手机号用 filter_var($phone, FILTER_SANITIZE_NUMBER_INT) 后再验证位数;邮箱必须用 FILTER_VALIDATE_EMAIL
- 枚举值强制白名单:in_array($status, ['draft', 'published', 'archived'], true),禁用 == 松散比较
- 敏感字段(如 order_by、callback)禁止直接拼入 SQL 或函数调用,应映射为内部键名
拒绝危险参数名与非常规输入
攻击者常利用框架特性注入恶意参数,需主动拦截典型攻击模式:
立即学习“PHP免费学习笔记(深入)”;
- 在入口或中间件中检查 $_GET['s']、$_POST['_method'] 是否含 \think\、invokefunction、call_user_func、__construct 等关键词,匹配即终止请求
- 禁止参数名含双下划线(如 __test)、点号(user.name)、方括号(data[0])等可能触发自动属性赋值的符号,除非明确启用且已加固
- 对 JSON 接口,用 json_last_error() 校验解析结果,空或错误时直接返回 400,不继续处理
输出与执行环节同步防护
参数校验只是第一关,后续使用方式同样关键:
- SQL 查询必须用 PDO 预处理,禁用字符串拼接;即使参数已校验,也不代表可直接插进查询语句
- 动态调用函数(如 call_user_func)前,必须校验函数名是否在预设白名单内,禁用用户可控的任意函数名
- 文件操作(include、file_get_contents)绝不拼接用户参数,路径必须经 realpath() 解析后与白名单根目录比对
- HTML 输出一律过 htmlspecialchars($str, ENT_QUOTES, 'UTF-8'),JSON 输出用 json_encode() 并设置 JSON_UNESCAPED_UNICODE 和 JSON_INVALID_UTF8_SUBSTITUTE



















