
File-Traversal(パストラバーサル、Path Traversal)の脆弱性は、攻撃者がWebアプリケーションでファイルシステムの権限を迂回して任意のファイルにアクセスできるようにする脆弱性であり、CWE-22に 指定されている攻撃の一種です。
Spring WebFluxはSpring 5で導入されたリアクティブプログラミングをサポートするモジュールで、非同期ノンブロッキングアプリケーションの開発をサポートし、WebFlux.fnは関数型エンドポイントルーティングを提供して、ラムダ式を使用した簡潔で柔軟なルーティング構成をサポートします。
CVE-2024-38819はWebFlux.fn、WebMVC.fnを使用するアプリケーションで発生し、本ドキュメントは当該脆弱性がWebFluxを基準にどのように発生するのかコードの流れを確認し、これに応じた対応策を模索します。
[図 1] FileApplication.java
[図 1]はSpring WebFluxで/static/**に入るすべてのリクエストをサーバーのC:/fileディレクトリから探して配信(Serving)します。ここで
[図 2] PathResourceLookupFunction.class - apply
[図 2] PathResourceLookupFunction - applyはSpring WebFluxで指定されたパスが有効なリソースを指しているか確認し、そのリソースを
[図 3] PathResourceLookupFunction.class - isInvalidPath
[図 3] PathResourceLookupFunction - isInvalidPathを見ると、StringUtils.cleanPath(path).contains("../")という条件が存在しますが、
[図 4] StringUtils.class - cleanPath
[図 4] StringUtils.class - cleanPathを見ると、StringUtils.cleanPath(path)はTOP_PATH("..")を除去した後、パスをpathElementsに入れ、topは0になるため、
[図 5] PathResourceLookupFunction.class - apply - 2
[図 6] PathResourceLookupFunction.class - isResourceUnderLocation
[図 5] のisResourceUnderLocationのcleanPath呼び出しにより、[図 6]を通じてcleanPathによるもう一度の検証が行われ、[図 5]で渡されたパスはC:/file../Windows/System32/drivers/etc/hostsであり、
[図 7] StringUtils.class - cleanPath -2
[図 7] のコードにより、prefixはC:/となり、パスは[図 4]を通じて/Windows/System32/drivers/etc/hostsに変更され、最終リターンは現在はWindowsでC:/fileでテストを実施しましたが、このケースがLinuxでシンボリックリンクと一緒に動作する場合、非常に危険です。
(../../と2回設定した場合は正常ロジックとなり、../と1回の場合のみ脆弱性が発生)

Linuxサーバーでシンボリックリンクと一緒に攻撃
public RouterFunction<ServerResponse> staticResourceRouter() {
return RouterFunctions.resources("/static/**", new FileSystemResource("/app/static/"));
}
シンボリックリンク追加 ln -s /static /app/static/link の後に攻撃

これまでSpring WebFlux環境でFile Traversal(CVE-2024-38819)が実行される流れを確認しました。サーバーの情報が奪取される攻撃方式であるため、 対応策が重要です。そのために、最新バージョンへのアップデート、追加検証ロジックの作成、IPSによる遮断策を提示します。
@Bean
public RouterFunction<ServerResponse> staticResourceRouter() {
return RouterFunctions.resources("/static/**", new FileSystemResource("C:/file"))
.filter((request, next) -> {
String path = request.path();
if (path.contains("..")) {
if(!StringUtils.cleanPath(path).contains("../")) {
return ServerResponse.status(HttpStatus.FORBIDDEN).bodyValue("Vuln path access.");
}
}
return next.handle(request);
});
}
../ 上位パスへの移動を引き起こすURLリクエストをすべて遮断
これまでWebFluxを通じたFile Traversalを確認しました。本脆弱性は、StringUtils.cleanPath()のロジックに起因する問題を認識せずに使用したケースでした。
(POC)
https://github.com/masa42/CVE-2024-38819-POC
(Spring公式)
https://spring.io/security/cve-2024-38819
(CVE-DETAIL)
https://www.cvedetails.com/cve/CVE-2024-38819/
(NIST)
https://nvd.nist.gov/vuln/detail/cve-2024-38819