替换Node.js + Express.js中的主机名以解码punycode域

时间:2016-03-12 10:31:54

标签: node.js express middleware idn punycode

我正在开发一个西里尔字段的网络应用程序。目前,该域名拥有一个停放的页面",表示该网站正在建设中。如果我在Chrome中访问它,我会在地址栏中看到punycode。 Safari虽然解码了它。出于开发目的,我修改了/etc/hosts文件,以便能够通过测试西里尔字段访问localhost。但是,Chrome和Safari都无法解码主机名。

我已经查到了这个问题,但找不到任何合理的解决方案。 Node.js有一个名为punycode的模块。现在,如果我的req.url包含西里尔字符,它会被URIComponent - 编码,因此我编写了一个中间件来解码它:

app.use(function(req, res, next) {
    var url = req.url,
        decoded = decodeURIComponent(url);

    if (url !== decoded) req.url = decoded;
    next();
});

它工作正常,我现在可以使用西里尔语路由。但是,当我尝试将此逻辑应用于主机名时,它不起作用:

app.use(function(req, res, next) {
    var hostname = req.hostname,
        decoded = punycode.toUnicode(hostname);

    if (hostname !== decoded) req.hostname = decoded;
    // I have also tried return res.redirect('https://' + decoded + ':' + ...);
    next();
});

非常感谢任何帮助。谢谢!

1 个答案:

答案 0 :(得分:0)

好的,经过研究,我发现这几乎是不可能的。主机解析策略严格针对特定于浏览器,并且(针对IDN)用于防止危险的网络钓鱼活动。 Safari一方面将IDN从punycode解析为UTF-8字符串,Chrome另一方面也没有。

这些危险的网上诱骗活动可能来自包含非ASCII字符的域名。考虑一组ASCII字母“o,e,a”和UTF-8俄语(西里尔文)字母“о,е,а”。它们看起来几乎相同,因此对客户来说无法区分。因此,黑客可以注册一个看起来就像一个众所周知的域名(“paypal.com”用ASCII“a”和“pаypаl.com”用UTF-8西里尔语“а”) )。

为防止此类恶意活动,Chrome会将非ASCII字符编码为punycode(“pаypаl.com”,UTF-8西里尔字母“а”将在浏览器地址栏中显示为“xn--pypl-53dc.com”警告客户,这不是原始网站。

叹息,看起来IDN不是目前为止最好的解决方案。