SV.SCRIPT
スクリプトの実行
このエラーは、汚染データを使用して、信頼できない制御範囲から機能をロードおよび実行した場合に報告されます。
脆弱性とリスク
Web ウィジェット、ライブラリ、または機能の他のソースなど、サードパーティ機能を含める場合、ソフトウェアはその機能を効率的に信頼する必要があります。十分な保護メカニズムがない場合、その機能は本質的に悪意のあるものである可能性があります(信頼できないソースからのもの、スプーフィングによるもの、信頼できるソースからの処理過程で変更されたもののいずれか)。また、その機能自体に脆弱性が含まれている場合もあり、またはシステム状態情報や、機密性の高いアプリケーションデータ、Web アプリケーションの DOM など、基本システムに対して機密性が保持されるべき追加の機能および状態情報にアクセスを与える場合もあります。
攻撃者は、悪意のある機能をプログラムに挿入することにより、そのプログラムを通じて、悪意のある Web サイトなどの信頼できない制御範囲に攻撃者が配置したコードをダウンロードさせようとする可能性があります。
軽減と防止
- この脆弱性の発生を不可能にするか、この脆弱性をより容易に回避できるようにする構築を提供するような、入念に検査されたライブラリまたはフレームワークを使用します。
- ファイル名または URL などの許容される一連のオブジェクトが制限されるか、既知の場合は、修正された入力値(数値 ID など)から実際のファイル名または URL へのマッピングを作成し、他のすべての入力を拒否するようにします。
- 全入力が悪意のある入力であると仮定します。「既知の良好なものを受け入れる」入力検証戦略を使用します。つまり、仕様に厳密に準拠した許容される入力を示したホワイトリストを使用します。仕様に厳密に準拠していない入力、または、その入力を何かに変換する入力はすべて拒否します。入力検証を実行する場合、入力の長さ、入力のタイプ、許容される入力値の全範囲、入力の欠落や余剰入力、構文、関連するフィールドの整合性およびビジネスルールとの適合性を含めて、関連する入力プロパティについてすべての可能性を考慮します。
- ライブラリ、インクルード、ユーティリティファイルをできる限り Web ドキュメントルートの外に保存します。
- パラメーターや引数、クッキー、ネットワークから読み取られる全内容、環境変数、逆 DNS ルックアップ、クエリ結果、要求ヘッダー、URL コンポーネント、電子メール、ファイル名、データベース、およびアプリケーションにデータを提供する外部システムなど、信頼されていない入力がソフトウェア内に入り込む可能性がある領域すべてを把握します。そのような入力は API 呼び出しによって間接的に取得される可能性があることを忘れないでください。多くのファイルインクルードに関する問題は、プログラマーが(特にクッキーおよび URL コンポーネントの場合に)特定の入力は変更できないものと仮定するために発生します。
脆弱コード例
この例では、ページのメニュー表示に renderMenu が使用されています。メニュー表示は、JavaScript スクリプト(その場所は要求時にパラメーターとして渡されます)によって処理されます。オブジェクト menuRenderer のメソッド render は、実際の表示を行う際に呼び出されます。
攻撃者が要求時にパラメーター renderer を変更し、攻撃者の制御下にあるサーバーを指し示すようにすることで、意図されたライブラリの代わりに悪意のあるスクリプトがロードされる可能性があります。上記のコードは、悪意のあるコードで render メソッドを実行し、アプリケーションのコンテキストへのアクセスを攻撃者に与えます。
public class MenuRenderer {
public static void renderMenu(HttpServletRequest request) throws Exception {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
//parameter "renderer" contains url of javascript rendering library
URL url = new URL(request.getParameter("renderer"));
engine.eval((String) url.getContent());
Invocable inv = (Invocable) engine;
// get script object on which we want to call the method
Object menu = engine.get("menuRenderer");
// invoke the method named "render" on the script object "obj"
inv.invokeMethod(menu, "render", request.getParameter("menu"));
}
}
修正コード例 1
修正例では、入力が無害化されています。
public class MenuRenderer {
public static void renderMenu(HttpServletRequest request) throws Exception {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
//parameter "renderer" contains url of javascript rendering library
String cleanRenderer = sanitize(request.getParameter("renderer"));
URL url = new URL(cleanRenderer);
engine.eval((String) url.getContent());
Invocable inv = (Invocable) engine;
// get script object on which we want to call the method
Object menu = engine.get("menuRenderer");
// invoke the method named "render" on the script object "menu"
inv.invokeMethod(menu, "render", request.getParameter("menu"));
}
}
脆弱コード例 2
この例では、doGet は、「dispatcher」パラメーターは改ざんされないものと信じて、応答に含めています。攻撃者はパラメーター「dispatcher」を変更し、意図されたものとは異なるファイルをサーバーにロードさせる可能性があり、これにより情報のリークまたは昇格された権限(admin servlet)がもたらされます。
void doGet(HttpServletRequest request, HttpServletResponse response) {
final String dispatcher = request.getParameter("dispatcher");
request.getRequestDispatcher(<source>).include(request, response);
}
修正コード例 2
修正例では、入力が無害化されています。
void doGet(HttpServletRequest request, HttpServletResponse response) {
final String dispatcher = request.getParameter("dispatcher");
if(isValid(dispatcher)){
request.getRequestDispatcher(<source>).include(request, response);
}
}
関連チェッカー
セキュリティトレーニング
Secure Code Warrior が提供しているアプリケーションセキュリティトレーニング教材。
拡張機能
このチェッカーは、@Check を使用してセキュリティチェックを実行するか、入力を無害化するメソッドを指定することにより、Klocwork knowledge base(ナレッジベース)を通じて拡張できます。詳細については、Java 解析のチューニングを参照してください。