How to avoid this sonar security violation 'Security – URLConnection Server-Side Request Forgery (SSRF) and File Disclosure'?

huangapple 未分类评论46阅读模式
英文:

How to avoid this sonar security violation 'Security - URLConnection Server-Side Request Forgery (SSRF) and File Disclosure'?

问题

我按照这里的指示进行了操作:

https://rules.sonarsource.com/java/tag/injection/RSPEC-5144

以及这里的内容:

https://security.stackexchange.com/questions/123655/preventing-server-side-request-forgeries-in-java

但是这两种解决方案都没有消除漏洞。

我不知道还能做什么。有什么想法,甚至可以指出问题出在哪里。

我的代码中存在安全违规的部分:

...

    String vmUrl = TerraformStateService.findFqdnForVM(Long.parseLong(subid), workspace, vmName);
    String jupyterUrl = vmUrl + "/hub";
    URL url = new URL(jupyterUrl);

    try {
        HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection();
        try {
            SSLService.setupSSL(keystoreCred, httpConnection);
            httpConnection.setRequestMethod("GET");
            if (httpConnection.getResponseCode() == 200 || httpConnection.getResponseCode() == 403) {
                return true;
            }
        } finally {
            httpConnection.disconnect();
        }
...

**请注意,findFqdnForVM 从我们这一端保存的状态文件中获取 URL。**

以下是我尝试修复它的失败尝试:

...

    String str = TerraformStateService.findFqdnForVM(Long.parseLong(subid), workspace, vmName);
    try {
        if (!str.startsWith(CommonConstants.URL_PREFIX_WHITELIST)) {
            throw new Exception();
        }
        if (!str.endsWith(CommonConstants.URL_WHITELIST)) {
            throw new Exception();
        }
        URL url = new URL(str);
        if (!url.getProtocol().startsWith("http")) {
            throw new Exception();
        }
        if (!url.getHost().equalsIgnoreCase(CommonConstants.URL_WHITELIST)) {
            throw new Exception();
        }
        if (!url.getAuthority().equalsIgnoreCase(CommonConstants.URL_WHITELIST)) {
            throw new Exception();
        }
        InetAddress inetAddress = InetAddress.getByName(url.getHost());
        if (inetAddress.isAnyLocalAddress() || inetAddress.isLoopbackAddress() || inetAddress.isLinkLocalAddress()) {
            throw new Exception();
        }
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setInstanceFollowRedirects(false);
        conn.connect();
        try {
            SSLService.setupSSL(keystoreCred, conn);
            conn.setRequestMethod("GET");
            if (conn.getResponseCode() == 200 || conn.getResponseCode() == 403) {
                return true;
            }
        } finally {
            conn.disconnect();
        }
...

我不确定在这里有什么危险,我根据一个只包含单个端点的白名单进行了检查。这怎么可能不安全呢?
英文:

I followed directions here.

https://rules.sonarsource.com/java/tag/injection/RSPEC-5144

As well as from here.

https://security.stackexchange.com/questions/123655/preventing-server-side-request-forgeries-in-java

Neither solutions worked to get rid of the vulnerability.

I don't know what else to do. Any ideas, or even pointers to what is wrong.

My code which has the Security Violation.

,,,

String vmUrl = TerraformStateService.findFqdnForVM(Long.parseLong(subid), workspace, vmName);
String jupyterUrl = vmUrl + "/hub";
URL url = new URL(jupyterUrl);

try {
    HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection();
    try {
        SSLService.setupSSL(keystoreCred, httpConnection);
        httpConnection.setRequestMethod("GET");
        if (httpConnection.getResponseCode() == 200 || httpConnection.getResponseCode() == 403) {
            return true;
        }
    } finally {
        httpConnection.disconnect();
    }

,,,

Note the findFqdnForVM gets the url from a state file saved on our end.

Here's my failed attempt at fixing it.

'''

String str = TerraformStateService.findFqdnForVM(Long.parseLong(subid), workspace, vmName);
try {
if (!str.startsWith(CommonConstants.URL_PREFIX_WHITELIST)){
    throw new Exception();
}
if (!str.endsWith(CommonConstants.URL_WHITELIST)){
    throw new Exception();
}
URL url = new URL(str);
if(!url.getProtocol().startsWith("http"))
    throw new Exception();
if (!url.getHost().equalsIgnoreCase(CommonConstants.URL_WHITELIST)){
    throw new Exception();
}
if (!url.getAuthority().equalsIgnoreCase(CommonConstants.URL_WHITELIST)) {
    throw new Exception();
}
InetAddress inetAddress = InetAddress.getByName(url.getHost());
if(inetAddress.isAnyLocalAddress() || inetAddress.isLoopbackAddress() || inetAddress.isLinkLocalAddress())
    throw new Exception();
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setInstanceFollowRedirects(false);
conn.connect();
try {
    SSLService.setupSSL(keystoreCred, conn);
    conn.setRequestMethod("GET");
    if (conn.getResponseCode() == 200 || conn.getResponseCode() == 403) {
        return true;
    }
} finally {
    conn.disconnect();
}

'''

I'm not sure how there is any danger here, I check against a whitelist which has a single endpoint. How can that not be secure?

huangapple
  • 本文由 发表于 2020年7月24日 01:03:04
  • 转载请务必保留本文链接:https://java.coder-hub.com/63059523.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定