mcpField
O
openharmony-security-review

openharmony-security-review

github.com/openharmonyinsightセキュリティ35140 回インストール11 週間前に更新
リポジトリ

openharmony-security-review について

openharmony-security-review は、OpenHarmony の C++ システムサービスを対象とする構造化されたセキュリティレビュー用スキルです。IPC やネットワーク入力、並行処理、機密情報のログ出力、権限確認のリスクを調べます。

主な機能

  1. 01IPC のデシリアライズと境界を確認
  2. 02共有状態のロックと競合をレビュー
  3. 03デッドロックと TOCTOU のリスクを特定
  4. 04ログの機密情報漏えいを確認
  5. 05権限検証をレビュー

活用シーン

  1. 01MessageParcel データを扱う OpenHarmony サービスのレビュー
  2. 02サービス状態への並行アクセスの監査
  3. 03サービスログにおける個人情報露出の確認
  4. 04特権操作の権限チェックの評価

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/openharmonyinsight/openharmony-skills --skill openharmony-security-review

インストール後、Claude Code で/openharmony-security-reviewを入力して読み込まれたか確認します。

詳細

OpenHarmony のセキュリティレビュー

概要

OpenHarmony のシステムサービスは高い権限で実行され、IPC やネットワークインターフェースを介して信頼できない入力を処理します。このスキルでは、外部入力の処理、マルチスレッドの競合状態、機密情報の漏えい、権限検証という4つの重要な領域で、重大なセキュリティ脆弱性を特定するための体系的なアプローチを紹介します。

使用する場面

digraph when_to_use {
    "Reviewing OpenHarmony code?" [shape=diamond];
    "Is it C++ system service?" [shape=diamond];
    "Handles IPC/network data?" [shape=diamond];
    "Has shared state?" [shape=diamond];
    "Logs data?" [shape=diamond];
    "Use this skill" [shape=box];
    "Different skill needed" [shape=box];

    "Reviewing OpenHarmony code?" -> "Different skill needed" [label="no"];
    "Reviewing OpenHarmony code?" -> "Is it C++ system service?" [label="yes"];
    "Is it C++ system service?" -> "Different skill needed" [label="no"];
    "Is it C++ system service?" -> "Handles IPC/network data?" [label="yes"];
    "Handles IPC/network data?" -> "Use this skill" [label="yes"];
    "Handles IPC/network data?" -> "Has shared state?" [label="no"];
    "Has shared state?" -> "Use this skill" [label="yes"];
    "Has shared state?" -> "Logs data?" [label="no"];
    "Logs data?" -> "Use this skill" [label="yes"];
    "Logs data?" -> "Different skill needed" [label="no"];
}

このスキルを使用する場面:

  • OpenHarmony の C++ システムサービスコード(xxxService、xxxStub の実装)をレビューする場合
  • コードが IPC(MessageParcel)またはネットワークデータ(JSON/XML/Protobuf)を処理する場合
  • コードが共有状態にマルチスレッドでアクセスする場合
  • コードがユーザーデータやポインターをログに記録する場合
  • コードが権限を検証する、または保護対象のリソースにアクセスする場合

以下の用途には使用しないでください:

  • アプリケーション層のコード(代わりに標準的なセキュアコーディングの手法を使用してください)
  • OpenHarmony 以外の C++ コード(代わりに一般的なセキュリティレビューのスキルを使用してください)
  • パフォーマンスの最適化(別のスキルを使用してください)

コードの追跡方針

ヘッダーファイルが入力の場合(.h/.hpp): 対応する xxxService.cpp と xxxStub.cpp を分析します
Stub ファイルが入力の場合(xxxStub.cpp): 分析対象を xxxService.cpp(コアロジックと共有状態)に広げます
外部呼び出し: コンポーネント間の並行処理リスクとして指摘し、別途レビューします

クイックリファレンス:重大な脆弱性のチェックリスト

カテゴリ重要なチェック項目重大度
IPC のデシリアライズすべての MessageParcel の読み取りで成功を確認している高
論理検証デシリアライズ後に配列の長さ/インデックスを検証している高
整数の境界値サイズ変数:0 <= size <= MAX_ALLOWED_BUFFER高
オブジェクトのライフサイクルRemoteObjects/fd を使用前に検証している(nullptr チェック)高
パーサーのセキュリティネットワークパーサーが不正な入力を拒否し、再帰攻撃を防いでいる高
コンテナーのスレッドセーフ性すべてのコンテナー操作が保護されている(読み取り/書き込み、書き込み/書き込み)高
イテレーターの無効化**反復処理中に変更していない高
ロックの一貫性共有状態へのすべてのアクセスがミューテックスで保護されている高
デッドロックのリスクネストしたロックを一貫した順序で取得している高
TOCTOU状態確認の直後に、それに依存する処理を実行している高
ログ内の PII電話番号、連絡先、SMS、生体認証情報をログに記録していない高
ログ内の入力イベント**生の KeyEvent、タッチ座標、画面境界をログに記録していない高
ポインターアドレスログ内で %p または &variable を使用していない(ASLR の回避防止)高
権限チェックすべての特権操作で呼び出し元の権限を検証している高

1. 外部入力の処理(IPC とネットワーク)

1.1 IPC のデシリアライズの完全性

ルール: すべての MessageParcel の読み取り操作で、戻り値を確認する必要があります。

アンチパターン:

// ❌ VULNERABLE: No validation
parcel.ReadInt32(val);
int32_t size = parcel.ReadInt32();

必須パターン:

// ✅ SECURE: Always check return value
if (!parcel.ReadInt32(val)) {
    HILOG_ERROR("Failed to read value");
    return ERR_INVALID_DATA;
}
if (!parcel.ReadInt32(size)) {
    HILOG_ERROR("Failed to read size");
    return ERR_INVALID_DATA;
}

検証: 読み取ったデータサイズが想定される型のサイズと一致することを確認します。読み取りに失敗した場合は、直ちに処理を停止します。

1.2 デシリアライズ後の論理検証

ルール: デシリアライズ後、値を使用する前に論理的な範囲内にあることを検証します。

攻撃ベクトル: 攻撃者が size = 0xFFFFFFFF を送信し、メモリ枯渇や new char[size] における整数オーバーフローを引き起こします。

アンチパターン:

// ❌ VULNERABLE: No bounds validation
int32_t size = parcel.ReadInt32();
std::vector<char> buffer(size);  // May allocate gigabytes or overflow

必須パターン:

// ✅ SECURE: Validate bounds immediately
int32_t size = 0;
if (!parcel.ReadInt32(size)) {
    return ERR_INVALID_DATA;
}
constexpr int32_t MAX_ALLOWED_BUFFER = 1024 * 1024;  // 1MB
if (size < 0 || size > MAX_ALLOWED_BUFFER) {
    HILOG_ERROR("Invalid size: %{public}d", size);
    return ERR_INVALID_DATA;
}
std::vector<char> buffer(size);

検証対象: 配列の長さ、インデックス、ループカウンター、バッファーサイズ

1.3 オブジェクトのライフサイクルと所有権

ルール: RemoteObjects とファイルディスクリプターは、使用前に検証する必要があります。

必須パターン:

// ✅ SECURE: Validate before use
if (remoteObject == nullptr) {
    HILOG_ERROR("Received null RemoteObject");
    return ERR_NULL_OBJECT;
}
if (fd < 0) {
    HILOG_ERROR("Invalid file descriptor");
    return ERR_INVALID_FD;
}
1.4 外部ネットワークデータ

ルール: ネットワークパーサーは不正な入力を拒否し、再帰攻撃を防ぐ必要があります。

チェック項目:

  • JSON パーサーが不正な入力を拒否するように設定されている
  • 「Zip Bomb」攻撃に対する保護がある
  • 深くネストした再帰に制限がある

2. マルチスレッドと並行処理

2.1 コンテナのスレッドセーフ性(最優先)

ルール: コンテナに対するすべての並行操作は、ロックで保護する必要があります。

重大なリスク:

  • 読み取り/書き込み: あるスレッドが読み取っている間に、別のスレッドが書き込む
  • 書き込み/書き込み: 複数のスレッドが同時に変更する
  • イテレーターの無効化: あるスレッドが反復処理している間に、別のスレッドが変更する

アンチパターン:

// ❌ VULNERABLE: Unprotected concurrent access
std::vector<int> items_;

void AddItem(int item) {
    items_.push_back(item);  // Unsafe if called concurrently
}

void ProcessItems() {
    for (auto& item : items_) {  // Iteration
        // If AddItem called here, iterator invalidates → CRASH
    }
}

必須パターン:

// ✅ SECURE: All access protected
std::vector<int> items_;
std::mutex itemsMutex_;

void AddItem(int item) {
    std::lock_guard<std::mutex> lock(itemsMutex_);
    items_.push_back(item);
}

void ProcessItems() {
    std::lock_guard<std::mutex> lock(itemsMutex_);
    for (auto& item : items_) {
        // Safe - lock held during iteration
    }
}

精査対象のコンテナ型: std::vector、std::map、std::list、std::unordered_map、std::string

精査対象の操作: push_back、insert、erase、operator[]、at、反復処理

2.2 ロック機構

ルール: すべての共有リソースを一貫して保護する必要があります。

保護が必要な共有リソース:

  • グローバル変数/静的変数
  • クラスメンバー変数
  • スレッド間で共有されるヒープ割り当てオブジェクト

ロック型: std::mutex、std::shared_mutex、SpinLock

アンチパターン:

// ❌ VULNERABLE: Inconsistent protection
class Service {
    std::map<int, Data> dataMap_;
    std::mutex mutex_;

    void Update(int key, const Data& data) {
        std::lock_guard<std::mutex> lock(mutex_);
        dataMap_[key] = data;
    }

    Data Lookup(int key) {
        // ❌ NO LOCK - race condition with Update
        return dataMap_[key];
    }
};

必須パターン:

// ✅ SECURE: Consistent protection
class Service {
    std::map<int, Data> dataMap_;
    std::mutex mutex_;

    void Update(int key, const Data& data) {
        std::lock_guard<std::mutex> lock(mutex_);
        dataMap_[key] = data;
    }

    Data Lookup(int key) {
        std::lock_guard<std::mutex> lock(mutex_);
        return dataMap_[key];
    }
};
2.3 デッドロックの防止

ルール: ロックをネストする場合は、デッドロックのリスクを評価してください。

デッドロックの条件:

  • 異なるコードパスで、複数のロックが異なる順序で取得される
  • ロックを保持したまま、ロックを取得する可能性のある外部関数を呼び出す

アンチパターン:

// ❌ VULNERABLE: Deadlock risk
void Path1() {
    std::lock_guard<std::mutex> lock1(mutex1_);
    std::lock_guard<std::mutex> lock2(mutex2_);  // Order: 1 then 2
}

void Path2() {
    std::lock_guard<std::mutex> lock2(mutex2_);
    std::lock_guard<std::mutex> lock1(mutex1_);  // Order: 2 then 1 → DEADLOCK
}

必須パターン:

// ✅ SECURE: Consistent lock order
void Path1() {
    std::lock_guard<std::mutex> lock1(mutex1_);
    std::lock_guard<std::mutex> lock2(mutex2_);  // Order: 1 then 2
}

void Path2() {
    std::lock_guard<std::mutex> lock1(mutex1_);  // Same order: 1 then 2
    std::lock_guard<std::mutex> lock2(mutex2_);
}
2.4 TOCTOU(確認時と使用時の競合)

ルール: 状態の確認後は、間を置かずに依存する操作を実行する必要があります。

アンチパターン:

// ❌ VULNERABLE: TOCTOU window
if (fileExists(path)) {
    // Attacker can delete/replace file here
    file = openFile(path);  // May open different file
}

必須パターン:

// ✅ SECURE: Atomic check-and-use
file = openFile(path);
if (file.isValid()) {
    // Use file
}

3. 機密情報の保護

3.1 PII の厳格なマスキング

ルール: ログでは、すべての個人を特定できる情報(PII)をマスキングする必要があります。

マスキングが必要な PII:

  • ユーザーのプライバシー: 電話番号、連絡先、SMS の内容、生体認証データ
  • 入力イベント: 生の KeyEvent、タッチ座標(x、y)、画面上の位置範囲(Rect)

アンチパターン:

// ❌ VULNERABLE: Logs PII
HILOG_INFO("Phone: %{public}s", phoneNumber.c_str());
HILOG_ERROR("Touch at (%{public}d, %{public}d)", x, y);

必須パターン:

// ✅ SECURE: Redact or suppress
HILOG_INFO("Phone: %{private}s", phoneNumber.c_str());  // Redacted
// Better: Don't log PII at all
HILOG_INFO("Processing phone number");

ポリシー: リリースビルドでは、完全に出力を抑制することを優先してください。デバッグにどうしても必要な場合に限り、%{private} 形式指定子を使用します。

3.2 メモリレイアウトの漏えい(ASLR の回避)

ルール: 生のポインターアドレスをログに記録してはいけません。

アンチパターン:

// ❌ VULNERABLE: Leaks addresses for ASLR bypass
HILOG_INFO("Object at %p", &object);
HILOG_DEBUG("Buffer address: %{public}p", buffer);

必須パターン:

// ✅ SECURE: No address logging
HILOG_INFO("Object created");
// Use opaque IDs instead of pointers
HILOG_INFO("Object ID: %{public}d", object.id_);

理由: ヒープ/スタックアドレスの漏えいは、攻撃者が ASLR(アドレス空間配置のランダム化)を回避する助けになります。

4. 権限の検証

ルール: すべての特権操作で、呼び出し元の権限を検証する必要があります。

アンチパターン:

// ❌ VULNERABLE: No permission check
int32_t Service::DeleteFile(const std::string& path) {
    // Any caller can delete any file!
    return unlink(path.c_str());
}

必須パターン:

// ✅ SECURE: Validate permissions
int32_t Service::DeleteFile(const std::string& path) {
    // Verify caller has permission to access this path
    if (!HasPermission(callerToken_, path, Permission::DELETE)) {
        HILOG_ERROR("Permission denied for path: %{private}s", path.c_str());
        return ERR_PERMISSION_DENIED;
    }

    // Verify path is within allowed sandbox
    if (!IsPathInSandbox(path)) {
        HILOG_ERROR("Path outside sandbox: %{private}s", path.c_str());
        return ERR_INVALID_PATH;
    }

    return unlink(path.c_str());
}

権限チェックが必要な操作:

  • ファイルシステム操作(読み取り、書き込み、削除)
  • システム設定の変更
  • ハードウェアへのアクセス(カメラ、マイク、位置情報)
  • プロセス間通信
  • ネットワーク操作

よくある間違い

間違い結果修正方法
MessageParcel の戻り値チェックを忘れる初期化されていないデータの使用、クラッシュ常に戻り値を確認する
サイズを検証するが、下限(負の値)を確認しない負のサイズが検証を通過する0 <= size <= MAX を確認する
共有コンテナで書き込みを保護するが、読み取りを保護しない読み取り中に競合状態が発生するすべてのアクセスを保護する
コンテナの変更後にイテレーターを使用するイテレーターの無効化、クラッシュ反復処理中はロックを保持する
PII のログ出力に %{public} を使用する情報漏えい%{private} を使用するか、ログに記録しない
デバッグ用にポインターアドレスを出力するASLR の回避不透明な ID を使用する
「内部処理だから」という理由で権限チェックを省略する外部から呼び出された場合に権限昇格が起きる常に検証する

レビュー出力形式

違反は次の形式で指摘してください。

**[HIGH SECURITY RISK] <Category>**

Location: <file_path>:<line_number>

Issue: <description>

Anti-pattern:
```cpp
<code>

必要な修正:

<code>

影響:悪用された場合に攻撃者が可能になること


## Real-World Impact

**Container race conditions:** Use-after-free crashes, privilege escalation through corrupted state
**IPC validation failures:** Remote code execution via deserialization exploits, memory exhaustion DoS
**PII leakage:** Privacy violations, GDPR compliance failures
**ASLR bypass:** Enables exploitation of memory corruption vulnerabilities
**Missing permission checks:** Unauthorized access to sensitive data, system modification

コメント