PHP Short Open Tag: Convenient Shortcut or Short Changing Security?
by Bill Brown on Monday, January 12, 2009 – 41 Responses
Most of us learned how to use “echo()” in one of our very first PHP tutorials. That was certainly the case for me. As a consequence, I never really had a need to visit PHP’s documentation page for echo(). On a recent visit to Perishable Press, I saw a Tumblr post from Jeff about the use of PHP’s shortcut syntax for echo() but somewhere deep in my memory, there lurked a warning about its use. I decided to investigate.
My first step in the investigation was to visit PHP’s documentation, where I learned:
echo()is a language construct, not a true function- if I pass
echo()more than one parameter, I cannot use parentheses echo()has a shortcut syntax (<?=$variable?>), but it requires that theshort_open_tagconfiguration is enabled
Recalling that I had once heard something about the insecurity of enabling the short_open_tag, I googled away. I saw a lot of opinions, but no real hard facts or examples showcasing any possible problems. It was time to experiment.
Using an Ubuntu Ibex box with PHP 5 on the Apache 2.2 server, I created a PHP document which contained only the following code:
<?
$username = "username";
$password = "password";
$message1 = "<p>This is my primary message.</p>\n";
$message2 = "<p>This is my secondary message.</p>\n";
$message3 = "<p>This is my tertiary message.</p>\n";
?>
<?=$message1?>
<?=$message2?>
<?=$message3?>
As you’d expect, I saw the following output in my browser:
<p>This is my primary message.</p>
<p>This is my secondary message.</p>
<p>This is my tertiary message.</p>
This seemed fine to me, so I decided to go into my php.ini file and disable short_open_tag and see what happened. On line 77, I found this ominous and foreboding harbinger of doom:
; Allow the <? tag. Otherwise, only <?php and <script> tags are recognized.
; NOTE: Using short tags should be avoided when developing applications or
; libraries that are meant for redistribution, or deployment on PHP
; servers which are not under your control, because short tags may not
; be supported on the target server. For portable, redistributable code,
; be sure not to use short tags.
short_open_tag = On
I guess it’s not really all that ominous but why wasn’t it in the PHP documentation? Anyway, a quick toggle…
short_open_tag = Off
…and back to the browser resulted in this unexpected output:
<?
$username = "username";
$password = "password";
$message1 = "<p>This is my primary message.</p>\n";
$message2 = "<p>This is my secondary message.</p>\n";
$message3 = "<p>This is my tertiary message.</p>\n";
?>
<?=$message1?>
<?=$message2?>
<?=$message3?>
All of my PHP code was silently output directly to the browser, completely ignored by PHP! No runs, no hits, no errors. “Not good,” I thought. So, I changed the code a little bit to ensure that PHP was still functioning properly. So now this code:
<?php
$username = "username";
$password = "password";
$message1 = "<p>This is my primary message.</p>\n";
$message2 = "<p>This is my secondary message.</p>\n";
$message3 = "<p>This is my tertiary message.</p>\n";
?>
<?=$message1?>
<?=$message2?>
<?=$message3?>
…resulted in this output:
<?=$message1?>
<?=$message2?>
<?=$message3?>
Obviously, this is a contrived example. Programmers don’t hardcode sensitive information like that. We ARE all keeping our MySQL connection scripts outside the web root anyway, right? Still, it doesn’t produce the results we want.
Modifying both code blocks to use the full syntax fixed this:
<?php
$username = "username";
$password = "password";
$message1 = "<p>This is my primary message.</p>\n";
$message2 = "<p>This is my secondary message.</p>\n";
$message3 = "<p>This is my tertiary message.</p>\n";
?>
<?php
echo $message1,
$message2,
$message3;
?>
…reliably and predictably resulting in this output (regardless of the short_open_tag configuration):
<p>This is my primary message.</p>
<p>This is my secondary message.</p>
<p>This is my tertiary message.</p>
To ensure short_open_tag was set to “off”, I also added this block to my central HTAccess file:
php_flag short_open_tag off
On my system, at least, I was able to use the HTAccess file to toggle this configuration. The short_open_tag configuration cannot be toggled using ini_set(), although you can test against it by using ini_get("short_open_tag").
Comma here, I wanna show you something…
Those of you with keen eyes may have also noticed my use of commas to separate instead of periods to concatenate my variables in that last echo(). I tend to use commas because once again, they produce more predictable and reliable results. Consider the following:
<?php
function echo_message () {
echo "I am a message.";
}
echo "<p>Message: ".echo_message()."</p>";
echo "<p>Message: ",echo_message(),"</p>";
?>
You’d probably expect the output to look like this:
<p>Message: I am a message.</p>
<p>Message: I am a message.</p>
…but what you actually get is this:
I am a message.
<p>Message: </p>
<p>Message: I am a message.</p>
This is a result of echo()’s special place as a language construct. When using concatenation, echo() must first evaluate the full, concatenated parameter before proceeding. When it does that, it triggers the echo() inside our echo_message() function which is immediately output to the browser before our first echo() has had a chance to complete its evaluation. Thus, we get the mixed up order of our output. In the second example, our first echo() evaluates and outputs each parameter individually. Since echo() itself actually returns NULL, from PHP’s point of view, our code looks more or less something like this:
<?php
echo_message();
echo "<p>Message: ".NULL."</p>";
echo "<p>Message: ";
echo echo_message(); # outputs "I am a message." and returns null
echo "</p>";
?>
To produce more predictable results, we could also do this:
<?php
function return_message () {
return "I am a message.";
}
echo "<p>Message: ".return_message()."</p>";
echo "<p>Message: ",return_message(),"</p>";
?>
…which will now produce exactly what we want:
<p>Message: I am a message.</p>
<p>Message: I am a message.</p>
Conclusion
The idea of an echo() shortcut is brilliant. It might be more useful had it been carried through so that <?php=$something?> would also result in output being echoed to the browser. In its current incarnation, I find it too unpredictable to be used in a production level application.
That’s my opinion, but the real question was: Are short open tags (and therefore the echo shortcut) security risks?
Anything that doesn’t produce predictable, reliable results can be problematic. Using short open tags when they are disabled produces no error or warning message of any kind. It simply fails, outputting your code directly and silently. In contrived examples, this can show devastating results. In real life, it’s more likely to be annoying than catastrophic. The most important thing is to be aware of it. Then, you can decide for yourself.
About the Author
Over the course of 33 years, Bill Brown has lived and worked in West Africa as a Field Station Coordinator on Bioko Island in Equatorial Guinea, represented the Memorex line of consumer electronics on QVC, owned a squirrel, taught improvisation and stage combat and launched two successful improv comedy troupes. Oh, and along the way, he’s developed some websites and applications.
Self-taught with a penchant for entertaining others, Bill’s clients have included internationally renowned photographer Steve McCurry, The National Maritime Law Enforcement Academy (whose site was deleveoped entirely in the rain forests of Bioko Island), Virtual Giving, Workforce Strategy Center and the WSC web application Pathways to Competitiveness. Bill was also a presenter at the 2008 National Association of Government Webmasters conference in Chicago, IL.
Bill owns and run WebDevelopedia.com and is an active member of several mailing lists, including the CSS Discussion List. When not online, Bill can be found enjoying the company of his girlfriend, Jessica and their dog, Leica (she doesn’t have a web site).
Focused on clean code and quality content, Perishable Press is the online home of Jeff Starr, author, artist, designer, developer, and all-around swell guy.






41 Responses
Add a comment
Louis – #1
Great post Mr. Brown, I really appreciated the reading! It’s interesting to finally see someone that take the time to verify that the tools he uses are the good ones. The examples are very clear too, thank you.
By the way, this reinforces my desire to learn Ruby/Python and say goodbye to PHP.
Bill Brown – #2
Louis,
Thank you kindly for your complimentary response.
I’m not yet skilled in Ruby/Python (it’s on the list), but every language has the potential for security gaps. It’s really up to the developer to understand the tools provided to us by any language and ensure that we’re not using them in a way that sacrifices too much security.
One assumes that every language has the potential to be insecure, depending on how it’s applied.
In any event, thank you again for your kind words. Stay well. –Bill
John – #3
Hm - this is an interesting post. The thing that makes me wonder is exactly why PHP includes some support for shorthand code other than the “convenience” of use? I prefer to stick to one way of coding (using the full <?php tags and echo statements), and allowing lenience for PHP developers such as myself presents all sorts of problems, mainly the one you mentioned.
Nonetheless, this was a very imformative article.
Jeff Starr – #4
Thanks to everyone who commented on Bill’s premier guest post. I also enjoyed the article immensely and am looking forward to seeing more of his articles posted here at Perishable Press. If all goes according to plan, we’ll be reading much more from Bill in the future. Stay tuned!
Antoine Leclair – #5
Short tags really shine when you completely separate logic from presentation (like we do when we use the MVC design pattern).
Here’s a short example:
<?php// Business logic here$my_array = function_that_fills_the_array();?><h1>The page title</h1><ul><?php foreach ($my_array as $element) : ?><li><?= $element ?></li><?php endforeach ?></ul>The way you used it in your post was not really useful. I mean, the point of using short tags is to make it more readable when you embed PHP variables into HTML. I don’t think it’s a good idea to add HTML in PHP variables.
Bill Brown – #6
Re: Antoine
“Short tags really shine when you completely separate logic from presentation (like we do when we use the MVC design pattern)”
Unless they’re disabled, in which case, they don’t do anything,, except pose a potential security risk, regardless of whether you’re using the Model-View-Controller (MVC) design pattern or not.
“The way you used it in your post was not really useful.”
Sorry about that. I don’t see much of a difference between my examples and yours save the lack of any HTML in your example.
“I mean, the point of using short tags is to make it more readable when you embed PHP variables into HTML.”
I don’t think it makes it more readable at all. I find the inconsistency awfully unattractive.
“I don’t think it’s a good idea to add HTML in PHP variables.”
I imagine I must be misreading this sentence. Otherwise, I have to assume that you’re telling me you never store ANY HTML in your databases, which seems terribly unlikely, or a terribly large and unoptimized database.
Antoine Leclair – #7
@Bill
For a designer (that mainly touches HTML, not PHP), I think
<li><?php echo $variable ?></li>is less readable than
<li><?= $variable ?></li>But I think it’s a matter of opinion.
Regarding HTML in PHP variables, I was thinking of short texts.
What I usually do is:
If I output code that contains the necessary HTML, I use
<?php echo $variable; ?>If I output code that does not (like in my previous example), I use
<?= $variable ?>Again, unless I have to embed HTML in variables, I try to avoid it. In, let’s say, a blog post, or product description, I am not ashamed to embed HTML. But if formating is not necessary, I avoid it.
Louis – #8
Awesome!
Bill Brown – #9
@Antoine
The fact that you’ve made the choice to use the short tags is what separates you from the developer who uses it blindly. I applaud you for having made an educated decision, even if it’s one I disagree with.
I suppose the real purpose of an article such as this is to foster knowledge as well as intelligent discourse. It seems we’ve succeeded. ;-)
Incidentally…je parle seulement un peu de Francais, mais votre site internet est tres beau. Le bon travail!
Antoine Leclair – #10
@Bill
I think we both agree on that ;).
Thanks for the little French sentence. We feel so lonely on the web, us, non-English people, hehe. Your site is pretty cool too. I like fixed background with transparent content ;).
Bill Brown – #11
@Antoine
Bien sur et de rien, mon ami.
My sites are woefully underdeveloped and underdesigned. I’ve been all too busy with client work, which is good for the bank account, but bad for the personal sites.
Cheers!
Langel – #12
I use a custom templating system. Instead of typing <?php echo I simply type <: and the closing tag stays the same. The parser converts the tags for me before they are rendered in an eval(). I also use <; for plain old <?php and <o for and it makes me happy. =D/
Bill Brown – #13
@Langel
I would say to you the same thing I said to Antoine: The best thing is that you’re aware of the issues and have made an informed decision about what works best for you.
That’s all I can hope for from an article such as this. I’m no security expert and I taught myself to code, so I imagine I’m plagued with habits which would appall others, while my own need for absolute control of my applications creates for me a certain distaste for some popular PHP coding practices, the use of PHP’s short tags among them.
Justen – #14
Thanks for the heads up! I just (re)discovered this shortcut recently. I’m glad I read this article before I started using it too heavily (as it is really handy).
PS – #15
The problem you describe here isn’t so much a problem with PHP short tags…the problem is running things in an unknown environment.
For example, if the PHP module isn’t loaded or if Apache’s AddType directive hasn’t been issued for “.php” files, raw PHP will be sent to the browser, even if you’re using the full “<?php”-style tags.
The lesson here is to be aware of what server configurations your coding depends on, and to ensure that any server intended for production use is configured accordingly and will run your code properly before bringing it online.
Thomas – #16
PS hit the nail on the head IMO. Some people go on like short open tags are devil spawn.
Steve – #17
This was a great short article to read on the subject. I’ve been aware of short tags for a while and my inclination is to use them as Antoine suggests (separating logic from presentation). I agree completely that it’s one of those decisions an informed developer can and should make for themselves, and I feel more informed to make that decision as a developer thanks to your article and the comments.
Silver Knight – #18
I totally agree with the mindset that usage of the short open tags should be an informed decision, made with full knowledge of the benefits and drawbacks and security issues involved. One detail I did not see mentioned here (and one of the reasons I see frequently quoted as an argument against short open tags) is that there is supposedly an issue involving XML open tags in certain instances? (I myself have never personally dealt with any such issue, but I tend to stick to the full PHP tags just for safety and compatibility anyhow.)
That having been said, I can totally see how the construct could be entirely too convenient (and readable) to ignore for some developers/designers, but if you should choose to use such conveniences, my advice is similar to that in other comments here and elsewhere on the web. Do not use such features without well researched knowledge. Don’t just code willy-nilly, assuming that it will work as expected without fully considering the implications of the choices you make.
Thank you very much to the author, Bill Brown, for adding an informative and helpful tidbit on the web regarding this important topic of web application security. It is a topic which should be at the forefront of every web application developer’s mind while coding their latest and greatest shiny new Web-five-point-oh buzz-word application. ;)
Bill Brown – #19
The issue with PHP’s short tags and XML is that PHP will attempt to parse anything which begins with “
<?”. This means that XML, which begins with<?xmlis sent to the PHP engine, generating errors since it is not PHP (obviously).To work around this issue while using short tags, you can do this:
<?="<?xml version='1.0' encoding='UTF-8'?>\n";?>or this:
<?php echo "<?xml version='1.0' encoding='UTF-8'?>;\n";?>Of course, if you are using PHP’s short open tag, you might also want to include a check in the beginning of your scripts to save yourself any headache in the future. Something like this ought to do the trick:
<?php if(!ini_get('short_open_tag'))die("Short open tag disabled!"); ?>…or to ensure it is always disabled:
<?php if(!!ini_get('short_open_tag'))die("Short open tag enabled!"); ?>Gabe – #20
Short open tags is such a headache when it comes to unknown environments. I’ve had numerous cases of debugging sites and find that it had to do with short open tags. Either <?xml being mangled because it was enabled, or php not executing code within short open tags when it wasn’t enabled. It can be one of those problems that gets hard to track - especially in xml.
If your php code will generate XML, or you want your PHP code to be redistributable then do not use short open tags.
If you do not use it, you don’t have to worry about the setting. It makes no difference.
Corey – #21
I’ve never run across any problems with short open tags. But after reading your detailed article on the downfalls of it, I will go back to writing echo the long way.
Thanks for this great article!
Bernhard H. – #22
I stopped using the short tags when I first uploaded a little something and nothing worked because they were disabled. When I read about the echo shortcut I thought yes why not, but then I remembered changing hundreds of short tags and the idea was smashed.
And I can only endorse what Gabe said: Whenever you’re using XHTML templates or do something with AJAX (the real AJAX with XML) or do some advanced XML stuff with Processing Instructions (and not using the DOM lib), you have to decide: Shortcut echo or echo all those <?.
Mahbub – #23
I had used short tags earlier. One website i had to change around 470 instances and lot of them were manual. All that was the server didn’t support short tags. After that i never use short tags. And i advise everyone not to use it in production servers.
bucabay – #24
In case you’re still trying to manually edit short open tags in PHP to the long form, I’d suggest using a search and replace.
You can even write the script in PHP. eg:
scandir()to get all files and directories,file_get_contents()to read the file, andstr_replace()orpreg_replace()to do your adjustments.It really helps to have a few of these scripts put together so repetitive tasks aren’t done manually. There really is no need to change every instance of
<?into<?phpmanually.kanwaljit singh – #25
I totally agree with bill, as we know that support for short tags might be discontinued in future(at least its not going to be set to on for default), its better to avoid it if u dont have access to your php.ini or if you want to make portable scripts for distribution or selling.
For that reason I always turn off short tags option on my development PC’s Php.ini.
Really nice and detailed article :-)
asad – #26
hi how r u …i have the problem with php .. the page is not display the data but it display the header and footer
i am totally confused what is the problem .. the code is working on other machine but not working on my machine. i installed wamp server which is working.
Rex – #27
i have a problem in PHP. i installed my project in a linux OS. then when i click one of the menu on my project, a window will pop up asking me if i want to open the *.php..Is there any concern with the rights?
Marcos – #28
“All of my PHP code was silently output directly to the browser, completely ignored by PHP! No runs, no hits, no errors.”
Perhaps you forgot to restart Apache after changing php.ini?
Regards,
Marcos.
Abeon – #29
Well, I’ll be…..
You learn something new every day!
I’m a code minimilist so this will be usefull for me, thanks :)
Jakub Lédl – #30
Sorry, sir, but few of your programming techniques really made me wonder what kind of programmer are you.
WTF is supposed to be this:
function echo_message() {echo "Message."}echo "blah", echo_message(), "blah"This has nothing to do with echo beign a language construct, this is just stupid! I mean,
if ... elseif ... elseis also an language construct, and still you would writefunction create_cond() {return true;}if (create_cond()) {...}and not
function create_cond() {echo true;}so that the value is returned, not echoed (if you won’t, then you totally don’t grasp basic concepts of programming. How do you ever wanna do OOP?)!
And also, I found quite interesting this:
if (!!ini_get("short_open_tags")) {why not just
if (ini_get("short_open_tags")) {???
Bill Brown – #31
@Jakub
The examples in this article are contrived as an attempt to isolate the behaviors of the echo language construct.
I fear you’ve missed the point of the article but am happy to answer any of your questions directly, including any related to OOP, as I code solely using object oriented programming techniques.
Thanks for your feedback and sorry the information wasn’t more clear to you.
Dave Coleman – #32
It seems to me the short tags security problem was completely artificially created by the PHP Development Team by making the setting optional. Had they made short tags always on by default when this issue began years ago, there wouldn’t be any of these ‘security’ issues.
And the xml tag opener issue is just one single line of code at the top of xml files that can easily be worked around with about 6 characters of code ONCE, instead of adding 7 characters of code every time you want to output a variable, in particular “
<?php echo” instead of “<?=”.Jakub Lédl – #33
My apologies, I misunderstood the point of this article.
As for the problem with xml declaration, nicest solution I’ve seen so far is this:
<?xml version="1.0" encoding="utf-8" ?>Tomás – #34
Thanks for the tip.
Jakub Lédl – #35
Oh sh*t, I came back. What happened to that code I posted? Does this CMS remove PHP from comments or what? I now look like an idiot :-)
This is what I meant:
http://www.sourcepod.com/idhblx03-2718
Edit:
<<?php ?>?xml version="1.0" encoding="utf-8"?>bucabay – #36
AT Jakub
<?xmlsuch as that on http://www.sourcepod.com/idhblx03-2718Why is it nice? Is it an OOP solution? Just kidding.
Bill Brown – #37
@Jakub:
Of course, there are many ways to bypass the XML declaration issue when you have PHP short tags enabled. Since the intention of the fix you posted is to fix the problem when short tags are enabled, you could probably shorten your hack by leaving the PHP off altogether.
I haven’t tested, but in theory, any of these should work:
<<??>?xml version="1.0" encoding="utf-8"?>
<<?/*XML*/?>?xml version="1.0" encoding="utf-8"?>
<<?php?>?xml version="1.0" encoding="utf-8"?>
<<?php/*XML*/?>?xml version="1.0" encoding="utf-8"?>
Trackbacks / Pingbacks