防范xss攻击需建立可信数据流转链:严格过滤输入(如filter_var校验类型、长度限制、htmlpurifier处理富文本)与可靠转义输出(htmlspecialchars、json_encode等),并配合httponly、csp等纵深防御。

防范XSS攻击,关键不在“堵住所有入口”,而在于建立可信的数据流转链:对表单输入做严格过滤,对输出做可靠转义,两者缺一不可。仅靠前端校验或只做后端过滤,都容易被绕过。
验证输入类型与格式
不要信任任何客户端传来的数据。PHP中应优先使用filter_var()进行类型化校验,而不是正则匹配或字符串替换。
- 邮箱用
FILTER_VALIDATE_EMAIL,不依赖自定义正则(易漏判国际化邮箱) - 整数用
FILTER_VALIDATE_INT并配合options指定范围,如['min_range' => 1, 'max_range' => 999] - URL用
FILTER_VALIDATE_URL,避免用户提交javascript:alert(1)类伪协议 - 若需白名单字符(如用户名),用
filter_var($input, FILTER_SANITIZE_STRING, ['options' => ['flags' => FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH]])后再结合preg_match('/^[a-zA-Z0-9_]{1,50}$/', $cleaned)
限制长度与拒绝危险内容
长度限制是低成本高收益的第一道防线;但不能仅靠maxlength属性——它可被浏览器禁用或绕过,必须在服务端二次校验。
- 所有文本字段设定合理最大长度(如昵称≤20、评论≤500),超长直接拒绝,不截断
- 主动检测并拦截含典型XSS载荷的输入,例如:
<script>、<code>onerror=</script>、javascript:、vbscript: - 对富文本字段(如文章正文),不自行“清洗HTML”,改用成熟库如
HTMLPurifier,配置白名单标签与属性
统一封装过滤逻辑,避免遗漏
分散写filter_var或htmlspecialchars极易出错。建议封装为可复用的工具方法,明确每个字段的处理策略。
- 定义
InputSanitizer::email(string $raw): ?string,失败返回null而非空字符串 - 定义
InputSanitizer::text(string $raw, int $maxLen = 200): string,内部自动trim、长度校验、移除控制字符 - 所有表单入口统一调用
$data = InputSanitizer::fromPost();,强制走同一套流程 - 日志记录被拦截的异常输入(含IP、时间、原始值),用于识别攻击模式
配合输出转义与HttpOnly等纵深防御
输入过滤只是起点。即使数据已净化,输出到不同上下文(HTML、JS、CSS、URL)时仍需对应编码,否则仍可能触发XSS。
- 插入HTML内容前,必须用
htmlspecialchars($value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') - 插入JavaScript字符串中,用
json_encode($value, JSON_UNESCAPED_UNICODE | JSON_HEX_TAG) - 所有Cookie设置
HttpOnly和Secure标志,防止JS读取会话标识 - 添加
Content-Security-Policy: default-src 'self'响应头,禁止内联脚本与未知来源加载











