The simplistic scenario would be to try and send --><?php phpinfo();?><!--
. If the <?php
tag is escaped, then this would result in
<!-- -->
<?php phpinfo();
<!-- -->
(newlines added for clarity). But the presence of <?php ...?>
in the HTML page might not be enough; the PHP code needs to be interpreted server side, not just sent back to the client.
By examining more closely the beginning of the resulting string:
<!--?
it is clear that it is not the PHP tag, but the <
alone that triggers escaping, and this is probably intended as a HTML/XML/XSS defense. Which means you can't send active contents and have it executed, or rendered in client-executable form.
Again you might try with "pre-unescaping", by sending
< --><hr><!-- >
and seeing whether this gets transformed naively into
<!----><hr><!-- -->
which would be rendered as HTML, or is defanged more thoroughly into
<!-- -- --><!-- hr --><!-- !-- -->
which renders to nothing useful. This depends completely on how the HTML open tag detection is done, and how it operates. Sometimes preg_replace
is used with incorrect, incomplete, or not-greedy-enough regular expressions, which may defang only the first or last tag, or blindly defang the first opening with the last closing, ignoring whatever lies in the middle. If that is the case, then the page is vulnerable to Javascript injection and a variety of related attacks.
Is the sanitizing code available for inspection?
Example of naive validation
For example, this code apparently sanitizes HTML output.
preg_replace("/<(.*)>/", "<!-- \\1 -->", $input);
but (apart from being a badly thought out measure) the lack of the ungreedy operator ? leaves it vulnerable to a simple pre-unescaping attack:
<?php
$params = array(
"<script>alert('FAIL');</script>",
"< --><script>alert('Success');</script><!-- >",
);
foreach($params as $param)
print preg_replace("/<(.*)>/", "<!-- \\1 -->", $param) . "\n\n\n";
?>
results in the first naive attack to fail, while the second succeeds:
<!-- script>alert('FAIL');</script -->
<!-- --><script>alert('Success');</script><!-- -->
Unfortunately, this preg_replace
option is often suggested or implemented as a "quick fix" for HTML injection attacks, and as most "temporary fixes" are wont to do, it may become permanent.
A better strategy would be to filter out anything that doesn't belong in the original parameter (e.g. replace [^A-Za-z0-9_]
with nothing at all), or reason that the presence of forbidden characters means that something wicked this way comes, and therefore the safest reaction is to drop the request altogether (maybe informing the user, on the off-chance that it happened by accident or due to a problem - e.g. maybe a syntactically incorrect link - somewhere else; for which reason a logging of HTTP_REFERER
is highly recommended).
<?
tag, so I do not believe you will be able to execute PHP code.