应采用X-Frame-Options、CSP frame-ancestors、Referer校验、Frame-Buster脚本及透明覆盖层五种方法协同防护点击劫持:一设X-Frame-Options为DENY或SAMEORIGIN;二用CSP frame-ancestors指定可信源;三服务端校验Referer是否同源;四嵌入JS检测并跳出iframe;五动态启用透明覆盖层拦截点击。

如果您在PHP应用中发现页面可被恶意嵌入第三方iframe并诱导用户误操作,则可能是由于缺乏有效的点击劫持防护机制。以下是多种防止点击劫持攻击的具体方法:
一、设置X-Frame-Options响应头
该HTTP响应头直接指示浏览器是否允许当前页面被嵌入iframe,是防御点击劫持最基础且广泛支持的手段。通过强制限制嵌套来源,可有效阻断iframe劫持链路。
1、在PHP脚本开头(输出任何内容前)调用header函数设置响应头。
2、使用DENY选项完全禁止所有iframe嵌入:header("X-Frame-Options: DENY");
立即学习“PHP免费学习笔记(深入)”;
3、或使用SAMEORIGIN仅允许同源iframe嵌入:header("X-Frame-Options: SAMEORIGIN");
4、确保该头未被后续代码覆盖,且不在HTML meta标签中模拟(meta方式无效)。
二、启用Content-Security-Policy frame-ancestors指令
CSP是更现代、更灵活的安全策略机制,frame-ancestors指令可替代并增强X-Frame-Options的功能,且支持更细粒度的来源控制,已被主流浏览器支持。
1、在PHP响应头部添加CSP策略:header("Content-Security-Policy: frame-ancestors 'self';");
2、若需允许多个可信域名,可写为:header("Content-Security-Policy: frame-ancestors 'self' https://trusted.example.com;");
3、注意避免与旧版X-Frame-Options冲突;当两者共存时,浏览器将采用更严格的策略。
三、服务端检测Referer来源并拦截非法请求
通过比对HTTP Referer头与当前站点域名,可在服务器端识别非预期的嵌入行为,并主动拒绝响应,适用于需兼容老旧浏览器或补充验证的场景。
1、启用会话前先检查Referer是否存在:if (!isset($_SERVER['HTTP_REFERER'])) { die('Access denied.'); }
2、提取当前请求协议和主机名:$origin = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'];
3、判断Referer是否匹配当前源:if (parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST) !== $_SERVER['HTTP_HOST']) { die('Illegal iframe embedding detected.'); }
四、嵌入JavaScript Frame-Buster脚本
该方法在客户端运行,通过检测窗口层级关系强制跳出iframe环境,适用于无法控制服务器响应头的部署场景,但依赖JavaScript执行且可能被禁用。
1、在HTML的
或顶部插入以下脚本块:2、使用严格相等判断顶层窗口:<script>if (top !== self) { top.location.replace(self.location.href); }</script>
3、为防绕过,可增加定时轮询与视觉提示:<script>var bust = function() { if (top !== self) { top.location.replace(self.location.href); } }; setInterval(bust, 500);</script>
五、添加透明覆盖层阻止UI交互劫持
此方案不阻止嵌入,而是使嵌入后的页面无法响应用户真实点击,通过CSS层叠与事件拦截保护关键操作区域,适用于高敏感操作页(如转账确认)。
1、在页面body末尾注入覆盖div:
2、使用JavaScript动态激活防护(仅当检测到iframe环境时):<script>if (top !== self) { document.getElementById('clickjacking-shield').style.pointerEvents = 'auto'; }</script>
3、配合CSS过渡实现无感遮罩:document.getElementById('clickjacking-shield').style.background = 'rgba(255,255,255,0.01)';



















