过时的浏览器兼容URL对象:https://github.com/JakeChampion/polyfill-library/blob/master/polyfills/URL/polyfill.js
对本文反向,即无法正常显示IDN的情况转换成punycode:https://github.com/mathiasbynens/punycode.js
什么是IDN?
IDN全称:Internationalized Domain Names,本意是为了让URL更适配各个地方的本地语言,但是这也造成了IDN homograph attacks(IDN同形异义字攻击,下文称“同态攻击”)。
举例说明,这样一个域名:
// 为避免误点击,使用Code块
аpple.com
如果这样的URL展示在页面上,不仔细查看其前往的实际地址或者复制粘贴到地址栏,是无法发现其实际的URL为:https://xn--pple-43d.com/
这是因为这个URL中的а
使用 Cyrillic(U + 0430)而不是ASCII“a”(U + 0041)。
如何防御这一类问题
浏览器自身防御机制
针对这种问题,浏览器自身有自己的策略,比如:
在现代浏览器上,凡是赋予到link的dom上的href或者是URL对象的,都会被转换到实际的Punycode(wiki)上,那么最简单的解决方案即:
const suspiciousUrl = "аpple.com";
const c = new URL(suspiciousUrl);
if(c.href === suspiciousUrl) {
console.log("secure url");
} else {
console.log("suspicious detected ! original url is: " + c.href);
}