このアプリケーションでは、ユーザーがプロフィール写真のURLを指定できます。 URLからデータをフェッチし、サーバーに保存します。ただし、アプリはサーバー側のリクエストフォージェリ(SSRF)に対して脆弱です。file:///etc/passwd
などのURLを指定し、http://localhost:8080/
などのローカルHTTPサービスにアクセスすることもできます。
これを修正する最良の方法は何ですか?私が持っていたいくつかのアイデア:
これは良いスタートのようです-DNSルックアップにTOCTOUの問題があります(ローカルDNSがキャッシュするため、実際には問題ないかもしれません)。
私が持っていた別のアイデアは、インターネットのみを見ることができる制限されたネットワークセグメントにプロキシを配置し、それを介してリクエストを送信することでした。
私はこれをオンラインで調査しましたが、あまり情報がありません。 この記事 はかなり良いです。
これは私が現在使用しているコードです:
if(!url.getProtocol().startsWith("http"))
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();
IOUtils.copy(conn.getInputStream(), out);
HTTPまたはHTTPSを適用し、ローカルアドレスを禁止し、リダイレクトを無効にします。ただし、TOCTOU(チェックの時間、使用の時間)の欠陥がまだあります。