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
se han eliminado por completo y ahora es posible agregar nuevos tipos de comando sin modificar el distribuidor de comandos.Worker
. Si el distribuidor de comandos sigue siendo responsable del control de acceso, entonces cada vez que los programadores creen una nueva clase que implemente la interfaz Worker
, no deben olvidar modificar el código de control de acceso del distribuidor. Si no pueden modificar el código de control de acceso, algunas clases Worker
no tendrán ningún control de acceso.Worker
sea responsable de realizar la comprobación de control de acceso. A continuación se muestra un ejemplo del código refactorizado:
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
podría permitir a los atacantes crear rutas de flujo de control inesperadas a través de la aplicación, lo que podría eludir los controles de seguridad.continuationMethod
, que determina el nombre del método al que se llamará al recibir una respuesta.
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
se establezca mediante parámetros de solicitud de tiempo de ejecución, lo que permite a los atacantes llamar a cualquier función que coincida con el nombre.
...
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
se han eliminado por completo y ahora es posible agregar nuevos tipos de comando sin modificar el distribuidor de comandos.Worker
. Si el distribuidor de comandos se encarga del control de acceso, cada vez que los programadores creen un número método en la clase Worker
, deben acordarse de modificar la lógica de control de acceso del distribuidor. Si esta lógica de control de acceso se queda obsoleta, algunos métodos Worker
no tendrán ningún control de acceso.Worker
sea responsable de realizar la comprobación de control de acceso. A continuación se muestra un ejemplo del código refactorizado:
...
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
se han eliminado por completo y ahora es posible agregar nuevos tipos de comando sin modificar el distribuidor de comandos.Worker
. Si el distribuidor de comandos sigue siendo responsable del control de acceso, entonces cada vez que los programadores creen una nueva clase que implemente la interfaz Worker
, no deben olvidar modificar el código de control de acceso del distribuidor. Si no pueden modificar el código de control de acceso, algunas clases Worker
no tendrán ningún control de acceso.Worker
sea responsable de realizar la comprobación de control de acceso. A continuación se muestra un ejemplo del código refactorizado:
String ctl = request.getParameter("ctl");
Class cmdClass = Class.forName(ctl + "Command");
Worker ao = (Worker) cmdClass.newInstance();
ao.checkAccessControl(request);
ao.doAction(request);
Worker
; se puede llamar al constructor predeterminado de cualquier objeto del sistema. Si el objeto no implementa la interfaz de Worker
, se generará una ClassCastException
antes de la asignación a ao
. Sin embargo, si el constructor realiza operaciones que trabajan a favor del usuario malintencionado, el daño ya estará hecho. Aunque este escenario es relativamente benigno en aplicaciones sencillas, en las aplicaciones de mayor tamaño en las que la complejidad crece exponencialmente, es razonable creer que un usuario malintencionado podría encontrar un constructor para aprovecharlo como parte de un ataque.performSelector
, lo que podría permitirles crear rutas de flujo de control inesperadas a través de la aplicación, omitiendo potencialmente las comprobaciones de seguridad.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
se han eliminado por completo y ahora es posible agregar nuevos tipos de comando sin modificar el distribuidor de comandos.Worker
. Si el distribuidor de comandos sigue siendo responsable del control de acceso, entonces cada vez que los programadores creen una nueva clase que implemente la interfaz Worker
, no deben olvidar modificar el código de control de acceso del distribuidor. Si no pueden modificar el código de control de acceso, algunas clases Worker
no tendrán ningún control de acceso.Worker
sea responsable de realizar la comprobación de control de acceso. A continuación se muestra un ejemplo del código refactorizado:
$ctl = $_GET["ctl"];
$args = $_GET["args"];
$cmdClass = new ReflectionClass(ctl . "Command");
$ao = $cmdClass->newInstance($args);
$ao->checkAccessControl(request);
ao->doAction(request);
Worker
; se puede llamar al constructor predeterminado de cualquier objeto del sistema. Si el objeto no implementa la interfaz de Worker
, se generará una ClassCastException
antes de la asignación a $ao
. Sin embargo, si el constructor realiza operaciones que trabajan a favor del usuario malintencionado, el daño ya estará hecho. Aunque este escenario es relativamente benigno en aplicaciones sencillas, en las aplicaciones de mayor tamaño en las que la complejidad crece exponencialmente, es razonable creer que un usuario malintencionado podría encontrar un constructor para aprovecharlo como parte de un 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
se han eliminado por completo y ahora es posible agregar nuevos tipos de comando sin modificar el distribuidor de comandos.define_method()
o llamarlos mediante el reemplazo de missing_method()
. Auditar y realizar un seguimiento de estos métodos y de cómo se utiliza el código de control de acceso con ellos resulta muy difícil, y si consideramos que también depende de qué código de biblioteca se cargue, realizar esta tarea correctamente puede convertirse en una misión imposible.
def exec(ctl: String) = Action { request =>
val cmdClass = Platform.getClassForName(ctl + "Command")
Worker ao = (Worker) cmdClass.newInstance()
ao.doAction(request)
...
}
if/else
se han eliminado por completo y ahora es posible agregar nuevos tipos de comando sin modificar el distribuidor de comandos.Worker
. Si el distribuidor de comandos sigue siendo responsable del control de acceso, entonces cada vez que los programadores creen una nueva clase que implemente la interfaz Worker
, no deben olvidar modificar el código de control de acceso del distribuidor. Si no pueden modificar el código de control de acceso, algunas clases Worker
no tendrán ningún control de acceso.Worker
sea responsable de realizar la comprobación de control de acceso. A continuación se muestra un ejemplo del código refactorizado:
def exec(ctl: String) = Action { request =>
val cmdClass = Platform.getClassForName(ctl + "Command")
Worker ao = (Worker) cmdClass.newInstance()
ao.checkAccessControl(request);
ao.doAction(request)
...
}
Worker
; se puede llamar al constructor predeterminado de cualquier objeto del sistema. Si el objeto no implementa la interfaz de Worker
, se generará una ClassCastException
antes de la asignación a ao
. Sin embargo, si el constructor realiza operaciones que trabajan a favor del usuario malintencionado, el daño ya estará hecho. Aunque este escenario es relativamente benigno en aplicaciones sencillas, en las aplicaciones de mayor tamaño en las que la complejidad crece exponencialmente, es razonable creer que un usuario malintencionado podría encontrar un constructor para aprovecharlo como parte de un ataque.performSelector
, lo que podría permitirles crear rutas de flujo de control inesperadas a través de la aplicación, omitiendo potencialmente las comprobaciones de seguridad.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
se han eliminado por completo y ahora es posible agregar nuevos tipos de comando sin modificar el distribuidor de comandos.Worker
. Si el distribuidor de comandos sigue siendo responsable del control de acceso, siempre que los programadores creen un nuevo método dentro de la clase Worker
, deberán acordarse de modificar el código de control de acceso del distribuidor. Si no pueden modificar el código de control de acceso, algunos métodos de Worker
no tendrán ningún control de acceso.Worker
sea responsable de realizar la comprobación de control de acceso. A continuación se muestra un ejemplo del código refactorizado:
...
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 el código XML sea similar al siguiente:
<?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 el código XML sea similar al siguiente:
<?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
del sistema. El atacante podría utilizar los elementos XML que se devuelven al cliente para extraer datos u obtener información sobre la existencia de recursos de red.
<?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
y lo incluirá en el 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 el código XML sea similar al siguiente:
<?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
en el siguiente documento XML.
<order>
<price>100.00</price>
<item>shoes</item>
</order>
shoes
por shoes</item><price>1.00</price><item>shoes
. El nuevo documento XML sería:
<order>
<price>100.00</price>
<item>shoes</item><price>1.00</price><item>shoes</item>
</order>
<price>
anula el valor de la primera etiqueta <price>
. Esto permite que el atacante compre un par de zapatos de 100 $ a 1 $.shoes
en el siguiente documento XML.
<order>
<price>100.00</price>
<item>shoes</item>
</order>
shoes
por shoes</item><price>1.00</price><item>shoes
. El nuevo documento XML sería:
<order>
<price>100.00</price>
<item>shoes</item><price>1.00</price><item>shoes</item>
</order>
<price>
anula el valor de la primera etiqueta <price>
. Esto permite que el atacante compre un par de zapatos de 100 $ a 1 $.shoes
en el siguiente documento XML:
<order>
<price>100.00</price>
<item>shoes</item>
</order>
shoes
por shoes</item><price>1.00</price><item>shoes
. El XML nuevo tendría este aspecto:
<order>
<price>100.00</price>
<item>shoes</item><price>1.00</price><item>shoes</item>
</order>
<price>
anula el valor de la primera etiqueta <price>
. Esto permite que el atacante compre un par de zapatos de $ 100 a $ 1.shoes
en el siguiente documento XML.
<order>
<price>100.00</price>
<item>shoes</item>
</order>
shoes
por shoes</item><price>1.00</price><item>shoes
. El nuevo documento XML sería:
<order>
<price>100.00</price>
<item>shoes</item><price>1.00</price><item>shoes</item>
</order>
<price>
anula el valor de la primera etiqueta <price>
. Esto permite que el atacante compre un par de zapatos de 100 $ a 1 $.shoes
en el siguiente documento XML:
<order>
<price>100.00</price>
<item>shoes</item>
</order>
shoes
por shoes</item><price>1.00</price><item>shoes
. El nuevo documento XML sería:
<order>
<price>100.00</price>
<item>shoes</item><price>1.00</price><item>shoes</item>
</order>
shoes
en el siguiente documento XML.
<order>
<price>100.00</price>
<item>shoes</item>
</order>
shoes
por shoes</item><price>1.00</price><item>shoes
. El nuevo documento XML sería:
<order>
<price>100.00</price>
<item>shoes</item><price>1.00</price><item>shoes</item>
</order>
<price>
anula el valor de la primera etiqueta <price>
. Esto permite que el atacante compre un par de zapatos de 100 $ a 1 $.shoes
en el siguiente documento XML.
<order>
<price>100.00</price>
<item>shoes</item>
</order>
shoes
por shoes</item><price>1.00</price><item>shoes
. El nuevo documento XML sería:
<order>
<price>100.00</price>
<item>shoes</item><price>1.00</price><item>shoes</item>
</order>
<price>
anula el valor de la primera etiqueta <price>
. Esto permite que el atacante compre un par de zapatos de 100 $ a 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
del sistema. El atacante podría utilizar los elementos XML que se devuelven al cliente para extraer datos u obtener información sobre la existencia de recursos de red.shoes
en el siguiente documento XML.
<order>
<price>100.00</price>
<item>shoes</item>
</order>
shoes
por shoes</item><price>1.00</price><item>shoes
. El nuevo documento XML sería:
<order>
<price>100.00</price>
<item>shoes</item><price>1.00</price><item>shoes</item>
</order>
<price>
anula el valor de la primera etiqueta <price>
. Esto permite que el atacante compre un par de zapatos de 100 $ a 1 $.shoes
en el siguiente documento XML.
<order>
<price>100.00</price>
<item>shoes</item>
</order>
shoes
por shoes</item><price>1.00</price><item>shoes
. El nuevo documento XML sería:
<order>
<price>100.00</price>
<item>shoes</item><price>1.00</price><item>shoes</item>
</order>
<price>
anula el valor de la primera etiqueta <price>
. Esto permite que el atacante compre un par de zapatos de 100 $ a 1 $.shoes
en el siguiente documento XML.
<order>
<price>100.00</price>
<item>shoes</item>
</order>
shoes
por shoes</item><price>1.00</price><item>shoes
. El nuevo documento XML sería:
<order>
<price>100.00</price>
<item>shoes</item><price>1.00</price><item>shoes</item>
</order>
<price>
anula el valor de la primera etiqueta <price>
. Esto permite que el atacante compre un par de zapatos de 100 $ a 1 $.shoes
en el siguiente documento XML.
<order>
<price>100.00</price>
<item>shoes</item>
</order>
shoes
por shoes</item><price>1.00</price><item>shoes
. El nuevo documento XML sería:
<order>
<price>100.00</price>
<item>shoes</item><price>1.00</price><item>shoes</item>
</order>
<price>
anula el valor de la primera etiqueta <price>
. Esto permite que el atacante compre un par de zapatos de 100 $ a 1 $.