React组件如何防止点击劫持绕过确认弹窗?

欧阳士媛 阅读 56

我正在给一个删除按钮加确认弹窗,但测试时发现如果页面被嵌入iframe,攻击者仍能通过透明覆盖层触发点击。虽然用了事件冒泡阻止和CSS定位,但效果不好。代码如下:


function ConfirmButton({ onDelete }) {
  const [showModal, setShowModal] = useState(false);
  
  const handleClick = (e) => {
    e.stopPropagation(); // 尝试阻止冒泡
    setShowModal(true);
  };

  return (
    
      
      {showModal && (
        
确认删除?
)}

即使设置了pointer-events和stopPropagation,攻击者还是能通过iframe定位到按钮坐标点击。有没有更可靠的防御方式?

我来解答 赞 18 收藏
二维码
手机扫码查看
2 条解答
司空仙仙
最简单的办法是加个X-Frame-Options响应头阻止iframe嵌入。再补个透明覆盖层检测:

// 组件里加这个hook
useEffect(() => {
if (window.self !== window.top) {
document.body.innerHTML = '别想嵌套我';
}
}, []);

// CSS里加这个
.modal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.01); // 近乎透明但能拦截点击
}


这样双重保险,比光阻止冒泡靠谱多了。
点赞 1
2026-03-06 22:05
A. 树果
A. 树果 Lv1
你这个问题挺典型的,防止点击劫持确实要多管齐下。光靠事件冒泡和CSS是不够的,得从JS逻辑上加强校验。给你个方案拿去改改:

1. 加一个时间戳校验,确保用户真的点了确认按钮
2. 检查窗口是否被iframe嵌套

直接上代码:

function ConfirmButton({ onDelete }) {
const [showModal, setShowModal] = React.useState(false);
const [timestamp, setTimestamp] = React.useState(null);

// 检查是否被iframe嵌套
React.useEffect(() => {
if (window.top !== window.self) {
console.warn("页面被iframe嵌套了!");
// 可以选择禁用按钮或者提示用户
}
}, []);

const handleClick = (e) => {
e.stopPropagation();
setTimestamp(Date.now());
setShowModal(true);
};

const handleConfirm = () => {
// 确保确认操作在合理时间内完成
if (Date.now() - timestamp < 5000) {
onDelete();
} else {
console.warn("操作超时");
}
setShowModal(false);
};

return (
<>

{showModal && (

确认删除?





)}

);
}


这样基本能防住大部分攻击了。记得再结合CSP策略一起用,效果更好。
点赞 8
2026-01-28 20:07