¿Cuál es la forma correcta de escapar de los datos erróneos del enlace en javascript contra xss?

2

¿Cuál es la forma correcta de escapar de los datos erróneos la var " $actuallinkk " dentro de este script java

<a href="javascript:reportUser(\''.$actuallinkk.'&act=inviteadmin\')">Invite Consultant to this conversation</a>

Esto es lo que hice a continuación, no sé si es lo correcto para abordar el ataque xss.

function noHTML($input, $encoding = 'UTF-8')
{
    return htmlentities($input, ENT_QUOTES | ENT_HTML5, $encoding);
}




$actuallinkk = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";

 echo'<script>
function reportUser(repUrl) {
  if (confirm("Are you sure you want to invite Consultant to this chat?")) {
   document.location = repUrl;
  }
}
</script>

';
echo'
<li><a href="javascript:reportUser(\''.noHTML($actuallinkk).'&act=inviteadmin\')">Invite Consultant to this conversation</a>
</li><br/>';


if($_GET["act"]=='inviteadmin'){}

    
pregunta General Omosco 02.02.2017 - 17:17
fuente

4 respuestas

1

No, este no es el enfoque correcto y actualmente es vulnerable a XSS a través de esta carga útil:

http://example.com/yourscript.php/');alert('1

Ataque

Como se vio anteriormente, un ataque estaría configurando $actuallinkk para:

1');alert('1

Lo que resulta en:

<a href="javascript:reportUser('1&apos;&rpar;&semi;alert&lpar;&apos;1&act=inviteadmin')">

Ahora, esto parece guardar lo suficiente, pero no lo es. Como la entrada está dentro de un contexto de atributo HTML, el analizador de HTML lo examinará y eliminará la referencia a las entidades. Luego pasará el resultado al intérprete de JavaScript, momento en el que el código se verá así:

reportUser('123');alert('1&act=inviteadmin')

Esto se ejecutará, incluida la carga útil inyectada.

Defensa

El ejemplo anterior muestra por qué es importante tener en cuenta el contexto cuando se defiende contra XSS.

Dentro de un contexto de JavaScript, no desea codificar HTML, sino que debe escapar de todos los caracteres especiales con sus valores hexadecimales (consulte OWASP ).

    
respondido por el tim 03.02.2017 - 11:37
fuente
0

Esto es lo que quería hacer antes, pero el splash [a-zA-Z0-9.?=&_: ( / este mismo hace que no funcione) ] en el interior hace que prg_match no funcione. ¿Cómo puedo implementar el splash

$rawactuallink = "https://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";


if (preg_match("/^[a-zA-Z0-9.?=&_:/]*$/", $rawactuallink)) {
$actuallinkk = $rawactuallink;
}
else
{
$actuallinkk = "";
}
    
respondido por el General Omosco 03.02.2017 - 13:09
fuente
0

Esto es lo que finalmente hice

 $rawactuallink = "https://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";

if (preg_match("/^[a-zA-Z0-9.#?=&_:\/]*$/", $rawactuallink)) {
$actuallink = $rawactuallink;
}
else
{
$actuallink = "https://www..com/err";
}

Espero que tenga sentido utilizar este

    
respondido por el General Omosco 03.02.2017 - 16:09
fuente
0

Haz las cosas paso a paso:

Construyes tu enlace en PHP, por lo que haces $actuallinkk .'&act=inviteadmin'

Luego, colocas este enlace en un contexto javascript, por lo que json_encode it con 'javascript:reportUser(' . json_encode($actuallinkk .'&act=inviteadmin') . ')'

Luego, colocas esta cadena de Javascript en un contexto HTML, por lo tanto, htmlentities it con <a href="<?php echo htmlentities('javascript:reportUser(' . json_encode($actuallinkk .'&act=inviteadmin') . ')', ENT_HTML, 'utf-8'); ?>">Invite Consultant to this conversation</a>

Por último, no debes confiar en GET para hacer algo como "Invitar a alguien" (a menos que este enlace recupere la página para hacer la invitación). Hacer la invitación en sí debe hacerse por POST (por lo tanto, en un <form> ).

Tenga en cuenta que no debe confiar en REQUEST_URI como lo hizo, ya que puede que no contenga ninguna cadena de consulta (como https://duckduckgo.com , daría como resultado un enlace como https://duckduckgo.com&act=inviteadmin que incluso podría no resolverse como el correcto anfitrión). Probablemente sepa en qué página está, así que úselo directamente (como /mypath/mypage.php?myparam=myvalue ).

    
respondido por el Xenos 03.02.2017 - 18:33
fuente

Lea otras preguntas en las etiquetas