...
CALL FUNCTION 'FTP_VERSION'
...
IMPORTING
EXEPATH = p
VERSION = v
WORKING_DIR = dir
RFCPATH = rfcp
RFCVERSION = rfcv
TABLES
FTP_TRACE = FTP_TRACE.
WRITE: 'exepath: ', p, 'version: ', v, 'working_dir: ', dir, 'rfcpath: ', rfcp, 'rfcversion: ', rfcv.
...
try {
...
}
catch(e:Error) {
trace(e.getStackTrace());
}
Example 1
では、検索パスに、オペレーティングシステムのタイプ、システムにインストールされているアプリケーション、およびプログラムの設定に対する管理者の警戒度についての情報が含まれています。
try {
...
} catch (Exception e) {
System.Debug(LoggingLevel.ERROR, e.getMessage());
}
string cs="database=northwind;server=mySQLServer...";
SqlConnection conn=new SqlConnection(cs);
...
Console.Writeline(cs);
Example 1
では、漏洩情報に、オペレーティングシステムのタイプ、システムにインストールされているアプリケーション、およびプログラムの設定に対する管理者の警戒度についての情報が含まれています。
char* path = getenv("PATH");
...
fprintf(stderr, "cannot find exe on path %s\n", path);
Example 1
では、検索パスに、オペレーティングシステムのタイプ、システムにインストールされているアプリケーション、およびプログラムの設定に対する管理者の警戒度についての情報が含まれています。
...
EXEC CICS DUMP TRANSACTION
DUMPCODE('name')
FROM (data-area)
LENGTH (data-value)
END-EXEC.
...
<cfscript>
try {
obj = CreateObject("person");
}
catch(any excpt) {
f = FileOpen("c:\log.txt", "write");
FileWriteLine(f, "#excpt.Message#");
FileClose(f);
}
</cfscript>
final file = await File('example.txt').create();
final raf = await file.open(mode: FileMode.write);
final data = String.fromEnvironment("PASSWORD");
raf.writeString(data);
Example 1
では、漏洩情報に、オペレーティングシステムのタイプ、システムにインストールされているアプリケーション、およびプログラムの設定に対する管理者の警戒度についての情報が含まれています。
path := os.Getenv("PATH")
...
log.Printf("Cannot find exe on path %s\n", path)
Example 1
では、検索パスに、オペレーティング システムのタイプ、システムにインストールされているアプリケーション、プログラムの設定に対する管理者の警戒度についての情報が含まれています。
protected void doPost (HttpServletRequest req, HttpServletResponse res) throws IOException {
...
PrintWriter out = res.getWriter();
try {
...
} catch (Exception e) {
out.println(e.getMessage());
}
}
Example 1
では、漏洩情報に、オペレーティングシステムのタイプ、システムにインストールされているアプリケーション、およびプログラムの設定に対する管理者の警戒度についての情報が含まれています。
...
try {
...
} catch (Exception e) {
String exception = Log.getStackTraceString(e);
Intent i = new Intent();
i.setAction("SEND_EXCEPTION");
i.putExtra("exception", exception);
view.getContext().sendBroadcast(i);
}
...
...
public static final String TAG = "NfcActivity";
private static final String DATA_SPLITTER = "__:DATA:__";
private static final String MIME_TYPE = "application/my.applications.mimetype";
...
TelephonyManager tm = (TelephonyManager)Context.getSystemService(Context.TELEPHONY_SERVICE);
String VERSION = tm.getDeviceSoftwareVersion();
...
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter == null)
return;
String text = TAG + DATA_SPLITTER + VERSION;
NdefRecord record = new NdefRecord(NdefRecord.TNF_MIME_MEDIA,
MIME_TYPE.getBytes(), new byte[0], text.getBytes());
NdefRecord[] records = { record };
NdefMessage msg = new NdefMessage(records);
nfcAdapter.setNdefPushMessage(msg, this);
...
var http = require('http');
...
http.request(options, function(res){
...
}).on('error', function(e){
console.log('There was a problem with the request: ' + e);
});
...
Example 1
では、漏洩情報に、オペレーティングシステムのタイプ、システムにインストールされているアプリケーション、およびプログラムの設定に対する管理者の警戒度についての情報が含まれています。
try {
...
} catch (e: Exception) {
e.printStackTrace()
}
Example 1
では、漏洩情報に、オペレーティングシステムのタイプ、システムにインストールされているアプリケーション、およびプログラムの設定に対する管理者の警戒度についての情報が含まれています。
...
try {
...
} catch (e: Exception) {
Log.e(TAG, Log.getStackTraceString(e))
}
...
...
NSString* deviceID = [[UIDevice currentDevice] name];
NSLog(@"DeviceID: %@", deviceID);
...
deviceID
エントリをデフォルトのユーザー リストに追加し、直ちに plist ファイルに格納します。
...
NSString* deviceID = [[UIDevice currentDevice] name];
[defaults setObject:deviceID forKey:@"deviceID"];
[defaults synchronize];
...
Example 2
のコードでは、モバイル デバイスのシステム情報が、そのデバイス上に格納されている保護されていない plist ファイルに格納されます。開発者の多くは、plist ファイルをあらゆるデータの安全な格納先として信頼しがちですが、plist ファイルはデバイスを保持しているあらゆるユーザーが読み取ることができるため、特にシステム情報およびプライバシーに関わる場合は盲目的に信頼しないでください。
<?php
...
echo "Server error! Printing the backtrace";
debug_print_backtrace();
...
?>
Example 1
では、漏洩情報に、オペレーティングシステムのタイプ、システムにインストールされているアプリケーション、およびプログラムの設定に対する管理者の警戒度についての情報が含まれています。
try:
...
except:
print(sys.exc_info()[2])
Example 1
では、漏洩情報に、オペレーティングシステムのタイプ、システムにインストールされているアプリケーション、およびプログラムの設定に対する管理者の警戒度についての情報が含まれています。
...
begin
log = Logger.new(STDERR)
...
rescue Exception
log.info("Exception: " + $!)
...
end
Example 1
では、漏洩情報に、オペレーティングシステムのタイプ、システムにインストールされているアプリケーション、およびプログラムの設定に対する管理者の警戒度についての情報が含まれています。当然、Example 1
には、特定のタイプのエラー/例外ではなくルート Exception
を救済するという問題もあります。つまり、すべての例外がキャッチされるため、他にも不用意で副次的な状況が発生する可能性があります。
...
println(Properties.osName)
...
Example 1
では、漏洩情報に、オペレーティングシステムのタイプ、システムにインストールされているアプリケーション、およびプログラムの設定に対する管理者の警戒度についての情報が含まれています。
let deviceName = UIDevice.currentDevice().name
...
NSLog("Device Identifier: %@", deviceName)
ASPError
オブジェクトを Microsoft Script Debugger などのスクリプトデバッガーに送ります。
...
Debug.Write Server.GetLastError()
...
StreamReader
の Finalize()
メソッドは最終的に Close()
をコールしますが、Finalize()
メソッドが呼び出されるまでの所要時間には何も保証がありません。それどころか、Finalize()
が呼び出されるという保証すらありません。その結果、処理量が多い環境では、利用可能なファイルハンドラを VM が使い尽くしてしまう可能性があります。
private void processFile(string fName) {
StreamWriter sw = new StreamWriter(fName);
string line;
while ((line = sr.ReadLine()) != null)
processLine(line);
}
FileInputStream
の finalize()
メソッドは最終的に close()
をコールしますが、finalize()
メソッドが呼び出されるまでにどれくらいの時間がかかるかは保証されません。つまり、使用中の環境では JVM ですべてのファイルハンドルを使い切ってしまう場合もあります。
private void processFile(String fName) throws FileNotFoundException, IOException {
FileInputStream fis = new FileInputStream(fName);
int sz;
byte[] byteArray = new byte[BLOCK_SIZE];
while ((sz = fis.read(byteArray)) != -1) {
processBytes(byteArray, sz);
}
}
...
CFIndex numBytes;
do {
UInt8 buf[bufferSize];
numBytes = CFReadStreamRead(readStream, buf, sizeof(buf));
if( numBytes > 0 ) {
handleBytes(buf, numBytes);
} else if( numBytes < 0 ) {
CFStreamError error = CFReadStreamGetError(readStream);
reportError(error);
}
} while( numBytes > 0 );
...
def readFile(filename: String): Unit = {
val data = Source.fromFile(fileName).getLines.mkString
// Use the data
}
...
func leak(reading input: InputStream) {
input.open()
let bufferSize = 1024
let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: bufferSize)
while input.hasBytesAvailable {
let read = input.read(buffer, maxLength: bufferSize)
}
buffer.deallocate(capacity: bufferSize)
}
...
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);
...
例 2: 前の例と同様に、アプリケーションは
...
func beforeExampleCallback(scope *Scope){
input := os.Args[1]
if input{
scope.CallMethod(input)
}
}
...
reflect
パッケージを使用して、コマンドライン引数から、呼び出される関数の名前を取得します。
...
input := os.Args[1]
var worker WokerType
reflect.ValueOf(&worker).MethodByName(input).Call([]reflect.Value{})
...
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>
<?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 で購入できます。