var params:Object = LoaderInfo(this.root.loaderInfo).parameters;
var ctl:String = String(params["ctl"]);
var ao:Worker;
if (ctl == "Add) {
ao = new AddCommand();
} else if (ctl == "Modify") {
ao = new ModifyCommand();
} else {
throw new UnknownActionError();
}
ao.doAction(params);
var params:Object = LoaderInfo(this.root.loaderInfo).parameters;
var ctl:String = String(params["ctl"]);
var ao:Worker;
var cmdClass:Class = getDefinitionByName(ctl + "Command") as Class;
ao = new cmdClass();
ao.doAction(params);
if/else
ブロックは完全に削除され、コマンドディスパッチャを修正しなくとも新しいコマンドタイプを追加することができるからです。Worker
インターフェイスを実装する任意のオブジェクトのインスタンスを作成することができます。コマンドディスパッチャが依然として Access Control の原因である場合、プログラマは Worker
インターフェイスを実装する新規クラスを作成するたびに、ディスパッチャの Access Control コードを忘れずに修正する必要があります。Access Control コードの修正を怠った場合、一部の Worker
クラスに対して一切の Access Control が適用されなくなります。Worker
オブジェクトに Access Control のチェックを実行させることです。リファクタリングされたコードの例を次に示します。
var params:Object = LoaderInfo(this.root.loaderInfo).parameters;
var ctl:String = String(params["ctl"]);
var ao:Worker;
var cmdClass:Class = getDefinitionByName(ctl + "Command") as Class;
ao = new cmdClass();
ao.checkAccessControl(params);
ao.doAction(params);
Continuation
オブジェクトのコールバック メソッドの決定を許可すると、攻撃者がアプリケーションを介して予期せぬ制御フロー パスを作成できてしまい、セキュリティ チェックをすり抜けてしまう可能性があります。continuationMethod
プロパティを設定します。これは、応答を受信したときに呼び出されるメソッドの名前を決定します。
public Object startRequest() {
Continuation con = new Continuation(40);
Map<String,String> params = ApexPages.currentPage().getParameters();
if (params.containsKey('contMethod')) {
con.continuationMethod = params.get('contMethod');
} else {
con.continuationMethod = 'processResponse';
}
HttpRequest req = new HttpRequest();
req.setMethod('GET');
req.setEndpoint(LONG_RUNNING_SERVICE_URL);
this.requestLabel = con.addHttpRequest(req);
return con;
}
continuationMethod
プロパティをランタイム リクエスト パラメーターで設定できるようになり、攻撃者が、名前と一致する関数を呼び出すことが可能になります。
...
Dim ctl As String
Dim ao As New Worker()
ctl = Request.Form("ctl")
If (String.Compare(ctl,"Add") = 0) Then
ao.DoAddCommand(Request)
Else If (String.Compare(ctl,"Modify") = 0) Then
ao.DoModifyCommand(Request)
Else
App.EventLog("No Action Found", 4)
End If
...
...
Dim ctl As String
Dim ao As New Worker()
ctl = Request.Form("ctl")
CallByName(ao, ctl, vbMethod, Request)
...
if/else
ブロックは完全に削除され、コマンドディスパッチャを修正しなくとも新しいコマンドタイプを追加することができるからです。Worker
オブジェクトによって実装された任意のメソッドを呼び出すことができます。コマンドディスパッチャが Access Control の原因である場合、プログラマは Worker
クラス内に新規メソッドを作成するたびに、ディスパッチャの Access Control ロジックを忘れずに修正する必要があります。この Access Control ロジックが古くなると、いくつかの Worker
メソッドにはいずれの Access Control も関連付けられなくなります。Worker
オブジェクトに Access Control のチェックを実行させることです。リファクタリングされたコードの例を次に示します。
...
Dim ctl As String
Dim ao As New Worker()
ctl = Request.Form("ctl")
If (ao.checkAccessControl(ctl,Request) = True) Then
CallByName(ao, "Do" & ctl & "Command", vbMethod, Request)
End If
...
clazz
で定義された任意の関数をコールできるようになります。
char* ctl = getenv("ctl");
...
jmethodID mid = GetMethodID(clazz, ctl, sig);
status = CallIntMethod(env, clazz, mid, JAVA_ARGS);
...
String ctl = request.getParameter("ctl");
Worker ao = null;
if (ctl.equals("Add")) {
ao = new AddCommand();
} else if (ctl.equals("Modify")) {
ao = new ModifyCommand();
} else {
throw new UnknownActionError();
}
ao.doAction(request);
String ctl = request.getParameter("ctl");
Class cmdClass = Class.forName(ctl + "Command");
Worker ao = (Worker) cmdClass.newInstance();
ao.doAction(request);
if/else
ブロックは完全に削除され、コマンドディスパッチャを修正しなくとも新しいコマンドタイプを追加することができるからです。Worker
インターフェイスを実装する任意のオブジェクトのインスタンスを作成することができます。コマンドディスパッチャが依然として Access Control の原因である場合、プログラマは Worker
インターフェイスを実装する新規クラスを作成するたびに、ディスパッチャの Access Control コードを忘れずに修正する必要があります。Access Control コードの修正を怠った場合、一部の Worker
クラスに対して一切の Access Control が適用されなくなります。Worker
オブジェクトに Access Control のチェックを実行させることです。リファクタリングされたコードの例を次に示します。
String ctl = request.getParameter("ctl");
Class cmdClass = Class.forName(ctl + "Command");
Worker ao = (Worker) cmdClass.newInstance();
ao.checkAccessControl(request);
ao.doAction(request);
Worker
インターフェイスを実装するオブジェクトにすら制約を受けず、システム内の任意のオブジェクトのデフォルト コンストラクタを呼び出すことができます。オブジェクトが Worker
インターフェイスを実装しない場合、ao
への割り当て前に ClassCastException
が発生しますが、コンストラクタが攻撃者に有利に働く操作を実行すると、すでに被害を被ったことになります。このシナリオは、簡単なアプリケーションの場合被害は比較的少なくて済みますが、複雑度が飛躍的に増す大規模アプリケーションの場合では攻撃者は攻撃に利用できるコンストラクタを見つけられると考えるのが妥当です。performSelector
メソッドの引数を制御できるため、セキュリティ チェックを回避して、アプリケーションに想定外の制御フロー パスを作成できる可能性があります。UIApplicationDelegate
クラスで定義されたメソッド シグネチャに一致する任意の関数をコールできるようになります。
...
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
NSString *query = [url query];
NSString *pathExt = [url pathExtension];
[self performSelector:NSSelectorFromString(pathExt) withObject:query];
...
$ctl = $_GET["ctl"];
$ao = null;
if (ctl->equals("Add")) {
$ao = new AddCommand();
} else if ($ctl.equals("Modify")) {
$ao = new ModifyCommand();
} else {
throw new UnknownActionError();
}
$ao->doAction(request);
$ctl = $_GET["ctl"];
$args = $_GET["args"];
$cmdClass = new ReflectionClass(ctl . "Command");
$ao = $cmdClass->newInstance($args);
$ao->doAction(request);
if/else
ブロックは完全に削除され、コマンドディスパッチャを修正しなくとも新しいコマンドタイプを追加することができるからです。Worker
インターフェイスを実装する任意のオブジェクトのインスタンスを作成することができます。コマンドディスパッチャが依然として Access Control の原因である場合、プログラマは Worker
インターフェイスを実装する新規クラスを作成するたびに、ディスパッチャの Access Control コードを忘れずに修正する必要があります。Access Control コードの修正を怠った場合、一部の Worker
クラスに対して一切の Access Control が適用されなくなります。Worker
オブジェクトに Access Control のチェックを実行させることです。リファクタリングされたコードの例を次に示します。
$ctl = $_GET["ctl"];
$args = $_GET["args"];
$cmdClass = new ReflectionClass(ctl . "Command");
$ao = $cmdClass->newInstance($args);
$ao->checkAccessControl(request);
ao->doAction(request);
Worker
インターフェイスを実装するオブジェクトにすら制約を受けず、システム内の任意のオブジェクトのデフォルト コンストラクタを呼び出すことができます。オブジェクトが Worker
インターフェイスを実装しない場合、$ao
への割り当て前に ClassCastException
が発生しますが、コンストラクタが攻撃者に有利に働く操作を実行すると、すでに被害を被ったことになります。このシナリオは、簡単なアプリケーションの場合被害は比較的少なくて済みますが、複雑度が飛躍的に増す大規模アプリケーションの場合では攻撃者は攻撃に利用できるコンストラクタを見つけられると考えるのが妥当です。
ctl = req['ctl']
if ctl=='add'
addCommand(req)
elsif ctl=='modify'
modifyCommand(req)
else
raise UnknownCommandError.new
end
ctl = req['ctl']
ctl << "Command"
send(ctl)
if/else
ブロックは完全に削除され、コマンドディスパッチャを修正しなくとも新しいコマンドタイプを追加することができるからです。define_method()
を使用して動的に作成するか、missing_method()
の上書きによってコールすることです。こうした状況とそこでアクセス制御コードがどう使用されるかを監査し、追跡するのは非常に困難です。また、他のどのライブラリ コードがロードされたかにも依存することを考えると、この作業をこの方法で適切に行うことはほぼ不可能です。
def exec(ctl: String) = Action { request =>
val cmdClass = Platform.getClassForName(ctl + "Command")
Worker ao = (Worker) cmdClass.newInstance()
ao.doAction(request)
...
}
if/else
ブロックは完全に削除され、コマンド ディスパッチャを修正しなくとも新しいコマンド タイプを追加することができるからです。Worker
インターフェイスを実装する任意のオブジェクトのインスタンスを作成することができます。コマンド ディスパッチャが依然として Access Control の原因である場合、プログラマは Worker
インターフェイスを実装する新規クラスを作成するたびに、ディスパッチャの Access Control コードを忘れずに修正する必要があります。Access Control コードの修正を怠った場合、一部の Worker
クラスに対して一切の Access Control が適用されなくなります。Worker
オブジェクトに Access Control のチェックを実行させることです。リファクタリングされたコードの例を次に示します。
def exec(ctl: String) = Action { request =>
val cmdClass = Platform.getClassForName(ctl + "Command")
Worker ao = (Worker) cmdClass.newInstance()
ao.checkAccessControl(request);
ao.doAction(request)
...
}
Worker
インターフェイスを実装するオブジェクトにすら制約を受けず、システム内の任意のオブジェクトのデフォルト コンストラクタを呼び出すことができます。オブジェクトが Worker
インターフェイスを実装しない場合、ao
への割り当て前に ClassCastException
が発生しますが、コンストラクタが攻撃者に有利に働く操作を実行すると、すでに被害を被ったことになります。このシナリオは、簡単なアプリケーションの場合被害は比較的少なくて済みますが、複雑度が飛躍的に増す大規模アプリケーションの場合では攻撃者は攻撃に利用できるコンストラクタを見つけられると考えるのが妥当です。performSelector
メソッドの引数を制御できるため、セキュリティ チェックを回避して、アプリケーションに想定外の制御フロー パスを作成できる可能性があります。UIApplicationDelegate
クラスで定義されたメソッド シグネチャに一致する任意の関数をコールできるようになります。
func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool {
...
let query = url.query
let pathExt = url.pathExtension
let selector = NSSelectorFromString(pathExt!)
performSelector(selector, withObject:query)
...
}
...
Dim ctl As String
Dim ao As new Worker
ctl = Request.Form("ctl")
If String.Compare(ctl,"Add") = 0 Then
ao.DoAddCommand Request
Else If String.Compare(ctl,"Modify") = 0 Then
ao.DoModifyCommand Request
Else
App.EventLog "No Action Found", 4
End If
...
...
Dim ctl As String
Dim ao As Worker
ctl = Request.Form("ctl")
CallByName ao, ctl, vbMethod, Request
...
if/else
ブロックは完全に削除され、コマンドディスパッチャを修正しなくとも新しいコマンドタイプを追加することができるからです。Worker
オブジェクトによって実装された任意のメソッドを呼び出すことができます。コマンドディスパッチャが依然として Access Control の原因である場合、プログラマは Worker
クラス内に新規メソッドを作成するたびに、ディスパッチャの Access Control コードを忘れずに修正する必要があります。Access Control コードの修正を怠った場合、一部の Worker
メソッドに対して一切の Access Control が適用されなくなります。Worker
オブジェクトに Access Control のチェックを実行させることです。リファクタリングされたコードの例を次に示します。
...
Dim ctl As String
Dim ao As Worker
ctl = Request.Form("ctl")
If ao.checkAccessControl(ctl,Request) = True Then
CallByName ao, "Do" & ctl & "Command", vbMethod, Request
End If
...
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///c:/winnt/win.ini" >]><foo>&xxe;</foo>
- (void) parseSomeXML: (NSString *) rawXml {
BOOL success;
NSData *rawXmlConvToData = [rawXml dataUsingEncoding:NSUTF8StringEncoding];
NSXMLParser *myParser = [[NSXMLParser alloc] initWithData:rawXmlConvToData];
[myParser setShouldResolveExternalEntities:YES];
[myParser setDelegate:self];
}
rawXml
を制御できると考えてみます。
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///c:/boot.ini" >]><foo>&xxe;</foo>
boot.ini
ファイルの内容が含まれます。
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///dev/random" >]><foo>&xxe;</foo>
- (void) parseSomeXML: (NSString *) rawXml {
BOOL success;
NSData *rawXmlConvToData = [rawXml dataUsingEncoding:NSUTF8StringEncoding];
NSXMLParser *myParser = [[NSXMLParser alloc] initWithData:rawXmlConvToData];
[myParser setShouldResolveExternalEntities:YES];
[myParser setDelegate:self];
}
rawXml
を制御できると考えてみます。
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///c:/boot.ini" >]><foo>&xxe;</foo>
boot.ini
ファイルの内容が含まれます。
...
<?php
$goodXML = $_GET["key"];
$doc = simplexml_load_string($goodXml);
echo $doc->testing;
?>
...
Example 2
のコードに以下の XML が渡されると仮定してください。
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///c:/boot.ini" >]><foo>&xxe;</foo>
boot.ini
ファイルのコンテンツが埋め込まれます。攻撃者は、データを盗み出したり、ネットワーク リソースの存在に関する情報を取得するために、クライアントに返される XML 要素を利用することができます。
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///dev/random" >]><foo>&xxe;</foo>
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]><foo>&xxe;</foo>
/etc/passwd
のコンテンツを読み込み、それらをドキュメントに含めます。
def readFile() = Action { request =>
val xml = request.cookies.get("doc")
val doc = XMLLoader.loadString(xml)
...
}
func parseXML(xml: String) {
parser = NSXMLParser(data: rawXml.dataUsingEncoding(NSUTF8StringEncoding)!)
parser.delegate = self
parser.shouldResolveExternalEntities = true
parser.parse()
}
rawXml
コンテンツを攻撃者が制御できる場合を考えてみましょう。
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///c:/boot.ini" >]><foo>&xxe;</foo>
boot.ini
ファイルの内容が含まれます。shoes
を攻撃者が制御できる場合を考えてみましょう。
<order>
<price>100.00</price>
<item>shoes</item>
</order>
shoes
を shoes</item><price>1.00</price><item>shoes
に置き換えるとします。新しい XML は以下のようになります。
<order>
<price>100.00</price>
<item>shoes</item><price>1.00</price><item>shoes</item>
</order>
<price>
の値により最初の <price>
タグの値が上書きされます。これにより、攻撃者は $100 の靴を $1 で購入できます。shoes
を攻撃者が制御できる場合を考えてみましょう。
<order>
<price>100.00</price>
<item>shoes</item>
</order>
shoes
を shoes</item><price>1.00</price><item>shoes
に置き換えるとします。新しい XML は以下のようになります。
<order>
<price>100.00</price>
<item>shoes</item><price>1.00</price><item>shoes</item>
</order>
<price>
の値により最初の <price>
タグの値が上書きされます。これにより、攻撃者は $100 の靴を $1 で購入できます。shoes
を攻撃者が制御できる場合を考えてみましょう。
<order>
<price>100.00</price>
<item>shoes</item>
</order>
shoes
を shoes</item><price>1.00</price><item>shoes
に置き換えるとします。新しい XML は以下のようになります。
<order>
<price>100.00</price>
<item>shoes</item><price>1.00</price><item>shoes</item>
</order>
<price>
の値により最初の <price>
タグの値が上書きされます。これにより、攻撃者は $100 の靴を $1 で購入できます。shoes
を攻撃者が制御できる場合を考えてみましょう。
<order>
<price>100.00</price>
<item>shoes</item>
</order>
shoes
を shoes</item><price>1.00</price><item>shoes
に置き換えるとします。新しい XML は以下のようになります。
<order>
<price>100.00</price>
<item>shoes</item><price>1.00</price><item>shoes</item>
</order>
<price>
の値により最初の <price>
タグの値が上書きされます。これにより、攻撃者は $100 の靴を $1 で購入できます。shoes
を攻撃者が制御できる場合を考えてみましょう。
<order>
<price>100.00</price>
<item>shoes</item>
</order>
shoes
を shoes</item><price>1.00</price><item>shoes
に置き換えるとします。新しい XML は以下のようになります。
<order>
<price>100.00</price>
<item>shoes</item><price>1.00</price><item>shoes</item>
</order>
shoes
を攻撃者が制御できる場合を考えてみましょう。
<order>
<price>100.00</price>
<item>shoes</item>
</order>
shoes
を shoes</item><price>1.00</price><item>shoes
に置き換えるとします。新しい XML は以下のようになります。
<order>
<price>100.00</price>
<item>shoes</item><price>1.00</price><item>shoes</item>
</order>
<price>
の値により最初の <price>
タグの値が上書きされます。これにより、攻撃者は $100 の靴を $1 で購入できます。shoes
を攻撃者が制御できる場合を考えてみましょう。
<order>
<price>100.00</price>
<item>shoes</item>
</order>
shoes
を shoes</item><price>1.00</price><item>shoes
に置き換えるとします。新しい XML は以下のようになります。
<order>
<price>100.00</price>
<item>shoes</item><price>1.00</price><item>shoes</item>
</order>
<price>
の値により最初の <price>
タグの値が上書きされます。これにより、攻撃者は $100 の靴を $1 で購入できます。
...
<?php
$goodXML = $_GET["key"];
$doc = simplexml_load_string($goodXml);
echo $doc->testing;
?>
...
Example 2
のコードに以下の XML が渡されると仮定してください。
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///c:/boot.ini" >]><foo>&xxe;</foo>
boot.ini
ファイルのコンテンツが埋め込まれます。攻撃者は、データを盗み出したり、ネットワーク リソースの存在に関する情報を取得するために、クライアントに返される XML 要素を利用することができます。shoes
を攻撃者が制御できる場合を考えてみましょう。
<order>
<price>100.00</price>
<item>shoes</item>
</order>
shoes
を shoes</item><price>1.00</price><item>shoes
に置き換えるとします。新しい XML は以下のようになります。
<order>
<price>100.00</price>
<item>shoes</item><price>1.00</price><item>shoes</item>
</order>
<price>
の値により最初の <price>
タグの値が上書きされます。これにより、攻撃者は $100 の靴を $1 で購入できます。shoes
を攻撃者が制御できる場合を考えてみましょう。
<order>
<price>100.00</price>
<item>shoes</item>
</order>
shoes
を shoes</item><price>1.00</price><item>shoes
に置き換えるとします。新しい XML は以下のようになります。
<order>
<price>100.00</price>
<item>shoes</item><price>1.00</price><item>shoes</item>
</order>
<price>
の値により最初の <price>
タグの値が上書きされます。これにより、攻撃者は $100 の靴を $1 で購入できます。shoes
を攻撃者が制御できる場合を考えてみましょう。
<order>
<price>100.00</price>
<item>shoes</item>
</order>
shoes
を shoes</item><price>1.00</price><item>shoes
に置き換えるとします。新しい XML は以下のようになります。
<order>
<price>100.00</price>
<item>shoes</item><price>1.00</price><item>shoes</item>
</order>
<price>
の値により最初の <price>
タグの値が上書きされます。これにより、攻撃者は $100 の靴を $1 で購入できます。shoes
を攻撃者が制御できる場合を考えてみましょう。
<order>
<price>100.00</price>
<item>shoes</item>
</order>
shoes
を shoes</item><price>1.00</price><item>shoes
に置き換えるとします。新しい XML は以下のようになります。
<order>
<price>100.00</price>
<item>shoes</item><price>1.00</price><item>shoes</item>
</order>
<price>
の値により最初の <price>
タグの値が上書きされます。これにより、攻撃者は $100 の靴を $1 で購入できます。