浏览器屏蔽的端口
今天我在用 Docker 和 Flask 做一个小项目时发现了一个奇怪的问题:我创建了两个几乎完全相同的服务,分别暴露在两个不同的端口上,本以为没什么花头,但出乎意料的是,只有其中一个服务能正常工作。
第一个服务监听端口 8000
,正如预期,我可以访问 localhost:8000
,看到自己编写的 HTML 的渲染结果。然而,第二个服务监听端口 6000
时,却无法正常显示我准备的页面,Chrome 浏览器返回了这个错误:
此网站无法访问
http://localhost:6000/ 可能暂时无法访问,或者已永久移动到新地址。
ERR_UNSAFE_PORT
出于好奇,我又在不使用 Docker 的情况下做了最简单的复现实验:用 Python 自带的 http.server
启动两个本地服务器:
$ python -m http.server 8000
$ python -m http.server 6000
两个命令分别在端口 8000
和 6000
启动了 HTTP 服务器。结果依旧:8000
端口可以正常访问,而访问 6000
端口则出现上述浏览器错误。究竟是什么原因呢?
跨协议脚本攻击
原来,部分端口会被浏览器显式屏蔽,这是为了防范所谓的跨协议脚本漏洞(VU#476267)。攻击者可通过恶意 HTML 代码,将数据发送到受害者可能运行的其它网络服务(例如伪造垃圾邮件、甚至对网络打印机发起打印命令)。IMAP、SMTP、NNTP、POP3 只是受影响服务的冰山一角。
Mozilla 与其他浏览器厂商已经通过在网络层面禁止访问这些易受攻击的端口来修复此漏洞。这样一来,当恶意脚本尝试发送数据时,就会出现前面提到的浏览器错误,从而阻止攻击。
各浏览器给出的提示略有不同。如上所示,Chrome 会显示 ERR_UNSAFE_PORT
。Safari 则通常只返回一个空白页面。Firefox 则最为直观,会提示:
此地址受限
该地址使用了通常不用于网页浏览的网络端口。为了保护您的安全,Firefox 已取消此请求。
从 Firefox 的提示里还可以看出,浏览器在发送请求之前就取消了它——请求根本没有到达服务器。查看服务器日志,也不会有任何访问记录。即使此时根本没有启动任何服务器,访问 http://localhost:6000
依然会出现同样的错误:浏览器在客户端就拦截了请求。
使用 cURL 验证
要证明这是浏览器层面的限制,你可以用命令行工具 cURL 绕过浏览器检查:
$ curl http://localhost:6000/
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Directory listing for /</title>
</head>
<body>
<h1>Directory listing for /</h1>
<hr>
<ul>
<li><a href="some_file.txt">some_file.txt</a></li>
</ul>
<hr>
</body>
</html>
可以看到,cURL 请求并没有被屏蔽,能够正确显示 Python 服务器的输出。
被屏蔽端口列表
以下是 Firefox 屏蔽的端口及其对应的服务(服务名称为标准协议名称):
端口 | 服务 |
---|---|
1 | tcpmux |
7 | echo |
9 | discard |
11 | systat |
13 | daytime |
15 | netstat |
17 | qotd |
19 | chargen |
20 | ftp 数据 |
21 | ftp 控制 |
22 | ssh |
23 | telnet |
25 | smtp |
37 | time |
42 | name |
43 | nicname |
53 | domain |
77 | priv-rjs |
79 | finger |
87 | ttylink |
95 | supdup |
101 | hostriame |
102 | iso-tsap |
103 | gppitnp |
104 | acr-nema |
109 | POP2 |
110 | POP3 |
111 | sunrpc |
113 | auth |
115 | sftp |
117 | uucp-path |
119 | NNTP |
123 | NTP |
135 | loc-srv/epmap |
139 | netbios |
143 | IMAP2 |
179 | BGP |
389 | LDAP |
465 | SMTP+SSL |
512 | print/exec |
513 | login |
514 | shell |
515 | printer |
526 | tempo |
530 | courier |
531 | chat |
532 | netnews |
540 | uucp |
556 | remotefs |
563 | NNTP+SSL |
587 | submission |
601 | syslog |
636 | LDAP+SSL |
993 | IMAP+SSL |
995 | POP3+SSL |
2049 | NFS |
4045 | lockd |
6000 | X11 |