スプリングブート - URL内にあり、エスケープされている場合、スプリングブートデコード%エラーが発生します

okwaves2024-01-24  5

バージョン情報:

サーバーのバージョン: Apache Tomcat/9.0.17 サーバー構築: 2019 年 3 月 13 日 15:55:27 UTC サーバー番号: 9.0.17.0 OS名:Windows8.1 OSバージョン:6.3 アーキテクチャ: amd64 JVM バージョン: 1.8.0_40-b25

スプリングブート-2.1.4 スプリングコア-5.1.6

次のような HTML ページがあります: localhost/example/37%.html (申し訳ありませんが、編集ページがリンクに自動的に変更し、% の後に 25 を追加するため、URL を http// で始めることはできません) この URL にアクセスすると、HTTP ステータス 400 というエラーが発生しました。 % はエスケープ文字であるため、そのはずです。 そこで URL を localhost/example/37%25.html に変更しました。 今回は、新しいエラーが発生しました:

ホワイトラベルのエラーページ このアプリケーションには /error の明示的なマッピングがないため、これはフォールバックとして表示されます。 2020年9月3日木 09:25:13 CST予期しないエラーが発生しました (タイプ = 内部サーバー エラー、ステータス = 500)。 URLDecoder: エスケープ (%) パターンに不正な 16 進文字が含まれています - 入力文字列の場合: ".h"

Tomcat コンソールを確認したところ、次のエラー メッセージが出力されました。

2020-09-03 09:25:12 [http-nio-8080-exec-3] ERROR 
o.s.b.w.s.support.ErrorPageFilter - Forwarding to error page from request [/37%.html] due to exception [URLDecoder: Illegal hex characters in escape (%) pattern - For input string: ".h"]
java.lang.IllegalArgumentException: URLDecoder: Illegal hex characters in escape(%) pattern - For input string: ".h" 
at java.net.URLDecoder.decode(URLDecoder.java:194)  
at org.springframework.web.servlet.resource.PathResourceResolver.isInvalidEncodedPath(PathResourceResolver.java:285)
at org.springframework.web.servlet.resource.PathResourceResolver.isResourceUnderLocation(PathResourceResolver.java:254)

tomcat (またはブラウザ) は %25 を % にデコードしたようですが、springboot はまだ % を再度デコードしています (PathResourceResolver.java)

これがバグの問題なのか、それともスプリングブートで URL に % を許可しない正しい方法なのかわかりません。



------------------------

面白いものを見つけました。

現在、2 つの Web ページがあり、1 つは 37%.html という名前で、もう 1 つは 37%25.html という名前です

springb のロジックに従います% を 2 回デコードするので、次の URL にアクセスしました。

localhost/example/37%2525.html

すると、37%.html が表示されますが、37%25.html も表示されます。

それで、スプリングブートで % をデコードする回数、または方法は何ですか ???

その後、Springboot で 2 つのクラス ファイルが見つかりました。 ResourceHttpRequestHandler.java PathResourceResolver.java

それらはすべて isInvalidEncodedPath() という名前の関数を持っています

コードはここにあります:

ResourceHttpRequestHandler.isInvalidEncodedPath(パス)

private boolean isInvalidEncodedPath(String path) {
    if(path.contains("%")) {
        try {
            String decodedPath = URLDecoder.decode(path, "UTF-8");
            if(this.isInvalidPath(decodedPath)) {
                return true;
            }

            decodedPath = this.processPath(decodedPath);
            if(this.isInvalidPath(decodedPath)) {
                return true;
            }
        } catch (UnsupportedEncodingException | IllegalArgumentException var3) {
            ;
        }
    }

    return false;
}

PathResourceResolver.isInvalidEncodedPath(resourcePath)

private boolean isInvalidEncodedPath(String resourcePath) {
    if(resourcePath.contains("%")) {
        try {
            String decodedPath = URLDecoder.decode(resourcePath, "UTF-8");
            if(decodedPath.contains("../") || decodedPath.contains("..\")) {
                this.logger.warn("Resolved resource path contains encoded \"../\" or \"..\\": " + resourcePath);
                return true;
            }
        } catch (UnsupportedEncodingException var3) {
            ;
        }
    }

    return false;
}   

何か違うものが見えますか??どちらも URLDecoder.decode(resourcePath, "UTF-8") を実行しますが、異なる例外をキャッチします。

URL にアクセスすると、springboot は次の順序で関数を呼び出します。

1 ResourceHttpRequestHandler.isInvalidEncodedPath(パス) 2 PathResourceResolver.isInvalidEncodedPath(resourcePath)

したがって、ResourceHttpRequestHandler.isInvalidEncodedPath(path) で /37%25.html にヒットすると、tomcat (またはブラウザ) が %25 を % にデコードするため、/37%.html が取得されます。次に URLDecoder.decode("/37%.html", "UTF-8") を実行すると、IllegalArgumentException がトリガーされ、キャッチされますが、何もせず、false を返します。 PathResourceResolver.isInvalidEncodedPath(resourcePath),URLDecoder.decode("/37%.html", "UTF-8") で、IllegalArgumentException をトリガーし、キャッチされず、例外をスローします。

ResourceHttpRequestHandler.isInvalidEncodedPath(path) で /37%2525.html にヒットすると、/37%25.html, URLDecoder.decode("/37%25.html", "UTF-8"; が取得されます。 )、問題ない。 PathResourceResolver.isInvalidEncodedPath(resourcePath)、URLDecoder.decode("/37%25.html"、"UTF-8")、これも問題ありません。その後、37%25.html を表示します。

「/37%.html」とだけ入力すると、400 エラー、無効な URI: isHexDigit が表示されます。

そのため、残念ながら % char を含む URL には正しくアクセスできません。

共有 フォローする

2020 年 9 月 7 日 6:17 に回答

スティーブン01997

スティーブン01997

1

1

銅バッジ 1 個

1

ああ、もう一つ興味深いことがありました。 IDEA でのデバッグに jrebel を使用している場合、エラーは表示されません。どのページも良好です。 PathResourceResolver.isInvalidEncodedPath(resourcePath) が呼び出されないためです。理由はわかりません.... (jrebel バージョン 2018.1.6)

– スティーブン01997

2020 年 9 月 7 日 6:28

総合生活情報サイト - OKWAVES
総合生活情報サイト - OKWAVES
生活総合情報サイトokwaves(オールアバウト)。その道のプロ(専門家)が、日常生活をより豊かに快適にするノウハウから業界の最新動向、読み物コラムまで、多彩なコンテンツを発信。