ここで直面している問題は、URL のさまざまな部分をエンコードするためのさまざまな規則があることです。覚えておくと、URL にはさまざまなエンコード規則を持つ 4 つのセクションがあります。UriBuilder
まず、Java でクラスを使用して URL を作成する必要がある理由を理解します。URL仕様は、核心的な詳細に役立ちます。
問題は、URL 全体がユーザーからの入力として送られてくるため、単純にクエリ パラメータを解析して個別にサニタイズすることはできないということです。2 つのクエリ パラメータを組み合わせて悪意のある入力を作成し、それらを個別にサニタイズしてもうまくいかないからです。場合。
ここでの唯一の実際のオプションはjava.net.URI
.
これを試して:
URI dirtyURI = new URI("http://example.com/alpha?abc=def&phil=key%3dbdj");
String cleanURIStr = enc.canonicalize( dirtyURI.getPath() );
への呼び出しURI.getPath()
は、パーセントでエンコードされていない URL を提供する必要があり、enc.canonicalize()
その段階の後に二重エンコードが検出された場合は、実際には二重にエンコードされた文字列があり、単一にエンコードされた URL 文字列のみを受け入れることを呼び出し元に通知する必要があります。はURI.getPath()
、URL 文字列の各部分にデコード ルールを使用するほどスマートです。
それでも問題が発生する場合、API リファレンスには、URL のさまざまな部分でさまざまなことを行う必要がある場合に備えて、URL の他の部分を抽出する他のメソッドがあります。たとえば、GET リクエストでパラメーターを手動で解析する必要がある場合は、実際にはクエリ文字列自体を返すだけで済み、デコード パスが実行されます。
=============JUNITテストケース============
package org.owasp.esapi;
import java.net.URI;
import java.net.URISyntaxException;
import org.junit.Test;
public class TestURLValidation {
@Test
public void test() throws URISyntaxException {
Encoder enc = ESAPI.encoder();
String input = "http://example.com/alpha?abc=def&phil=key%3dbdj";
URI dirtyURI = new URI(input);
enc.canonicalize(dirtyURI.getQuery());
}
}
=================更新された質問の回答====================
これを回避する方法はありません。 Encoder.canonicalize()
エスケープされた文字シーケンスを縮小された Java 固有の形式に縮小することを目的としています。URL は特殊なケースと見なされる可能性が高いため、意図的に考慮対象から除外された可能性が高いです。ホワイトリストなしであなたのケースを処理する方法は次のとおりですEncoder.canonicalize()
.
上記のコードを使用して、入力の URI 表現を取得します。
ステップ 1: ステップ 2 を除くすべての URI 部分を正規URI.getQuery()
化します。ライブラリ パーサーを使用して、クエリ文字列をデータ構造に解析します。commons の httpclient-4.3.3.jar と httpcore-4.3.3.jar を使用します。次に、次のようにします。
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Iterator;
import java.util.List;
import javax.ws.rs.core.UriBuilder;
import org.apache.http.client.utils.URLEncodedUtils;
import org.junit.Test;
import org.owasp.esapi.ESAPI;
import org.owasp.esapi.Encoder;
public class TestURLValidation
{
@Test
public void test() throws URISyntaxException {
Encoder enc = ESAPI.encoder();
String input = "http://example.com/alpha?abc=def&phil=key%3dbdj";
URI dirtyURI = new URI(input);
UriBuilder uriData = UriBuilder.fromUri(enc.canonicalize(dirtyURI.getScheme()));
uriData.path(enc.canonicalize(enc.canonicalize(dirtyURI.getAuthority() + dirtyURI.getPath())));
println(uriData.build().toString());
List<org.apache.http.NameValuePair> params = URLEncodedUtils.parse(dirtyURI, "UTF-8");
Iterator<org.apache.http.NameValuePair> it = params.iterator();
while(it.hasNext()) {
org.apache.http.NameValuePair nValuePair = it.next();
uriData.queryParam(enc.canonicalize(nValuePair.getName()), enc.canonicalize(nValuePair.getValue()));
}
String canonicalizedUrl = uriData.build().toString();
println(canonicalizedUrl);
}
public static void println(String s) {
System.out.println(s);
}
}
ここで実際に行っているのは、標準ライブラリを使用して inputURL を解析し (したがって、すべての負担を取り除きます)、各セクションを解析した後にパーツを正規化することです。
リストしたコードは、すべてのURL タイプで機能するとは限らないことに注意してください... URL には、スキーム/権限/パス/クエリよりも多くの部分があります。(欠けているのは、userInfo または port の可能性です。これらが必要な場合は、このコードを適宜変更してください。)