SecurityManagerチェックから明示的な認可へ
無効化されたSecurityManagerチェックを、アプリケーションによる明示的な認可とデプロイ環境での分離に置き換えます。
コード比較
✕ JDK 23 and earlier
SecurityManager manager = System.getSecurityManager();
if (manager != null) {
manager.checkRead(path.toString());
}
return Files.readString(path);
✓ JDK 24+
// Untrusted users must not be able to modify this tree
Path root = allowedRoot.toRealPath();
Path resolved = root.resolve(requested)
.normalize()
.toRealPath();
if (!resolved.startsWith(root)) {
throw new SecurityException(
"Path is outside the allowed root");
}
return Files.readString(resolved);
このコードに問題がありますか? お知らせください。
モダンな方法が優れている理由
明示的なポリシー
認可がアプリケーションロジック内で可視化され、テスト可能になります。
実効性のある分離
プロセス、コンテナ、オペレーティングシステムの境界がアプリケーション全体を保護します。
必須の移行
JDK 24以降ではポリシーを適用できなくなったチェックを削除します。
旧来のアプローチ
SecurityManagerによるチェック
モダンなアプローチ
明示的な認可
JDKバージョン
24
難易度
上級
JDKサポート
SecurityManagerチェックから明示的な認可へ
利用可能
JEP 486によってSecurity Managerが恒久的に無効化されるJDK 24以降では必須です。
仕組み
JEP 486によりJDK 24でSecurity Managerが恒久的に無効化されたため、System.getSecurityManager()を介したチェックでポリシーを適用できるのはJDK 23以前のみです。アプリケーションはドメインロジックでアクセスを明示的に認可する必要があります。信頼できないユーザーがそのツリーを同時に変更できない場合、ファイルシステム上の実際のパスを解決することで、既存のシンボリックリンクが許可されたルートの外へ抜け出すことを防げます。攻撃者が書き込み可能なツリーでは、SecureDirectoryStreamのような競合状態に強いハンドル相対アクセスを使用してください。分離には、プロセス、コンテナ、またはオペレーティングシステムの境界を使用してください。JDK 24では非推奨のAPIが一時的に残されていますが、有効化することはできず、別のプロセス内サンドボックスにも置き換えられていません。
関連ドキュメント
証明