JavaScript协议链接会被XSS攻击吗?怎么防?

IT人忠娟 阅读 6

我在项目里有个地方要动态生成超链接,用户可以输入URL,但我发现如果输入 javascript:alert(1) 这种,点击就会执行脚本,这算XSS漏洞吧?

我试过用正则过滤 javascript:,但担心有绕过方式。有没有更稳妥的处理方法?比如只允许 http/https 协议?

现在代码大概是这样:

function createLink(url) {
  const a = document.createElement('a');
  a.href = url;
  a.textContent = '点击跳转';
  return a;
}
我来解答 赞 2 收藏
二维码
手机扫码查看
1 条解答
程序员柯欣
这绝对是 XSS 漏洞,而且是个挺经典的坑。你用正则过滤 javascript: 的思路是对的,但确实容易被绕过,比如 JAVASCRIPT:javascript:java script:(中间加制表符)等各种骚操作,防不胜防。

更稳妥的做法是用白名单机制,只允许 httphttps 协议。可以利用浏览器原生的 URL 解析能力来做校验:

function createSafeLink(url) {
// 默认置空,安全第一
let safeUrl = '';

try {
const parsed = new URL(url, window.location.href);
// 白名单只允许 http 和 https
if (parsed.protocol === 'http:' || parsed.protocol === 'https:') {
safeUrl = parsed.href;
}
} catch (e) {
// URL 解析失败,说明格式有问题,直接丢弃
console.warn('非法URL格式:', url);
}

const a = document.createElement('a');
a.href = safeUrl || 'javascript:void(0)'; // 不安全就给个空操作
a.textContent = '点击跳转';
a.rel = 'noopener noreferrer'; // 注意安全,防止钓鱼页面反向操控你的页面

// 如果URL不合法,可以禁用链接或者不插入DOM
if (!safeUrl) {
a.style.color = '#999';
a.style.pointerEvents = 'none';
a.textContent = '无效链接';
}

return a;
}


几个关键点说下。new URL() 会自动帮你处理编码、大小写等问题,解析出来的 protocol 是标准化的,不存在绕过的可能。白名单思维永远比黑名单靠谱,你不需要去猜黑客有多少种绕过姿势。

注意安全,还有个细节容易忽略:给外链加上 rel="noopener noreferrer"。不然目标页面可以通过 window.opener 操纵你的源页面,这叫 tabnabbing 攻击,虽然不是 XSS,但也是个安全隐患。

另外如果你的业务需要支持相对路径,第二个参数 window.location.href 作为 base URL 会帮你正确解析。如果只允许绝对路径的外链,可以把 base 参数去掉,解析失败就当非法处理。
点赞
2026-03-03 02:00