4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

オープンソースのMacクリーンアプリが流石に怖すぎるから、AIを使って悪意のあるコードが仕込まれていないか調べた

4
Posted at

はじめに

スクリーンショット 2026-04-15 22.58.01.png
「システムデータ」が220GB
は????なんだこれ??Macのこれだけは許せぬ。
CleanMyMacのような有料アプリもありますが、サブスクで年間数千円かかります。しかもこのアプリWindowsXP時代に一世を風靡した(?)クリーナーアプリっぽくて怖い。

そこで見つけたのがPureMacというオープンソースのMacクリーンアプリです。

スクリーンショット 2026-04-15 22.49.29.png

ただ、このアプリはFull Disk Access(フルディスクアクセス)を要求します。Mac内のほぼ全てのファイルにアクセスできる権限で、写真、メール、Safari履歴、SSHキーなども読めます。

ソースコードが公開されているとはいえ、悪意のあるコードが紛れ込んでいない保証はありません。なので、Claude Code(AI)を使ってソースコード約4,400行を監査しました。

↓プロンプト

悪意のあるコードが含まれていないか徹底的に調査して
最新のマルウェアやゼロデイアタックの知識を検索してそれがないか確認せよ

調査対象

項目 内容
アプリ名 PureMac
リポジトリ https://github.com/momenbasel/PureMac
言語 Swift 5.9
コード量 約4,395行(26ファイル)
対応OS macOS 13.0+
ライセンス MIT
外部依存 なし

調査方法

Claude Codeのプランモードを使い、3つの調査エージェントを並列実行して以下を調べました。

基本監査

  • プロジェクト構造、ビルドシステム、全ソースファイルの通読
  • ネットワーク通信、データ収集、難読化の有無

最新脅威との照合

2024-2025年に発見されたmacOSマルウェアの具体的な手法と照合しました。

  • Atomic Stealer(AMOS): osascriptで偽パスワードダイアログを表示してKeychainを窃取します
  • Banshee Stealer: AppleのXProtectの暗号化キーを盗んでC2通信を暗号化します
  • Cuckoo: スクリーンキャプチャ、キーロガー、情報窃取を組み合わせた複合マルウェアです
  • Realst: ブラウザのSQLiteデータベースを直接読んでパスワードを窃取します

高度な攻撃パターンの検出

  • TCC.db操作(プライバシー権限の改竄)
  • dylib hijacking(動的ライブラリ注入)
  • XPC悪用
  • サプライチェーン攻撃(ビルドスクリプト改竄、依存関係汚染)
  • コード隠蔽手法(文字列難読化、リソースへのペイロード埋込、メソッドスウィズリング)

調査結果

1. ネットワーク通信: なし

URLSession     → 0件
URLRequest     → 0件
HTTP/HTTPS     → 0件
ソケット接続     → 0件

ネットワーク通信のコードが存在しません。データを外部に送る手段そのものがないので、仮に他の部分で情報を集めていたとしても送信できません。

2. 既知マルウェアの手法との照合: 全て該当なし

チェック項目 マルウェアでの用途 PureMacでの検出
osascript / NSAppleScript 偽パスワードダイアログ なし
SecItemCopyMatching Keychain窃取 なし
Chrome Login Data 読取 ブラウザパスワード窃取 なし
CGEventTap キーロギング なし
CGWindowListCreateImage スクリーンキャプチャ なし
NSPasteboard クリップボード監視 なし
XProtect.bundle アクセス 暗号化キー窃取 なし
暗号通貨ウォレットパス 仮想通貨窃取 なし
VM検出(IOKit) 解析回避 なし

3. 外部プロセス実行: 全て正当

アプリ内で呼び出される外部コマンドは7箇所です。全てハードコードされたパスと引数で、ユーザー入力は混入しません。

// ディスク操作
"/usr/sbin/diskutil" ["apfs", "purgePurgeable", "/"]
"/usr/sbin/diskutil" ["apfs", "listSnapshots", "/", "-plist"]

// Time Machine
"/usr/bin/tmutil" ["listlocalsnapshots", "/"]

// Homebrew キャッシュ検出
"/opt/homebrew/bin/brew" ["--cache"]

// スケジューラ管理
"/bin/launchctl" ["load", plistPath]
"/bin/launchctl" ["unload", plistPath]

引数が全て固定値なので、コマンドインジェクションの余地はありません。

4. ファイル削除の安全性

クリーンアプリで最も気になるのは、ファイル削除が悪用されないかという点です。

まず、シンボリックリンクを解決してから削除判定を行っています。

// CleaningEngine.swift
let resolved = itemURL.resolvingSymlinksInPath().path
guard isSafeToDelete(resolvedPath: resolved) else { continue }

削除可能なパスはホワイトリスト方式で制限されています。

private func isSafeToDelete(resolvedPath: String) -> Bool {
    let allowedRoots = [
        "\(home)/Library/Caches",
        "\(home)/Library/Logs",
        "\(home)/Library/Saved Application State",
        "\(home)/.Trash",
        "/Library/Caches",
        "/Library/Logs",
        "/tmp",
        // ...
    ]
    return allowedRoots.contains { resolvedPath.hasPrefix($0) }
}

Keychain、TCC.db、~/.ssh、システムファイルはホワイトリストに含まれないため削除できません。シンボリックリンクを解決してからホワイトリストと照合しているため、~/Library/Caches/evil~/.ssh のようなシンボリックリンク攻撃も通りません。

5. サプライチェーン攻撃: 該当なし

外部依存パッケージ(SPM/CocoaPods/Carthage): 0個
Xcodeビルドスクリプトフェーズ: 0個
pre/post-installスクリプト: 0個

外部依存がゼロなので、依存関係を通じたサプライチェーン攻撃の攻撃面が存在しません。

6. コード隠蔽手法: 該当なし

Base64エンコード文字列    → なし
XOR難読化               → なし
動的メソッド呼出          → なし
メソッドスウィズリング      → なし
dlopen/dlsym            → なし
UnsafePointer           → なし
リソースへのペイロード埋込  → なし
ローカライゼーションへの隠蔽 → なし(中国語翻訳ファイルも純粋なUI文字列のみ)

7. エンタイトルメント

<!-- PureMac.entitlements -->
<key>com.apple.security.app-sandbox</key>
<false/>

App Sandboxの無効化のみです。以下の危険なエンタイトルメントは含まれていません。

  • com.apple.security.cs.disable-library-validation(dylib注入を許可する)→ なし
  • com.apple.security.cs.allow-dyld-environment-variables → なし
  • com.apple.developer.endpoint-security.client → なし

軽微な指摘事項

悪意のあるコードではありませんが、セキュリティ上の改善余地がある箇所も見つかりました。

1. TOCTOU競合状態(低リスク)

CleaningEngine.swiftで、ファイルの存在確認からシンボリックリンク解決、削除までの間に理論的な競合ウィンドウがあります。

guard fileManager.fileExists(atPath: item.path) else { continue }  // チェック
let resolved = itemURL.resolvingSymlinksInPath().path
guard isSafeToDelete(resolvedPath: resolved) else { continue }
try fileManager.removeItem(atPath: item.path)  // 使用(この間に差し替え可能)

ホワイトリスト検証で軽減されており、シングルユーザーのmacOS環境では実害リスクは低いです。

2. OrphanListViewのシンボリックリンク検証欠如

Orphan(孤立ファイル)の削除パスには、CleaningEngineにある isSafeToDelete チェックがありません。ユーザーが手動選択する操作なのでリスクは低いですが、防御の一貫性としては改善できます。

3. GitHub ActionsのSHA未ピン留

# 現状(タグ指定)
- uses: actions/checkout@v4

# 推奨(SHA指定)
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11

タグは書き換え可能なため、サプライチェーン攻撃のリスクが理論的にはあります。

まとめ

観点 結果
ネットワーク通信 なし
データ窃取機能 なし
既知マルウェア手法 全て該当なし
コード難読化/隠蔽 なし
サプライチェーンリスク 低い(依存ゼロ)
ファイル削除の安全性 ホワイトリスト+シンボリックリンク対策あり

約4,400行のSwiftコードに悪意のあるコードは見つかりませんでした。
疑ってすまんかった。

オープンソースだから安全なのではなく、コードを読んで確認したから安全だと判断しました。AIを使えば、こうした監査を短時間で実施できます。Full Disk Accessを要求するアプリを使う前に試してみてください。

環境

  • 監査ツール: Claude Code(Claude Opus 4.6)
  • 監査手法: 3並列エージェントによるコードベース全文探索 + 最新脅威パターン照合
  • 対象コミット: 3d425cb (feat: CLI interface + universal binary)
4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?