Estoy publicando una nueva respuesta porque encuentro que la respuesta de zneak no tiene suficientes ejemplos, no muestra el manejo de HTML y URI como diferentes aspectos y estándares y faltan algunas cosas menores.
Tiene dos estándares con respecto a las URL en los enlaces ( <a href
).
El primer estándar es RFC 1866 (HTML 2.0) donde en "3.2.1. Caracteres de datos" puede leer los caracteres que deben escaparse cuando se usan como valor para un atributo HTML. (Los atributos en sí mismos no permiten caracteres especiales, por ejemplo, <a hr&ef="http://...
no está permitido ni lo está <a hr&ef="http://...
).
Más tarde, esto se ha incorporado al estándar HTML 4 , los caracteres que necesita para escapar son:
< to <
> to >
& to &
" to "e;
' to '
El otro estándar es RFC 3986 "Estándar genérico de URI", donde se manejan las URL (esto sucede cuando el navegador está a punto de seguir un enlace porque el usuario hizo clic en el elemento HTML).
reserved = gen-delims / sub-delims
gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
Es importante escapar de esos caracteres para que el cliente sepa si representan datos o un delimitador.
Ejemplo sin escapes:
https://example.com/?user=test&password&te&st&goto=https://google.com
Ejemplo, URL totalmente legítima
https://example.com/?user=test&password&te%26st&goto=https%3A%2F%2Fgoogle.com
Ejemplo de URL totalmente legítima en el valor del atributo HTML:
https://example.com/?user=test&password&te%26st&goto=https%3A%2F%2Fgoogle.com
También escenarios importantes:
Javascript como valor:
<img src="..." onclick="window.location.href = "https://example.com/?user=test&password&te%26st&goto=https%3A%2F%2Fgoogle.com";">...</a>
(Sí, ;;
es correcto)
JSON como valor:
<a href="..." data-analytics="{"event": "click"}">...</a>
Cosas escapadas dentro de cosas escapadas, doble codificación, URL dentro de URL dentro de parámetro, etc., ...
http://x.com/?passwordUrl=http%3A%2F%2Fy.com%2F%3Fuser%3Dtest&password=""123