【问题标题】:Is there a bug in java.net.SocketPermission when dealing with cname reverse lookupjava.net.SocketPermission 在处理 cname 反向查找时是否存在错误
【发布时间】:2013-01-14 22:29:18
【问题描述】:

考虑以下 sn-p:

(在本例中为 OpenJDK 6b24-1.11.5-0ubuntu1~12.10.1,这似乎无关紧要,因为 Oracle 和 OpenJDK 的所有 JVM 6&7 都具有相同的行为)

SocketPermission toCheck = new SocketPermission("www.google.ca", "resolve");

SocketPermission checker = new SocketPermission("*.ca:80", "connect");

System.out.println("Result: " + checker.implies(toCheck));

checker = new SocketPermission("*.1e100.net:80", "connect");

System.out.println("Result: " + checker.implies(toCheck));

我得到的结果是:

Result: false
Result: true

问题似乎是 JVM 进行反向查找以验证地址是否与已解析的域实际匹配。

对 www.google.ca 域的挖掘查找显示以下内容:

[rotty@rotty-desktop ~]$ dig www.google.ca ANY

; <<>> DiG 9.8.1-P1 <<>> www.google.ca ANY
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48015
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;www.google.ca.         IN  ANY

;; ANSWER SECTION:
www.google.ca.      114 IN  A   74.125.226.55
www.google.ca.      114 IN  A   74.125.226.56
www.google.ca.      114 IN  A   74.125.226.63
www.google.ca.      74  IN  AAAA    2607:f8b0:400b:801::1018

;; Query time: 27 msec
;; SERVER: 127.0.1.1#53(127.0.1.1)
;; WHEN: Mon Jan 14 17:18:50 2013
;; MSG SIZE  rcvd: 107

此外,获取结果中的第一个地址并执行 DNS 查找会产生:

[rotty@rotty-desktop ~]$ nslookup 74.125.226.55
Server:     127.0.1.1
Address:    127.0.1.1#53

Non-authoritative answer:
55.226.125.74.in-addr.arpa  name = yyz06s06-in-f23.1e100.net.

Authoritative answers can be found from:

这似乎清楚地表明了这个问题。非权威反向查找返回为域定义的第一个(在本例中按位置)别名。

这意味着我需要知道并声明任何可能解析为指定域名基础地址的潜在别名。

为什么 JVM 需要这样的匹配?一个地址确实存在的简单验证是否足以满足“解决”过程?该地址很可能有任意数量的可能反向映射。这怎么可能在实践中发挥作用?

[更新]为了阐明这实际上与默认 java 策略定义的行为相同,请考虑以下附加示例:

Socket socket = new Socket("www.google.ca", 80);

socket.close();

对上述应用以下安全策略:

grant {
    permission java.net.SocketPermission "*.ca:80", "connect";
    //permission java.net.SocketPermission "*.1e100.net:80", "connect";
};

程序执行如下:

java -Djava.security.manager -Djava.security.policy=../security.policy Test

结果:

Exception in thread "main" java.security.AccessControlException: access denied ("java.net.SocketPermission" "www.google.ca" "resolve")
    at java.security.AccessControlContext.checkPermission(AccessControlContext.java:366)
    at java.security.AccessController.checkPermission(AccessController.java:560)
    at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
    at java.lang.SecurityManager.checkConnect(SecurityManager.java:1048)
    at java.net.InetAddress.getAllByName0(InetAddress.java:1203)
    at java.net.InetAddress.getAllByName(InetAddress.java:1127)
    at java.net.InetAddress.getAllByName(InetAddress.java:1063)
    at java.net.InetAddress.getByName(InetAddress.java:1013)
    at java.net.InetSocketAddress.<init>(InetSocketAddress.java:142)
    at java.net.Socket.<init>(Socket.java:208)
    at example.security.SocketSecurityExample.test(SocketSecurityExample.java:13)
    at example.security.SocketSecurityExample.main(SocketSecurityExample.java:9)

将策略文件更改为:

grant {
    //permission java.net.SocketPermission "*.ca:80", "connect";
    permission java.net.SocketPermission "*.1e100.net:80", "connect";
};

导致代码正确执行。

【问题讨论】:

标签: java permissions dns


【解决方案1】:

连接时 JVM 不会执行该操作。它构造一个包含实际主机名/IP 地址的 SocketPermission,并使用 'implies' 检查 .policy 文件中的任何权限是否暗示该权限。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-17
    • 2016-02-21
    • 2021-09-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-15
    • 1970-01-01
    相关资源
    最近更新 更多