web-dev-qa-db-ja.com

Spring BootでHTTP Getを検証およびサニタイズする方法は?

Checkmarxコードスキャナーからこの迷惑なエラーが出続けます。

Method getTotalValue at line 220 of src\Java\com\example\PeopleController.Java 
gets user input for the personName element. This element’s value then flows through
the code without being properly sanitized or validated and is eventually 
displayed to the user. This may enable a Cross-Site-Scripting attack. 

これが私のコードです。必要なすべての検証を実行したと思います。他に何か???

@Slf4j
@Configuration
@RestController
@Validated 

public class PeopleController {

    @Autowired
    private PeopleRepository peopleRepository; 

    @RequestMapping(value = "/api/getTotalValue/{personName}", method = RequestMethod.GET)
    @ResponseBody
    public Integer getTotalValue(@Size(max = 20, min = 1, message = "person is not found") 
    @PathVariable(value="personName", required=true) String personName) {

        PersonObject po = peopleRepository.findByPersonName(
                            Jsoup.clean(personName, Whitelist.basic()));

        try {
            return po.getTotalValue(); 
            } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }  


@ExceptionHandler
    public String constraintViolationHandler(ConstraintViolationException ex) {
        return ex.getConstraintViolations().iterator().next()
                .getMessage();
    } 

} 

いくつかの検証が欠落している必要があります。 Spring BootでHTTP GETを適切に検証する方法

3
john

これらのスキャンツールは誤検知を報告する場合があり、コードの変更が不要な場合があるため、これらのスキャンツールには少し注意する必要があります。私はcheckmarxの専門家ではありませんが、このツールが、使用しているBean検証アノテーションとJsoup.clean(personName, Whitelist.basic())の呼び出しを本当に理解していることを確認してください。

私は必要な検証をすべてやったと思います。ほかに何か???

最初に、コントローラーのアプリケーションレベル入力サニテーションとビジネスレベル入力検証の違いを理解する必要があります。ここで行っているのは2番目の部分であり、最初の設定ではセキュリティの観点から排他的に行われ、通常はアプリケーション全体に対して設定が行われていない可能性があります。

_@Size_アノテーションを使用して入力のサイズを制限していますが、これは不正な文字列(XSS攻撃を引き起こす可能性がある文字列)を保証するものではありません。次に、call Jsoup.clean(personName, Whitelist.basic()))を使用して、このサイズが検証された入力をクリーンアップします。私はその呼び出しが何をするのかわからないので、新しい値がXSS-Safeであることを確認する必要があります。あなたはすぐにその値をDB呼び出しに渡し、次にIntegerを呼び出し元/クライアントに返すので、XSS攻撃の可能性については非常に悲観的ですが、ツールはそう言っています。

いくつかの検証が欠落している必要があります。 Spring BootでHTTP GETを適切に検証する方法

すでに説明したように、入力の検証は通常、ビジネスロジックレベルの入力の検証を意味する用語ですが、入力のサニタイズ/クリーンアップはセキュリティに関するものです。 Spring Boot環境では、これは通常Spring Security APIを使用してXSSフィルターを有効にするか、独自のXSSフィルターを作成してアプリケーションにプラグインすることで行われます。フィルターが最初に来て、コントローラーが後で来るため、コントローラーは常にサニタイズされた値を持ち、そのサニタイズされた値にビジネス検証を適用します。

これは幅広いレベルの回答であり、コードなどの場合はGoogleを使用する場合があります。 XSS攻撃についての詳細を読むこともお勧めします。同じ目標を達成するには複数の方法があることを理解してください。

XSSを防ぐ3つの方法

JavaでのXSS防止

Spring RESTful for Prevent XSSでフィルターを作成する方法

クロスサイトスクリプティング(XSS)攻撃のチュートリアル、例、タイプ、防止

最後のリンクでは、その言及、

この攻撃を防ぐ最初のステップは、入力の検証です。ユーザーの入力が出力に至るまでの道を見つける可能性があるため、ユーザーが入力したものすべてを正確に検証する必要があります。

&あなたはあなたのコードでやっていないので、XSSはないと思います。

編集:

XSSセキュリティには2つの側面があります-最初にサーバー側コードへの悪意のある入力を許可しない&XSSフィルターを使用することで行われます&場合によっては、悪意のある入力を許可しても害はありません(その悪意のある入力をDBまたはAPIレスポンスで戻る)。

2番目の側面は、可能性のあるXSS攻撃についてHTMLクライアントに指示することです(APIクライアントがHTML/UIになることが確実にわかっている場合)、_X-XSS-Protection_ヘッダーを追加する必要があります。これは、以下のコードで実行されます。これにより、ブラウザはXSS保護機能を有効にすることができます(存在する場合)。

@Override protected void configure(HttpSecurity http)が例外をスローします{

_http.headers().xssProtection()....
_

}

http-header "X-XSS-Protection"とは何ですか?

SpringセキュリティのXss保護はデフォルトで有効になっていますか?

最初の側面、つまりフィルターの作成- my this answer とその回答のリンクを参照してください。

Spring Securityが入力サニタリーフィルターを提供していると間違って記述したと思いますが、そうではありません。確認してお知らせします。この質問への回答で言及されている行にカスタムフィルターを記述しました Spring MVCコントローラーでXSSを防ぐ

また、Spring Bootは、サーバー側でHTMLを表示してレンダリングする従来のMVCアプリの記述にも使用されていることを理解する必要があります。 JSON応答(REST APIs)の場合、UIクライアントは何をエスケープし、何をエスケープしないかを制御できます。JSON出力は常にHTMLクライアント、つまりブラウザーに供給されないため、複雑さが生じます。

3
Sabir Khan

JsoupとApache Commonsを使用した優れた(IMHO)ソリューションがあります。他の人の役に立つことを願っています

このクラスを追加

import org.Apache.commons.lang.StringEscapeUtils;
import org.jsoup.Jsoup;
import org.jsoup.safety.Whitelist;

public class SecurityEscape {

    public static String cleanIt(String arg0) {
        return Jsoup.clean(
                StringEscapeUtils.escapeHtml(StringEscapeUtils.escapeJavaScript(StringEscapeUtils.escapeSql(arg0)))
                , Whitelist.basic());
    }


} 

これで、コントローラでこのようにGETまたはPOSTからすべての着信文字列をクリーンアップできます

    @PostMapping("/api/blah") or GET whatever . .. . .  .
    public ResponseEntity<?> testIt(String whatever) { 

String whatever = SecurityEscape.cleanIt(whatever); 

... .. 

このCHECKMARXがこれを言った後IS安全なコード

@Sabir Khanの指導に感謝します

4
john