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

欧阳士媛 阅读 36

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


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

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

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

我来解答 赞 8 收藏
二维码
手机扫码查看
1 条解答
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