La doble codificación es el acto de codificar datos dos veces seguidas utilizando el mismo esquema de codificación. Generalmente se utiliza como técnica de ataque para eludir esquemas de autorización o filtros de seguridad que interceptan la entrada del usuario. En los ataques de doble codificación contra filtros de seguridad, los caracteres de la carga útil que esos filtros consideran ilegales se reemplazan con su forma de doble codificación.
La codificación URI doble es un tipo especial de codificación doble en la que los datos se codifican en URI dos veces seguidas. Se ha utilizado para eludir esquemas de autorización y filtros de seguridad contra inyección de código , cruce de directorios , secuencias de comandos entre sitios (XSS) e inyección SQL .
En la codificación doble, los datos se codifican dos veces seguidas utilizando el mismo esquema de codificación, es decir, la forma de datos con doble codificación X
es Encode(Encode(X))
donde Encode
es una función de codificación. [1]
La doble codificación se utiliza habitualmente como técnica de ataque para eludir los esquemas de autorización o los filtros de seguridad que interceptan la entrada del usuario. [2] En los ataques de doble codificación contra filtros de seguridad, los caracteres de la carga útil que son tratados como ilegales por esos filtros se reemplazan con su forma doblemente codificada. [3] Los filtros de seguridad pueden tratar los datos X
y su forma codificada como ilegales. [4] Sin embargo, todavía es posible que Encode(Encode(X))
, que es la forma doblemente codificada de los datos X
, no sea tratada como ilegal por los filtros de seguridad y, por lo tanto, pase a través de ellos, pero más adelante, el sistema de destino podría usar la forma doblemente decodificada de Encode(Encode(X))
, que es X
, algo que los filtros habrían tratado como ilegal. [5]
La codificación URI doble, también denominada codificación de porcentaje doble, es un tipo especial de codificación doble en la que los datos se codifican URI dos veces seguidas. [6] En otras palabras, la forma de datos con codificación URI doble X
es URI-encode(URI-encode(X))
. [7] Por ejemplo, para calcular la forma de codificación URI doble de <
, primero <
se codifica URI como %3C
que luego, a su vez, se codifica URI como %253C
, es decir, double-URI-encode(<) = URI-encode(URI-encode(<)) = URI-encode(%3C) = %253C
. [8] Como otro ejemplo, para calcular la forma de codificación URI doble de ../
, primero ../
se codifica URI como %2E%2E%2F
que luego, a su vez, se codifica URI como %252E%252E%252F
, es decir, double-URI-encode(../) = URI-encode(URI-encode(../)) = URI-encode(%2E%2E%2F) = %252E%252E%252F
. [9]
La codificación doble de URI se utiliza habitualmente como técnica de ataque contra aplicaciones web y navegadores web para eludir esquemas de autorización y filtros de seguridad que interceptan la entrada del usuario. [10] [11] Por ejemplo, debido a que .
y su forma codificada en URI %2E
se utilizan en algunos ataques de recorrido de directorio, normalmente los filtros de seguridad los tratan como ilegales. [12] Sin embargo, todavía es posible que %252E
, que es la forma de doble codificación de URI de .
, no sea tratada como ilegal por los filtros de seguridad y, por tanto, pase a través de ellos, pero más adelante, cuando el sistema de destino esté construyendo la ruta relacionada con el ataque de recorrido de directorio, podría utilizar la forma de doble codificación de URI de %252E
, que es .
, algo que los filtros habrían tratado como ilegal. [13]
Se han utilizado ataques de doble codificación de URI para eludir esquemas de autorización y filtros de seguridad contra inyección de código, recorrido de directorios, XSS e inyección SQL. [14]
La decodificación de una entrada de usuario dos veces utilizando el mismo esquema de decodificación, una vez antes de una medida de seguridad y otra después, puede permitir que ataques de doble codificación eviten esa medida de seguridad. [15] Por lo tanto, para evitar ataques de doble codificación, todas las operaciones de decodificación de la entrada de usuario deben ocurrir antes de los esquemas de autorización y filtros de seguridad que interceptan la entrada de usuario. [16]
En el lenguaje de programación PHP, los elementos de datos en $_GET
y $_REQUEST
están suficientemente decodificados por URI y, por lo tanto, los programadores deben evitar llamar a la urldecode
función en ellos. [17] Llamar a la urldecode
función en datos que se han leído desde $_GET
o $_REQUEST
hace que los datos se decodifiquen por URI una vez más de lo debido y, por lo tanto, puede abrir la posibilidad de ataques de doble codificación de URI.
En el siguiente programa PHP, el valor de $_GET["file"]
se utiliza para construir la ruta del archivo que se enviará al usuario. Esto abre la posibilidad de ataques de recorrido de directorio que incorporan su carga útil en el parámetro HTTP GET file
. Como filtro de seguridad contra ataques de recorrido de directorio, este programa busca $_GET["file"]
secuencias de recorrido de directorio en el valor que lee y sale si encuentra una. Sin embargo, después de este filtro, el programa decodifica mediante URI los datos que ha leído de $_GET["file"]
, lo que lo hace vulnerable a ataques de doble codificación de URI.
<?php /* Tenga en cuenta que $_GET ya está decodificado por URI */ $path = $_GET [ "file" ];/* Filtro de seguridad */ /* Salir si la entrada del usuario contiene una secuencia de recorrido de directorio */ if ( strstr ( $path , "../" ) or strstr ( $path , ".. \\ " )) { exit ( "Se detectó un intento de recorrido de directorio." ); }/* Decodificar nuevamente la URI de la entrada del usuario */ $path = urldecode ( $path );/* Ruta del archivo de compilación que se enviará usando la entrada del usuario */ echo htmlentities ( file_get_contents ( "uploads/" . $path ));
Este filtro evita cargas útiles como ../../../../etc/passwd
y su forma codificada en URI %2E%2E%2F%2E%2E%2F%2E%2E%2F%2E%2E%2Fetc%2Fpasswd
. Sin embargo, %252E%252E%252F%252E%252E%252F%252E%252E%252F%252E%252E%252Fetc%252Fpasswd
, que es la forma de doble codificación URI de ../../../../etc/passwd
, omitirá este filtro. Cuando %252E%252E%252F%252E%252E%252F%252E%252E%252F%252E%252E%252Fetc%252Fpasswd
se utiliza una carga útil con doble codificación URI, el valor de $_GET["file"]
será %2E%2E%2F%2E%2E%2F%2E%2E%2F%2E%2E%2Fetc%2Fpasswd
que no contiene ninguna secuencia de recorrido de directorio y, por lo tanto, pasa por el filtro y se entregará a la urldecode
función que devuelve ../../../../etc/passwd
, lo que da como resultado un ataque exitoso.
En el siguiente programa PHP, el valor de $_GET["name"]
se utiliza para crear un mensaje que se mostrará al usuario. Esto abre la posibilidad de ataques XSS que incorporan su carga útil en el parámetro HTTP GET name
. Como filtro de seguridad contra ataques XSS, este programa desinfecta el valor que lee a $_GET["name"]
través de la htmlentities
función. Sin embargo, después de este filtro, el programa decodifica mediante URI los datos que ha leído $_GET["name"]
, lo que lo hace vulnerable a ataques de doble codificación de URI.
<?php /* Tenga en cuenta que $_GET ya está decodificado por URI */ $name = $_GET [ "name" ];/* Filtro de seguridad */ /* Sanitizar la entrada del usuario a través de htmlentity */ $name = htmlentities ( $name );/* Decodificar la URI de la entrada del usuario una vez más */ $name = urldecode ( $name );/* Crea un mensaje que se mostrará usando la entrada del usuario */ echo "Hola " . $name ;
Este filtro evita cargas útiles como <script>alert(1)</script>
y su forma codificada en URI %3Cscript%3Ealert%281%29%3C%2Fscript%3E
. Sin embargo, %253Cscript%253Ealert%25281%2529%253C%252Fscript%253E
, que es la forma de doble codificación en URI de <script>alert(1)</script>
, omitirá este filtro. Cuando %253Cscript%253Ealert%25281%2529%253C%252Fscript%253E
se utiliza una carga útil con doble codificación en URI, el valor de $_GET["name"]
será %3Cscript%3Ealert%281%29%3C%2Fscript%3E
que no contiene ningún carácter ilegal y, por lo tanto, pasa por la htmlentities
función sin ningún cambio y se entregará a la urldecode
función que devuelve <script>alert(1)</script>
, lo que da como resultado un ataque exitoso.