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
foram totalmente eliminados e agora é possível adicionar novos tipos de comando sem modificar o expedidor de comandos.Worker
. Se o expedidor de comandos ainda for responsável pelo controle de acesso, sempre que os programadores criarem uma nova classe que implementa a interface Worker
, eles deverão se lembrar de modificar o código de controle de acesso do expedidor. Se o código de controle de acesso não for modificado, algumas classes Worker
não terão controle de acesso.Worker
responsável pela execução da verificação de controle de acesso. Veja a seguir um exemplo do código novamente refatorado:
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
pode permitir que invasores criem caminhos de fluxo de controle inesperados através do aplicativo, potencialmente ignorando as verificações de segurança.continuationMethod
, que determina o nome do método a ser chamado ao receber uma resposta.
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
seja definida por parâmetros de solicitação de tempo de execução, o que permite que invasores chamem qualquer função que corresponda ao nome.
...
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
foram totalmente eliminados e agora é possível adicionar novos tipos de comando sem modificar o expedidor de comandos.Worker
. Se o dispatcher de comandos for responsável pelo controle de acesso, sempre que os programadores criarem um novo método na classe Worker
, eles deverão modificar a lógica de controle de acesso do dispatcher. Se essa lógica de controle de acesso se tornar obsoleta, alguns métodos Worker
não terão controle de acesso.Worker
responsável pela execução da verificação de controle de acesso. Veja a seguir um exemplo do código novamente refatorado:
...
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
foram totalmente eliminados e agora é possível adicionar novos tipos de comando sem modificar o expedidor de comandos.Worker
. Se o expedidor de comandos ainda for responsável pelo controle de acesso, sempre que os programadores criarem uma nova classe que implementa a interface Worker
, eles deverão se lembrar de modificar o código de controle de acesso do expedidor. Se o código de controle de acesso não for modificado, algumas classes Worker
não terão controle de acesso.Worker
responsável pela execução da verificação de controle de acesso. Veja a seguir um exemplo do código novamente refatorado:
String ctl = request.getParameter("ctl");
Class cmdClass = Class.forName(ctl + "Command");
Worker ao = (Worker) cmdClass.newInstance();
ao.checkAccessControl(request);
ao.doAction(request);
Worker
; o construtor padrão para qualquer objeto no sistema pode ser invocado. Se o objeto não implementar a interface Worker
, um ClassCastException
será lançado antes da atribuição a ao
, mas, se o construtor realizar operações que funcionarem a favor do invasor, os danos já terão sido feitos. Embora esse cenário seja relativamente favorável em aplicativos simples, em aplicativos maiores, nos quais a complexidade cresce exponencialmente, não é absurdo considerar que um invasor possa encontrar um construtor a ser otimizado como parte de um ataque.performSelector
, o que pode permitir que eles criem caminhos inesperados de controle de fluxo por meio do aplicativo, potencialmente ignorando as verificações de segurança.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
foram totalmente eliminados e agora é possível adicionar novos tipos de comando sem modificar o expedidor de comandos.Worker
. Se o expedidor de comandos ainda for responsável pelo controle de acesso, sempre que os programadores criarem uma nova classe que implementa a interface Worker
, eles deverão se lembrar de modificar o código de controle de acesso do expedidor. Se o código de controle de acesso não for modificado, algumas classes Worker
não terão controle de acesso.Worker
responsável pela execução da verificação de controle de acesso. Veja a seguir um exemplo do código novamente refatorado:
$ctl = $_GET["ctl"];
$args = $_GET["args"];
$cmdClass = new ReflectionClass(ctl . "Command");
$ao = $cmdClass->newInstance($args);
$ao->checkAccessControl(request);
ao->doAction(request);
Worker
; o construtor padrão para qualquer objeto no sistema pode ser invocado. Se o objeto não implementar a interface Worker
, um ClassCastException
será lançado antes da atribuição a $ao
, mas, se o construtor realizar operações que funcionarem a favor do invasor, os danos já terão sido feitos. Embora esse cenário seja relativamente favorável em aplicativos simples, em aplicativos maiores, nos quais a complexidade cresce exponencialmente, não é absurdo considerar que um invasor possa encontrar um construtor a ser otimizado como parte de um ataque.
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
foram totalmente eliminados e agora é possível adicionar novos tipos de comando sem modificar o expedidor de comandos.define_method()
, ou pode ser chamá-los ao substituir missing_method()
. Fazer a auditoria e o rastreio desses métodos assim como de que maneira o código de controle é utilizado com eles é muito difícil e, ao considerar essa situação, ela também dependerá de quais outros códigos de biblioteca estão carregados; isso fará com que essa tarefa seja quase impossível de realizar corretamente.
def exec(ctl: String) = Action { request =>
val cmdClass = Platform.getClassForName(ctl + "Command")
Worker ao = (Worker) cmdClass.newInstance()
ao.doAction(request)
...
}
if/else
foram totalmente eliminados e agora é possível adicionar novos tipos de comando sem modificar o expedidor de comandos.Worker
. Se o expedidor de comandos ainda for responsável pelo controle de acesso, sempre que os programadores criarem uma nova classe que implementa a interface Worker
, eles deverão se lembrar de modificar o código de controle de acesso do expedidor. Se o código de controle de acesso não for modificado, algumas classes Worker
não terão controle de acesso.Worker
responsável pela execução da verificação de controle de acesso. Veja a seguir um exemplo do código novamente refatorado:
def exec(ctl: String) = Action { request =>
val cmdClass = Platform.getClassForName(ctl + "Command")
Worker ao = (Worker) cmdClass.newInstance()
ao.checkAccessControl(request);
ao.doAction(request)
...
}
Worker
; o construtor padrão para qualquer objeto no sistema pode ser invocado. Se o objeto não implementar a interface Worker
, um ClassCastException
será lançado antes da atribuição a ao
, mas, se o construtor realizar operações que funcionarem a favor do invasor, os danos já terão sido feitos. Embora esse cenário seja relativamente favorável em aplicativos simples, em aplicativos maiores, nos quais a complexidade cresce exponencialmente, não é absurdo considerar que um invasor possa encontrar um construtor a ser otimizado como parte de um ataque.performSelector
, o que pode permitir que eles criem caminhos inesperados de controle de fluxo por meio do aplicativo, potencialmente ignorando as verificações de segurança.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
foram totalmente eliminados e agora é possível adicionar novos tipos de comando sem modificar o expedidor de comandos.Worker
. Se o dispatcher de comandos ainda for responsável pelo controle de acesso, sempre que os programadores criarem um novo método na classe Worker
, eles deverão se lembrar de modificar o código de controle de acesso do dispatcher. Se eles não conseguirem modificar o código de controle de acesso, alguns métodos Worker
não terão nenhum controle de acesso.Worker
responsável pela execução da verificação de controle de acesso. Veja a seguir um exemplo do código novamente refatorado:
...
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
de tal forma que o XML tenha a seguinte aparência:
<?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
de tal forma que o XML tenha a seguinte aparência:
<?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
do sistema. O invasor pode usar elementos XML que são devolvidos ao cliente para roubar dados ou obter informações sobre a existência de recursos de rede.
<?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
e o incluirá no documento.
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
de tal forma que o XML tenha a seguinte aparência:
<?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
no seguinte XML.
<order>
<price>100.00</price>
<item>shoes</item>
</order>
shoes
com por shoes</item><price>1.00</price><item>shoes
. O novo XML teria a seguinte aparência:
<order>
<price>100.00</price>
<item>shoes</item><price>1.00</price><item>shoes</item>
</order>
<price>
substitui o valor da primeira tag <price>
. Isso permite que o invasor compre um par de sapatos de $100 por apenas $1.shoes
no seguinte XML.
<order>
<price>100.00</price>
<item>shoes</item>
</order>
shoes
com por shoes</item><price>1.00</price><item>shoes
. O novo XML teria a seguinte aparência:
<order>
<price>100.00</price>
<item>shoes</item><price>1.00</price><item>shoes</item>
</order>
<price>
substitui o valor da primeira tag <price>
. Isso permite que o invasor compre um par de sapatos de $100 por apenas $1.shoes
no seguinte XML:
<order>
<price>100.00</price>
<item>shoes</item>
</order>
shoes
com por shoes</item><price>1.00</price><item>shoes
. O novo XML teria a seguinte aparência:
<order>
<price>100.00</price>
<item>shoes</item><price>1.00</price><item>shoes</item>
</order>
<price>
. Isso permite que o invasor compre um par de sapatos de $100 por apenas $1.shoes
no seguinte XML.
<order>
<price>100.00</price>
<item>shoes</item>
</order>
shoes
com por shoes</item><price>1.00</price><item>shoes
. O novo XML teria a seguinte aparência:
<order>
<price>100.00</price>
<item>shoes</item><price>1.00</price><item>shoes</item>
</order>
<price>
substitui o valor da primeira tag <price>
. Isso permite que o invasor compre um par de sapatos de $100 por apenas $1.shoes
no XML a seguir.
<order>
<price>100.00</price>
<item>shoes</item>
</order>
shoes
com por shoes</item><price>1.00</price><item>shoes
. O novo XML teria a seguinte aparência:
<order>
<price>100.00</price>
<item>shoes</item><price>1.00</price><item>shoes</item>
</order>
shoes
no seguinte XML.
<order>
<price>100.00</price>
<item>shoes</item>
</order>
shoes
com por shoes</item><price>1.00</price><item>shoes
. O novo XML teria a seguinte aparência:
<order>
<price>100.00</price>
<item>shoes</item><price>1.00</price><item>shoes</item>
</order>
<price>
substitui o valor da primeira tag <price>
. Isso permite que o invasor compre um par de sapatos de $100 por apenas $1.shoes
no seguinte XML.
<order>
<price>100.00</price>
<item>shoes</item>
</order>
shoes
com por shoes</item><price>1.00</price><item>shoes
. O novo XML teria a seguinte aparência:
<order>
<price>100.00</price>
<item>shoes</item><price>1.00</price><item>shoes</item>
</order>
<price>
substitui o valor da primeira marca <price>
. Isso permite que o invasor compre um par de sapatos de $100 por apenas $1.
...
<?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
do sistema. O invasor pode usar elementos XML que são devolvidos ao cliente para roubar dados ou obter informações sobre a existência de recursos de rede.shoes
no seguinte XML.
<order>
<price>100.00</price>
<item>shoes</item>
</order>
shoes
com por shoes</item><price>1.00</price><item>shoes
. O novo XML teria a seguinte aparência:
<order>
<price>100.00</price>
<item>shoes</item><price>1.00</price><item>shoes</item>
</order>
<price>
substitui o valor da primeira tag <price>
. Isso permite que o invasor compre um par de sapatos de $100 por apenas $1.shoes
no seguinte XML.
<order>
<price>100.00</price>
<item>shoes</item>
</order>
shoes
com por shoes</item><price>1.00</price><item>shoes
. O novo XML teria a seguinte aparência:
<order>
<price>100.00</price>
<item>shoes</item><price>1.00</price><item>shoes</item>
</order>
<price>
substitui o valor da primeira tag <price>
. Isso permite que o invasor compre um par de sapatos de $100 por apenas $1.shoes
no seguinte XML.
<order>
<price>100.00</price>
<item>shoes</item>
</order>
shoes
com por shoes</item><price>1.00</price><item>shoes
. O novo XML teria a seguinte aparência:
<order>
<price>100.00</price>
<item>shoes</item><price>1.00</price><item>shoes</item>
</order>
<price>
substitui o valor da primeira marca <price>
.Isso permite que o invasor compre um par de sapatos de $100 por apenas $1.shoes
no XML a seguir.
<order>
<price>100.00</price>
<item>shoes</item>
</order>
shoes
com por shoes</item><price>1.00</price><item>shoes
. O novo XML teria a seguinte aparência:
<order>
<price>100.00</price>
<item>shoes</item><price>1.00</price><item>shoes</item>
</order>
<price>
substitui o valor da primeira tag <price>
. Isso permite que o invasor compre um par de sapatos de $100 por apenas $1.