最近 Hacker News 上有一篇关于网站滥用 WebSockets 在客户端机器上搜索开放端口的文章(链接)。
该文章没有提供具体细节,因此我决定自己试试。
我在端口 8080 上打开了一个 web 服务器,并尝试在 Chrome 控制台中运行这个脚本:
function test(port) {
try {
var start = performance.now();
var socket = new WebSocket('ws://localhost:' + port);
socket.onerror = function (event) {
console.log('error', performance.now() - start, event);
}
socket.addEventListener('close', function(event) {
console.log('close', performance.now() - start, event);
})
socket.addEventListener('open', function (event) {
console.log('open', performance.now() - start, event);
socket.send('Hello Server!');
});
socket.addEventListener('message', function (event) {
console.log('message ', performance.now() - start, event);
});
} catch(ex) {
console.log(ex)
}
}
当我试图连接一个未开放的端口时,Chrome浏览器会记录不同的错误信息(ERR_CONNECTION_REFUSED
):
test(8081)
VM1886:3 WebSocket connection to 'ws://127.0.0.1:8081/' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED
当我尝试连接到一个开放但不支持 WebSockets 的端口时 (Unexpected response code: 200
):
test(8080)
WebSocket connection to 'ws://127.0.0.1:8080/' failed: Error during WebSocket handshake: Unexpected response code: 200
但我找不到任何方法在JavaScript中访问和读取这些错误。
控制流程似乎没有进入catch子句 catch(ex) { console.log(ex) }
,并且Chrome传递给socket.onerror
的事件对象似乎无论端口是否打开都没有任何区别。
至少在Chrome中,时间攻击似乎也没有帮助。在调用test(...)
几次后,在onerror
和new Socket()
创建之间的时间差好像会增加。
那么,网页是否实际上有办法确定计算机上的一个端口是否打开?