Sanitize your input, by escaping HTML special characters. In PHP this is done with htmlspecialcharacters. Make sure you do not supply a flag that prevents htmlspecialcharacters from escaping the type of quote you use.
Your problem is your URL is http://example.com/?s=login&m=forgotten" onload=alert(966) bad="
, which your PHP code which is probably something like this:
<?php
$var = $_GET['m'];
echo '<a href="$var">something</a>';
but on straight simple substitution with the bad input becomes:
<a href="forgotten" onload=alert(966) bad=">something</a>';
The problem arises from the unescaped "
. The sanitizing PHP function htmlspecialcharacters
will change the "
to a "
so with:
<?php
$var = htmlspecialcharacters($_GET['m']);
echo '<a href="$var">something</a>';
the rendered HTML will be:
<a href="forgotten" onload=alert(966) bad="">something</a>';
which your browser will interpret as one giant link to forgotten" onload=alert(966) bad="
, instead of an html tag containing the onload
attribute.
Personally, I'd move away from PHP and to a web framework that starts with security in mind; e.g., automatically HTML escapes all input from database and query parameters in templates (unless specifically marked otherwise), does CSRF checks by default, use query parameters, etc.
javascript:alert(966)