Redis 7.4.5 Lua の脆弱性 CVE-2025-49844/46817/46818:PoC が提供される

PoC Exploit Released for Critical Vulnerabilities in Lua Engine

2025/10/08 gbhackers — Redis 7.4.5 で使用される Lua スクリプト・エンジンに存在する3件の深刻な脆弱性に対する、新たな PoC エクスプロイトが公表された。セキュリティ研究者たちが発見したのは、Lua パーサー/unpack() 関数/基本型メタテーブル保護の欠陥を悪用する攻撃者が、リモート・コード実行や権限昇格を引き起こす可能性があることだ。これらの問題は、 EVAL コマンドに影響を及ぼす。それにより、信頼できないスクリプトをシステムが許可するという、直接的な脅威が生じるため、直ちにパッチを適用する必要がある。

Redis 7.4.5 の定期的な監査中に、Lua エンジンに 3件の深刻な欠陥が見つかった。1つ目の CVE-2025-49844 は、 Lua パーサーのメモリ解放後使用の欠陥である。スクリプトを解析する際に、このエンジンはスタック上での保護を行わずに TString オブジェクトを割り当てる。ガベージコレクション・サイクルにより、このオブジェクトが早期に解放され、攻撃者によるメモリの上書と任意のコード実行の可能性が生じる。

2つ目の脆弱性 CVE-2025-46817 は、 unpack() 関数の整数オーバーフローに起因する。極端なインデックス値を指定する攻撃者により、 Lua スタックが破壊され、制御フローが乗っ取られる可能性がある。

3つ目の脆弱性 CVE-2025-46818 は、メタテーブルの変更による権限昇格を引き起こすものだ。文字列/数値などのプリミティブ型の基本型メタテーブルは変更が可能であり、それにより他ユーザーのコンテキストで実行される、悪意のコード挿入にいたるという。

技術的な詳細

1つ目の解放後使用 (use-after-free) の問題は、”deps/ lua/ src/ lparser.c” の 387 行目で発生する。生のパーサー・コードは luaS_new (L, name) を呼び出すが、結果を Lua スタックにプッシュできず、保護されていない状態になる。ただし、パッチ適用版では、新しい文字列を保護するために、解析前に setsvalue2s (L, L->top, tname) と incr_top (L) が使用される。

2つ目である、”deps/ lua/ src/ lbaselib.c” の整数オーバーフロー脆弱性は、要素数を “n = e – i + 1” と誤って計算するため、 “e” の値が非常に大きい場合にオーバーフローを発生する。このエラーにより、スタック境界を超えた書き込みが発生する。

3つ目のメタテーブルの問題については、ファイル “src/ script_lua.c” と “src/ eval.c” に基本型のメタテーブルへの書き込みを防ぐチェックが不足しており、悪意のコード・インジェクションが可能になる。

以下の表は、これらの脆弱性を簡潔にまとめたものである。

CVEVulnerabilityImpactExploit PrerequisitesCVSS 3.1 Score
CVE-2025-49844Use-After-Free in Lua ParserRemote Code ExecutionEVAL access9.8
CVE-2025-46817Integer Overflow in unpack()Remote Code ExecutionEVAL access9.8
CVE-2025-46818Metatable Privilege EscalationPrivilege EscalationEVAL access9.8
PoC エクスプロイト

Python による PoC は完全なものであり、稼働中の Redis サーバに対して3つの脆弱性をテストできる。たとえば、use-after-free テストでは、Lua のメモリを枯渇させ、パース中のガベージコレクションを強制する。

# Step 1: Create memory pressure

for i in range(50):

    huge_script = "local t={}; " + ";".join([f"t[{j}]=string.rep('X',10000)" for j in range(50)]) + "; return 'ok'"

    client.eval(huge_script, 0)

# Step 2: Trigger GC during parse

client.eval("collectgarbage('collect'); return 'gc'", 0)

unpack() オーバーフロー・チェックでは、 “return { unpack({1,2,3}, -2, 2147483647) }” のようなスクリプトを使用してエラーを検出する。nil メタテーブルの変更により、保護の有無は確認できる。

緩和策

ユーザー組織にとって必要なことは、Redis 7.4.6 以降への速やかなアップグレードである。前述の、パーサーのスタック保護/unpack() の境界チェック/基本メタテーブルにおける読み取り専用強制などが、このパッチには含まれる。

これらのアップデートを適用することで、攻撃対象領域が消え去り、スクリプトの分離が回復する。リスクを軽減するために推奨されるものには、予期しない EVAL アクティビティの継続的な監視と厳格なアクセス制御もある。