Content Management Systems always end up suffering, at least a little, from the Inner Platform Effect. There’s the additional problem that, unlike say, a big ol’ enterprise HR system or similar, CMSes are useful for just about everyone. It’s a quick and easy way to put together a site which anyone can maintain. But it never has enough features for your content. So you always install plugins- plugins of wildly varying quality and compatibility.

Lucio Crusca was doing a security audit of a Joomla site, found this block inside an installed plugin:

<?php if(!empty($MyForm->formrow->scriptcode)){
                echo "<script type='text/javascript'>\n";
                echo "//<![CDATA[\n";
                eval("?>".$MyForm->formrow->scriptcode);
                echo "//]]>\n";
                echo "</script>\n";
        }
        ?>

Let’s just focus on the echos to start. We’re directly outputting a <script> tag into the body of the page, and doing the bonus CDATA wrapper, ensuring compatibility with XHTML, which is nice if if your code ever slips into the mirror universe where people thought mashing up HTML’s formatting and XML’s formality into a single document standard was a good idea.

But that, of course, is not the WTF. The WTF is the body of the script, which is output into the document via this line:

eval("?>".$MyForm->formrow->scriptcode);

$MyForm is submitted from a client-side form. It, ostensibly, contains some executable PHP code, which outputs some JavaScript into the body of the document. eval, of course, just executes that code. Blindly. Hoping for the best. With full access to the current executable scope.

Now, there’s one important thing to note about PHP’s eval compared to other languages. Note the opening ?>. The eval block implicitly assumes an opening <?php tag, which you can exit with a ?>. This lets you, in your eval, mix straight PHP and HTML content together:

eval("if (foo) { ?> <p>This is just pure HTML</p> <?php }");

So you see, the developer responsible for this was being “smart”. They knew just enough to understand how to use eval to inject HTML content, and just went on to assume that no one would ever think about tossing a <?php in there to get back into a server-side execution context.

In any case, something about the phrasing of the PHP docs on eval makes me chuckle:

Caution The eval() language construct is very dangerous because it allows execution of arbitrary PHP code. Its use thus is discouraged. If you have carefully verified that there is no other option than to use this construct, pay special attention not to pass any user provided data into it without properly validating it beforehand.

“Its use thus is discouraged” should be the new “considered harmful”.

[Advertisement] ProGet can centralize your organization's software applications and components to provide uniform access to developers and servers. Check it out!