PHP开发中如何拒绝来自服务器或站点外部的POST请求
拒绝外部站点/服务器POST请求的实现方案
要拦截非本站来源的POST请求,可根据安全要求选择不同的校验方案,以下是可直接落地的实现方式:
基础防护:请求头校验
通过校验浏览器携带的来源头实现基础拦截,实现成本低,适合普通非敏感场景:
- 校验
Origin头:跨域请求时浏览器会强制携带该头,伪造难度高于Referer,适配接口类请求校验 - 校验
Referer头:本站正常提交的表单请求会携带当前站点域名作为Referer,适配普通表单提交场景
对应实现代码:
<?php // 替换为你自己的站点域名,注意带http/https前缀 $allowed_domain = 'https://your-website.com'; if ($_SERVER['REQUEST_METHOD'] == 'POST'){ $origin = $_SERVER['HTTP_ORIGIN'] ?? ''; $referer = $_SERVER['HTTP_REFERER'] ?? ''; $is_legal_request = false; // Origin头匹配校验 if (!empty($origin) && str_starts_with($origin, $allowed_domain)) { $is_legal_request = true; } // Referer头匹配校验 elseif (!empty($referer) && str_starts_with($referer, $allowed_domain)) { $is_legal_request = true; } // 校验不通过直接返回403拒绝访问 if (!$is_legal_request) { http_response_code(403); exit('Access Forbidden'); } // 你的业务逻辑代码 // code } ?>
高可靠防护:CSRF令牌校验
不受浏览器配置影响,可阻挡几乎所有外部伪造的POST请求,适合敏感操作场景:
- 首先在渲染表单页面时生成随机令牌,存入用户Session并嵌入表单隐藏域:
<?php session_start(); // 生成随机CSRF令牌 if (empty($_SESSION['csrf_token'])) { $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); } ?> <form method="post" action="submit.php"> <input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>"> <!-- 其他表单字段 --> <input type="submit" value="提交"> </form>
- POST接口侧校验令牌:
<?php session_start(); if ($_SERVER['REQUEST_METHOD'] == 'POST'){ $request_token = $_POST['csrf_token'] ?? ''; // 令牌不匹配直接拒绝 if (empty($request_token) || $request_token !== $_SESSION['csrf_token']) { http_response_code(403); exit('Access Forbidden'); } // 你的业务逻辑代码 // code } ?>
注意事项
- 请求头校验存在局限性,部分用户浏览器可能会禁用Referer头,也存在被特殊手段篡改的可能,仅可作为基础防护使用
- 涉及资金操作、用户信息修改等敏感场景,必须搭配CSRF令牌校验才能保证安全性
内容的提问来源于stack exchange,提问作者Shazz
相关产品推荐
相关产品推荐

