如果我使用“ localhost”,是否可以保证客户端是本地的? (考虑到我可以编辑系统主机文件)

时间:2018-12-04 16:46:08

标签: java security dns

如果我使用this解决方案:

new ServerSocket(9090, 0, InetAddress.getByName("localhost"))

...并且用户将其系统主机文件更改为以“ localhost”访问我的网站,这是否会阻止非本地客户端的访问?

1 个答案:

答案 0 :(得分:1)

(响应悬赏电话)

与计算机安全性一样,保证取决于攻击者的功能

  1. 攻击者很la脚,一无所知。然后,是的,localhost保证了客户的所在地。

  2. 攻击者具有对系统的登录访问权限,并且可以将SSH运行到外部环境。这样就无法保证-SSH可以通过隧道转发内部端口:

ssh -R *:8080:localhost:9090 some.external.server

在Java服务器的包装盒上执行此命令将导致建立隧道。发送到some.external.server:8080的所有请求都将传递到目标框的localhost:9090

如今,VPS几乎不收费,因此攻击者可以轻松租用这种外部设备并将其用作您的本地主机和全世界之间的代理。

  1. 您可以尝试通过过滤掉Host标头不是localhost的所有请求来保护服务器。通过在转发链中包含标头重写代理(例如nginx),可以很容易地对付它。

摘要

如您所见,保证意味着必须严格限制目标框中的用户:没有转发软件。这意味着拒绝用户访问ssh之类的系统实用程序,或者以用户特权安装和/或运行它们。除非该机顶盒是没有任何用户登录或软件重新配置的机顶盒,否则这种情况极不可能发生。

本地主机地址

对该问题的第一条评论提出了一个使用localhost名称解析的技巧:

用户可能会覆盖localhost,使其不再是127.0.0.1

想法是将记录放置到/etc/hostsc:\Windows\System32\Drivers\etc\hosts上,以将localhost名称绑定到另一个IP地址。

如果您的设备具有与地址1.2.3.4的以太网连接,则该行

1.2.3.4 localhost

可能会导致localhost地址的更改。如果发生这种情况,则该行

new ServerSocket(9090, 0, InetAddress.getByName("localhost"))

将绑定外部网络接口上的端口9090,该端口可从包装箱外部访问。

我在Ubuntu 18.04上尝试了此方法,并且有效。我已成功连接到Pasific另一侧框中的localhost上运行的应用。

但是

从前,MS Windows开发人员曾经将localhost硬编码为127.0.0.1Here is the Medium post about that

我检查了Windows 10框。已确认:localhost解析为127.0.0.1。测试程序

package org.example;
import java.net.*;
import java.io.*;

public class TryLocalhost {
    public static void main(String[] args) throws IOException {

        System.out.println("localhost: " + InetAddress.getByName("localhost"));
    }
}

产生

localhost: localhost/127.0.0.1

hosts文件试图将localhost绑定到本地链接地址

# localhost name resolution is handled within DNS itself.
#   127.0.0.1       localhost
#   ::1             localhost
192.168.0.198 localhost

此评论来自Microsoft。