Detección de la configuración regional y gran encabezado Accept-Language, ¿se puede considerar una vulnerabilidad de ataque?

0

Estaba buscando algunos ejemplos de detección automática de locale, ya que necesitaba hacer lo mismo en mi aplicación PHP. La mayoría de las respuestas que encontré fueron similares, solo que diferían en los métodos de análisis. Un ejemplo 'pseudo-código':

$supportedLocales = ['en, 'bg', 'pl'];
$locale = 'en'; // default fallback locale

$userLangs = preg_split('/,|;/', $_SERVER["HTTP_ACCEPT_LANGUAGE"]);
foreach($userLangs as $lang)
{
    if(in_array($lang, $supportedLocales))
    {
        $locale = $lang;
        break;
    }        
}

Pero, después de un rato de experimentar con el encabezado Accept-Language en mi navegador para ver si todo funciona correctamente, noté que en realidad podía hacer el encabezado muy largo, haciendo que el servidor haga muchos bucles porque el código los bucles anteriores se distribuyen a través de toda la matriz $ supportedLocales para cada clave de la matriz $ userLangs. De hecho, podría enviar fácilmente un encabezado forjado en Accept-Language con más de 25000 idiomas falsos que no eran compatibles con la aplicación, generando más de 100000 iteraciones en total. Sin incluir las iteraciones utilizadas para comparar los valores de cadena.

Incluso aquí, en los sitios web de Stack, podría enviar más de unos miles de idiomas antes de recibir el error '400 Bad Request'. Si esto puede considerarse un ataque, ¿cómo se puede proteger su sitio web de tales encabezados falsificados? Sé que podría limitar la cantidad de idiomas, pero aún así, ¿qué cantidad puede considerarse normal?

    
pregunta hazelnutek 24.10.2018 - 14:55
fuente

2 respuestas

2

Parece que su situación es bastante única, ya que, según esta respuesta , la mayoría de los servidores web no le permiten enviar 25000 idiomas falsos, sino solo algo alrededor de 2500.

Dado su código no es óptimo y haberlo cambiado de esta manera

$supportedLocales = array_fill_keys($supportedLocales, 1);
foreach($userLangs as $lang)
{
    if(isset($supportedLocales[$lang]))
    {
        $locale = $lang;
        break;
    }        
}

lo mantendrá en 2500 iteraciones humildes.

    
respondido por el Your Common Sense 24.10.2018 - 15:34
fuente
4
  

Si esto puede considerarse un ataque, ¿cómo se puede proteger su sitio web de esos encabezados falsificados?

Forjar solicitudes que demoran mucho tiempo en procesarse en el servidor es una técnica común para un ataque de denegación de servicio (DOS). Esta es la razón por la que siempre desinfecta sus comentarios . No solo los valores POST y GET, sino también los encabezados si los usa.

Para el encabezado HTTP_ACCEPT_LANGUAGE , diría que nada más que unos 30 caracteres o 10 idiomas no sería un valor razonable para la mayoría de las aplicaciones. Así sanitse el encabezado. Puede limitar el número de resultados en preg_split o limitar la longitud del encabezado HTTP_ACCEPT_LANGUAGE

$userLangs = preg_split('/,|;/', $_SERVER["HTTP_ACCEPT_LANGUAGE"], 10);

or

$userLangs = preg_split('/,|;/', substr($_SERVER["HTTP_ACCEPT_LANGUAGE"], 0, 30))

editar: Se aceptó la respuesta del usuario 'Su sentido común', pero tenga en cuenta que la optimización de un bucle no es la forma correcta de protegerse de cualquier entrada falsificada. Solo está reduciendo el impacto, en lugar de resolver la fuente del problema.

    
respondido por el Securist 24.10.2018 - 15:58
fuente

Lea otras preguntas en las etiquetas