WebVulnerabilities

デシリアライゼーションによる攻撃について

概要

シリアライゼーション攻撃は、オブジェクトをシリアライズ(データとして保存や転送できる形式に変換)する処理を悪用して、不正なデータをデシリアライズ(シリアライズされたデータを元のオブジェクトに戻す)する際に、攻撃者が任意のコードを実行する脆弱性です。この攻撃は、シリアライズされたデータが信頼できないソースから提供されたり、不適切に検証された場合に発生します。

シリアライゼーション攻撃は、以下のリスクを伴います:


脆弱性を持つコードの例と攻撃手法

PHP

脆弱なコード例:

<?php
class User {
    public $isAdmin = false;
}

$user = unserialize($_GET['data']);

if ($user->isAdmin) {
    echo "Admin access granted";
} else {
    echo "User access";
}
?>

攻撃手法:

Python(pickle)

脆弱なコード例:

import pickle
from flask import Flask, request

app = Flask(__name__)

@app.route('/load')
def load_object():
    data = request.args.get('data')
    obj = pickle.loads(data.encode('latin1'))
    return str(obj)

if __name__ == '__main__':
    app.run()

攻撃手法:

Node.js(Serialized-JavaScript)

脆弱なコード例:

const express = require('express');
const app = express();

app.get('/load', (req, res) => {
    const data = JSON.parse(req.query.data);
    res.send(`Hello, ${data.name}`);
});

app.listen(3000);

攻撃手法:

Java(ObjectInputStream)

脆弱なコード例:

import java.io.ObjectInputStream;
import java.io.FileInputStream;

public class DeserializeUser {
    public static void main(String[] args) {
        try {
            ObjectInputStream in = new ObjectInputStream(new FileInputStream("user.ser"));
            User user = (User) in.readObject();
            in.close();
            if (user.isAdmin()) {
                System.out.println("Admin access granted");
            } else {
                System.out.println("User access");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

攻撃手法:


防止策

  1. 信頼できないデータのデシリアライズを避ける:
    • シリアライズされたデータは信頼できるソースからのみ受け取るようにし、外部から提供されたシリアライズデータを直接デシリアライズしないようにします。
  2. シリアライゼーションの代替手法を使用:
    • 可能な限り、シリアライズを使用せず、JSONなどのより安全なデータ形式を使用してデータを交換します。ただし、JSONも適切にサニタイズする必要があります。
  3. デシリアライズ時のデータ検証:
    • デシリアライズされたオブジェクトのタイプやプロパティを厳密に検証し、予期しないオブジェクトが含まれていないかを確認します。
  4. セキュリティパッチとライブラリの最新化:
    • 使用しているシリアライゼーションライブラリやフレームワークの最新のセキュリティパッチを適用し、既知の脆弱性から守るようにします。
  5. シリアライズされたデータの署名:
    • シリアライズされたデータにデジタル署名を追加し、その署名を検証することで、データの改ざんを防ぎます。

まとめ: シリアライゼーションによる攻撃は、信頼できないデータをデシリアライズする際に非常に危険です。信頼できないソースからのデシリアライズを避ける、代替手法を使用する、データの検証を徹底するなどの対策を講じることで、この脆弱性を防ぐことができます。シリアライズの使用を必要とする場合には、セキュリティ対策を強化して、システムの安全性を確保することが重要です。