To be clear, this is in the interest of ethical testing to secure an application on behalf of my work.

Now that that's out of the way, here are the details:

  1. Un-sanitised GET params are used in a PHP script to dynamically modify a HTML page.
  2. Only the param substring before a / is written to the HTML file

I am trying to have the code <?php phpinfo() ?> execute when the HTML page is rendered.

When I navigate to:

[host]/index.php/someparam=<?php phpinfo() ?>

The page source shows the code has been wrapped in a comment:

<!--?php phpinfo() ?-->

The code is only wrapped in a html comment when <? is detected, i.e. ?> on its own is fine.

Any ideas on defeating this? I've tried:


which still results in:

<!--?php phpinfo() ?-->

base64 just renders as is and isn't treated as code, decimal values are not present anywhere in the source (not even wrapped in a html comment).

  • It seems likely that it is explicitly filtering the <? tag, so I do not believe you will be able to execute PHP code.
    – Anorov
    May 28, 2013 at 5:46

2 Answers 2


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:

    $params = array(
            "< --><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).

  • it is not just the angle bracket. it is the combination of < and ? which triggers it. html tags are allowed, I was able to modify the styling of the page by inserting open comments and tags such as <em>. Sadly I can't show you the code as it seems to be a convenience feature in PHP not in the PHP script itself. Thank you for your help though :)
    – Très
    May 29, 2013 at 0:39

Looking at this, the only thing I can think of is an XSS attack. What you're trying will most likely fail, not because the site is filtering certain input, it's just the way this "functionality" is implemented. It is most likely something like this:

echo '<!--'.$_GET['someparam'].'-->';

Even without the <!-- -->, what the script is doing is taking your input, storing it in a variable, then printing back it to you, it's not being processed again by the PHP interpreter.

An exploitable situation would be eval($_GET);, but that's clearly not the case here.

  • I can't imagine a good use case for eval($_GET);
    – Skyl3r
    Jun 13, 2016 at 18:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .