...
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
中,搜索路径可能会暗示操作系统的类型、系统上安装了哪些应用程序以及管理员在配置程序时采取了哪些保护措施。<apex:messages/>
元素中泄露异常信息:
try {
...
} catch (Exception e) {
ApexPages.Message msg = new ApexPages.Message(ApexPages.Severity.FATAL, e.getMessage());
ApexPages.addMessage(msg);
}
try
{
...
}
catch (Exception e)
{
Response.Write(e.ToString());
}
Example 1
中,泄露的信息可能会暗示有关操作系统类型、系统上安装了哪些应用程序以及管理员在配置程序时采取了哪些保护措施的信息。
int sockfd;
int flags;
char hostname[1024];
hostname[1023] = '\0';
gethostname(hostname, 1023);
...
sockfd = socket(AF_INET, SOCK_STREAM, 0);
flags = 0;
send(sockfd, hostname, strlen(hostname), flags);
Example 1
中,搜索路径可能会暗示操作系统的类型、系统上安装了哪些应用程序以及管理员在配置程序时采取了哪些保护措施。SQLCODE
和错误消息 SQlERRMC
。
...
EXEC SQL
WHENEVER SQLERROR
PERFORM DEBUG-ERR
SQL-EXEC.
...
DEBUG-ERR.
DISPLAY "Error code is: " SQLCODE.
DISPLAY "Error message is: " SQLERRMC.
...
Example 1
中,可通过一条数据库错误消息来揭示应用程序容易受到 SQL Injection 攻击。其他的错误消息可以揭示有关该系统的更多间接线索。
<cfcatch type="Any">
<cfset exception=getException(myObj)>
<cfset message=exception.toString()>
<cfoutput>
Exception message: #message#
</cfoutput>
</cfcatch>
func handler(w http.ResponseWriter, r *http.Request) {
host, err := os.Hostname()
...
fmt.Fprintf(w, "%s is busy, please try again later.", host)
}
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);
...
...
dirReader.readEntries(function(results){
...
}, function(error){
$("#myTextArea").val('There was a problem: ' + error);
});
...
Example 1
中,泄露的信息可能会暗示有关操作系统类型、系统上安装了哪些应用程序以及管理员在配置程序时采取了哪些保护措施的信息。
protected fun doPost(req: HttpServletRequest, res: HttpServletResponse) {
...
val out: PrintWriter = res.getWriter()
try {
...
} catch (e: Exception) {
out.println(e.message)
}
}
Example 1
中,泄露的信息可能会暗示有关操作系统类型、系统上安装了哪些应用程序以及管理员在配置程序时采取了哪些保护措施的信息。
...
try {
...
} catch (e: Exception) {
val exception = Log.getStackTraceString(e)
val intent = Intent()
intent.action = "SEND_EXCEPTION"
intent.putExtra("exception", exception)
view.context.sendBroadcast(intent)
}
...
...
companion object {
const val TAG = "NfcActivity"
private const val DATA_SPLITTER = "__:DATA:__"
private const val MIME_TYPE = "application/my.applications.mimetype"
}
...
val tm = Context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
val VERSION = tm.getDeviceSoftwareVersion();
...
val nfcAdapter = NfcAdapter.getDefaultAdapter(this)
val text: String = "$TAG$DATA_SPLITTER$VERSION"
val record = NdefRecord(NdefRecord.TNF_MIME_MEDIA, MIME_TYPE.getBytes(), ByteArray(0), text.toByteArray())
val records = arrayOf(record)
val msg = NdefMessage(records)
nfcAdapter.setNdefPushMessage(msg, this)
...
NSString *deviceName = [[UIDevice currentDevice] name];
NSString *baseUrl = @"http://myserver.com/?dev=";
NSString *urlString = [baseUrl stringByAppendingString:deviceName];
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest* request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
NSError *err = nil;
NSURLResponse* response = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
<?php
...
echo "Server error! Printing the backtrace";
debug_print_backtrace();
...
?>
Example 1
中,泄露的信息可能会暗示有关操作系统类型、系统上安装了哪些应用程序以及管理员在配置程序时采取了哪些保护措施的信息。PATH_INFO
和 SCRIPT_NAME
。
...
HTP.htmlOpen;
HTP.headOpen;
HTP.title ('Environment Information');
HTP.headClose;
HTP.bodyOpen;
HTP.br;
HTP.print('Path Information: ' ||
OWA_UTIL.get_cgi_env('PATH_INFO') || '');
HTP.print('Script Name: ' ||
OWA_UTIL.get_cgi_env('SCRIPT_NAME') || '');
HTP.br;
HTP.bodyClose;
HTP.htmlClose;
...
}
Example 1
中,搜索路径可能会暗示操作系统的类型、系统上安装了哪些应用程序以及管理员在配置程序时采取了哪些保护措施。
...
import cgi
cgi.print_environ()
...
Example 1
中,泄露的信息可能会暗示有关操作系统类型、系统上安装了哪些应用程序以及管理员在配置程序时采取了哪些保护措施的信息。
response = Rack::Response.new
...
stacktrace = caller # Kernel#caller returns an array of the execution stack
...
response.finish do |res|
res.write "There was a problem: #{stacktrace}"
end
Example 1
中,搜索路径可能会暗示操作系统的类型、系统上安装了哪些应用程序以及管理员在配置程序时采取了哪些保护措施。
def doSomething() = Action { request =>
...
Ok(Html(Properties.osName)) as HTML
}
Example 1
中,泄露的信息可能会暗示有关操作系统类型、系统上安装了哪些应用程序以及管理员在配置程序时采取了哪些保护措施的信息。
let deviceName = UIDevice.currentDevice().name
let urlString : String = "http://myserver.com/?dev=\(deviceName)"
let url : NSURL = NSURL(string:urlString)
let request : NSURLRequest = NSURLRequest(URL:url)
var err : NSError?
var response : NSURLResponse?
var data : NSData = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error:&err)
Response
输出流:
...
If Err.number <>0 then
Response.Write "An Error Has Occurred on this page!<BR>"
Response.Write "The Error Number is: " & Err.number & "<BR>"
Response.Write "The Description given is: " & Err.Description & "<BR>"
End If
...
Example 1
中,泄露的信息可能会暗示有关操作系统类型、系统上安装了哪些应用程序以及管理员在配置程序时采取了哪些保护措施的信息。
...
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
对象:
...
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
...
...
DATA(ixml) = cl_ixml=>create( ).
DATA(stream_factory) = ixml->create_stream_factory( ).
istream = stream_factory->create_istream_string(
`<?xml version="1.0" encoding="UTF-8"?> ` &&
`<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]> ` &&
`<stockCheck>&xxe;</stockCheck>` ).
istream->set_dtd_restriction( level = 0 ).
DATA(document) = ixml->create_document( ).
parser = ixml->create_parser(
stream_factory = stream_factory
istream = istream
document = document ).
parser->set_validating( mode = `0` ).
DATA(rc) = parser->parse( ).
...
<?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 的形式如下所示:
<?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>
String xml = "...";
...
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
DefaultHandler handler = new DefaultHandler() {
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
System.out.println(new String(ch, start, length));
}
};
saxParser.parse(new InputSource(new StringReader(xml)), handler);
} catch (Exception e) {
e.printStackTrace();
}
...
<?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 的形式如下所示:
<?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 version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///c:/boot.ini" >]><foo>&xxe;</foo>
boot.ini
文件的内容填充 <foo> 元素的内容。攻击者可能会利用返回到客户端的 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 的形式如下所示:
<?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>
标签中的值。这样,攻击者就可以只花 1 美元购买一双价值 100 美元的鞋。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>
标签中的值。这样,攻击者就可以只花 1 美元购买一双价值 100 美元的鞋。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>
标签中的值。这样,攻击者就可以只花 1 美元购买一双价值 100 美元的鞋。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>
标签中的值。这样,攻击者就可以只花 1 美元购买一双价值 100 美元的鞋。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>
标签中的值。这样,攻击者就可以只花 1 美元购买一双价值 100 美元的鞋。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>
标签中的值。这样,攻击者就可以只花 1 美元购买一双价值 100 美元的鞋。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>
标签中的值。这样,攻击者就可以只花 1 美元购买一双价值 100 美元的鞋。
...
<?php
$goodXML = $_GET["key"];
$doc = simplexml_load_string($goodXml);
echo $doc->testing;
?>
...
Example 2
中的代码:
<?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
文件的内容填充 <foo> 元素的内容。攻击者可能会利用返回到客户端的 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>
标签中的值。这样,攻击者就可以只花 1 美元购买一双价值 100 美元的鞋。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>
标签中的值。这样,攻击者就可以只花 1 美元购买一双价值 100 美元的鞋。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>
标签中的值。这样,攻击者就可以只花 1 美元购买一双价值 100 美元的鞋。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>
标签中的值。这样,攻击者就可以只花 1 美元购买一双价值 100 美元的鞋。