CodeZine(コードジン)

特集ページ一覧

Javaのデシリアライズに関する問題への対策

Javaのデシリアライズに潜むセキュリティ問題(後編)

  • LINEで送る
  • このエントリーをはてなブックマークに追加

目次

3. その他、デシリアライズ処理を悪用した攻撃の影響を軽減するための参考情報

 その他、デシリアライズ処理を悪用した攻撃の影響を軽減するための対策を、参考までにいくつかご紹介する。

SecurityManagerによりアプリケーションが可能な動作を制限する

 デシリアライズ時にJavaのセキュリティ機構であるSecurityManagerを使用して、アプリケーションに許可する動作を制限する。これにより、意図しないオブジェクトがデシリアライズされて悪意あるコード(OSコマンドなど)が実行された場合においても、システムへの影響を軽減できる場合がある。詳細はセキュアコーディングスタンダードSER04-Jを参照されたい。

 なお、SecurityManagerによるセキュリティチェックはAPIを使ってプログラム内で行う以外にもJVMオプション" -Djava.security.manager"によって有効化することもできる。

 以下は、デシリアライズ処理を悪用するように細工したクラスを、SecurityManagerを有効にしてデシリアライズした結果の例だ。セキュリティ例外が発生し、細工したコードの実行は行われない。

AnnotationInvocationHandlerクラスをSecurityManagerを有効にしてデシリアライズした場合:

 通常外からの呼び出しができないクラスをデシリアライズしようとして、セキュリティ例外が発生。

java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessClassInPackage.sun.reflect.annotation")
    at java.security.AccessControlContext.checkPermission(AccessControlContext.java:457)
    at java.security.AccessController.checkPermission(AccessController.java:884)
    at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
OSコマンドを実行するクラスをSecurityManagerを有効にしてデシリアライズした場合:

 許可されていないファイルにアクセスしようとして、セキュリティ例外が発生。

Exception in thread "main" java.security.AccessControlException: access denied ("java.io.FilePermission" "<<ALL FILES>>" "execute")
    at java.security.AccessControlContext.checkPermission(AccessControlContext.java:457)
    at java.security.AccessController.checkPermission(AccessController.java:884)
    at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
    at java.lang.SecurityManager.checkExec(SecurityManager.java:799)
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1018)
    at java.lang.Runtime.exec(Runtime.java:620)

 なお、デシリアライズ時に悪意あるコード(OSコマンドなどの外部プロセス)が実行された場合、Javaアプリケーションを実行しているユーザの権限で実行される。OSレベルでの対策として、アプリケーションの実行ユーザに対してアプリケーションの実行に必要な最小限の権限のみ与えることで、意図しないオブジェクトがデシリアライズされ、悪意あるコードが実行された場合においても、システムへの影響を軽減できる場合がある。

シリアライズデータを保護する

 シリアライズデータを外部から受け取っている場合、盗聴や改ざんを受ける可能性がある。シリアライズデータにはクラスやオブジェクトの情報などが含まれるため、シリアライズデータをやりとりする通信を傍受するなどにより、攻撃に有用な情報を入手される可能性がある。外部(特にインターネット)から受け取ったデータをデシリアライズする場合は、オブジェクトの正当性、機密性を保証するために、シリアライズ対象オブジェクトに署名後、暗号化を行うことも有効な対策となる。詳細はセキュアコーディングスタンダードSER02-Jを参照のこと。また、シリアライズデータをやりとりする通信を認証や暗号化で保護することも対策の一つとして考えられる。

おわりに

 昨年11月に話題となったApache Commons Collectionsライブラリの脆弱性と攻撃手法を踏まえ、外部から受け取ったデータをデシリアライズする際に発生し得るセキュリティ上の問題とその対策についての解説を行った。

 シリアライズデータを受け取るサービスがインターネットに公開されており、認証なしでアクセスできる場合は特に注意が必要だ。可能であれば、信頼できない接続元からアクセスできないように制限することをお勧めする。また、認証を行っていても、ID/パスワードが弱い場合は、突破されてしまう可能性があるので、ID/パスワードの見直しをご検討いただきたい。

 信頼できないデータのデシリアライズに関する脆弱性は、共通脆弱性タイプ(CWE)ではCWE-502(Deserialization of Untrusted Data)として定義されており、過去の例では、本記事で解説したCommons Collectionsライブラリの脆弱性の他、CVE-2012-0507 AtomicReferenceArrayクラスにおけるデシリアライズに関する脆弱性などが該当する。また、Java以外にもRuby、PHP、Pythonなどの言語仕様に起因して発生し得る脆弱性であり、この機会に、アプリケーションがセキュアな実装になっているかをご確認いただければと思う。

参考情報



  • LINEで送る
  • このエントリーをはてなブックマークに追加

バックナンバー

連載:Javaのデシリアライズに潜むセキュリティ問題

著者プロフィール

  • 藤本 万里子(JPCERT コーディネーションセンター)(フジモト マリコ)

    一般社団法人JPCERTコーディネーションセンター 早期警戒グループ 情報セキュリティアナリスト。 前職では、国内企業においてソフトウエアの開発や内部統制のためのシステム開発等を担当。 2015年4月、JPCERTコーディネーションセンター早期警戒グループに情報セキュリティアナリストとして着任。主...

あなたにオススメ

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5