SV.SSRF.URI

無効化されたユーザー入力に基づく URI。

SV.SSRF.URI チェッカーは、Java Web サーバーアプリケーションが、アップストリームコンポーネントから URL または同様のリクエストを受信し、この URL のコンテンツを取得しながらも、予期された送信先にリクエストが確実に送信されるようにしない場合にフラグを立てます。

リリース 2023.2 の時点で、このチェッカーは Jakarta EE をサポートしています。

脆弱性とリスク

サーバー側のリクエストフォージェリ (SSRF) は、アプリケーションを悪用して内部または外部のネットワーク、あるいはマシン自身とやりとりする、攻撃ベクトルです。このベクトルが可能になる要因の 1 つには、さまざまなタイプの URL を誤って取り扱うことがあります。次に例を示します。

  • 外部サーバー上の画像ファイル。たとえば、ユーザーはアバターの画像に URL を入力して、アプリケーションをダウンロードして使用します。
  • カスタム Webhook。ユーザーは Webhook ハンドラーまたはコールバック URL を指定します。
  • 特定の機能を提供するために別のサービスとやりとりすための内部リクエスト。多くの場合、ユーザーデータは処理のために送信され、不十分に取り扱われた場合、インジェクション攻撃が発生する可能性があります。

SSRF は HTTP プロトコルに限定されないことに注意してください。通常、最初のリクエストは HTTP ですが、アプリケーション自身が 2 番目のリクエストを実行する場合は、さまざまなプロトコル (FTP、SMB、SMTP など) またはスキーム (file://、phar://、gopher://、data://、dict:// など) を使用できます。

アプリケーションが XML eXternal Entity (XXE) インジェクションに脆弱である場合、SSRF 攻撃を実行するために悪用される可能性があります

軽減と防止

提供された IP アドレスが、識別され信頼されたアプリケーションのいずれかの IP アドレスに属していることを確認します。

脆弱コード例

コピー
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;

public class SV_SSRF_URI_POSITIVE_JAKARTA {
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException,URISyntaxException, InterruptedException {
        HttpClient client = HttpClient.newHttpClient();
        String url = req.getParameter("uri");
        URI uri = new URI(url);
        // BAD: a request parameter is incorporated without validation into a Http request
        HttpRequest r = HttpRequest.newBuilder(uri).build();
        client.send(r, null);
    }
}

この例では、req.getParameter("uri") を使用することで HttpServletRequest から抽出された String URL パラメーターが、HttpRequest 接続のために検証なしで使用されています。Klocwork は、13 行目で欠陥を報告し、「URI オブジェクトの一部として使用された無効化されたユーザー入力」を示します。

修正コード例

コピー
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;

public class SV_SSRF_URI_POSITIVE_JAKARTA {
   protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, URISyntaxException, InterruptedException {
      HttpClient client = HttpClient.newHttpClient();

      // GOOD: the request parameter is validated against a known fixed string or valid source of IP address
      String url = req.getParameter("uri");
      if (VALID_URI.equals(url)) {
       URI uri = new URI(url);
       HttpRequest r = HttpRequest.newBuilder(uri).build();
       client.send(r, null);
     }
  }

修正されたこの例では、req.getParameter("uri") を使用することで、HttpServletRequest から抽出された URL パラメーターが、HttpRequest 接続のために使用される前に、信頼できる URL に対して検証されるため、Klocwork は欠陥を報告しなくなります。

拡張機能

このチェッカーは、プロジェクトで使用されている保護された API へのアクセスがユーザーに承認されているかをチェックするように調整できます。この調整は、.jkb ファイル内の @CheckerParam オプションを使用して行うことができます。詳細については、Java 解析のチューニングを参照してください。