Category: PHP

  • PHP 5.2 to get HttpOnly!

    Ilia has just blogged that HttpOnly is now supported in PHP 5.2.

    This prevents the usual sort of basic XSS attacks, like:

    Supported browsers:

    • IE 6.0 SP1 and later – prevents reading, but not over-writing (still allows preset CSRF attacks)
    • IE 7.0 – prevents reading and writing – safest
    • Safari 1.3 – not support (update)
    • Opera 8 and later – not supported (update)
    • Mozilla – not supported
    • Firefox – not supported
    • IE 5.x for Mac – will actually fail to render the page. Use browser detection to encourage them to migrate to Safari or Firefox once it supports HttpOnly

    There is a potential solution for Firefox’s and Mozilla’s lack of support.

    Now all we need is for Firefox, Mozilla, Safari (=WebKit), and Opera to climb aboard!

    Update: Chris and I spent some time working out if HttpOnly works on a range of browsers. Sadly, some browsers I thought had support… don’t. Oh well.

  • OSCON

    Work: I owe my boss a huge beer (and a document) and an apology when I get back to Australia.

    Personal life: in the dog house. I got very little sleep these last few days, and I bet my other half is feeling far worse than me. Hopefully, she can come to Vegas so we can sort things out.

    OSCON: Awesome.

    My presentations went down well. I’ll upload the new presentations soon, but the Ajax Security demo went off really well. The room was overflowing with folks, so I’m really chuffed that so many of you decided to come.

    I’ll put up the Ajax XSS demo I did later, but please be aware that these demos are INSECURE by design, and only to test them on your internal systems. The trick is to:

    <img src="kitty.jpg" onLoad="... your javascript attack here ...">
    

    People forget there’s literally hundreds and possibly millions of ways to do XSS. Do NOT look for script or Javascript and think you’re done. That’s stupid. Make the output safe, it’s faster, it’s simpler, and it works.

    People

    I met so many folks who I had spoken to over the net, or e-mailed. Everyone is so nice and friendly, it’s incredible to meet the greats. I really enjoyed catching up with Chris and Laura, met the Schlossnagles for the first time (cool dudes, cute kids :), and of course, Wez.

    Unfortunately, due to the bad things going on in my personal life, I could not bring myself to hang out after hours as I was feeling extremely down, but life goes on. I was hoping to go out to Portland a bit more; maybe next time.

    Talks

    I went to a fair few webappsec related talks, and it’s truly gratifying to me that the developers had an entire stream dedicated to it. I really enjoyed the PHP Security hoe down – we had a wack job in the back row causing a bit of a stir, but after he left, the hour really flew.

    Portland

    I’ve never been here before. It’s a very nice city, great public transport. I’ll post some images soon as it’s very pretty this time of the year. It was a bit hot when I got here (about 40C) but it soon cooled down to mid 20’s and I’ve been happy with that. 🙂

    A friend through newbeetle.org picked me up from the airport last Sunday, and we went to her place and hung out for a while. She invited over a friend of hers, and I got to see her and her hubbie’s New Beetles (a nice Turbo S and a unired NBC), and her friend’s green Gecko TDI New Beetle. Very nice – I wish we could get that color in Australia. We had breakfast on Friday morning even though I was extremely tired (no sleep) and a bit sad, and she picked me up this morning to take me to the airport. I’m so impressed, I wish I could say I was as good a host when I have folks visiting. Thanks, Debbie – you set the standard!

    Next steps

    I’m off to SF next. I’m at the airport now. I have to spend a few hours this weekend getting stuff together to meet the CSO of a major partner of work’s, like running through the ESA presentations and ensuring that we have something constructive to talk about. I might need to go to Kinkos tomorrow and print off a few things unless my hotel has a printer I can use.

  • A quickie

    Here’s a single slide from the PHP security architecture slide deck. When I’ve sorted myself out in terms of demos for OSCON, I will release the entire thing when it’s in better shape (and smaller for the web – this Keynote theme seems particularly heavy).

    Slide 9 (1.2 MB, pdf)

  • PHP Security Architecture

    [ EDIT: a comment I wrote in this entry referred to Laura Thomson as one of the reviewers of the OWASP Top 5 article. Although I have discussed other PHP related things with Laura, this article is not one of them. I’ve carefully reviewed my Sent folder during this time, and I’ve updated the reviewers in the article on the OWASP website. I apologize to Laura for bringing her into this sordid affair. ]

    I have a comprehensive PHP security architecture for PHP 6 I’ve been developing, which I wanted to present to Chris for his comment, and if he felt it was good, possibly then ask Rasmus and Andi for a beer or two whilst I am at OSCON.

    However, I’ve just had a very disturbing e-mail conversation with Stefan Esser, PHP security researcher, founder of Hardened PHP, and one of the initiators of security@php.net. He posted from his php.net address, so I imagine he was talking to us (as in OWASP) in his PHP security bod at large capacity, but I’m not sure.

    I’m now basically convinced that there is just no point trying to make PHP safe. The people involved are too poisonous and arrogant to change, therefore PHP will not change and become safe. My architecture would be attacked viciously but nothing would be done to put something like it in place. And without a decent architecture (mine or someone else’s), PHP is no safer than it is today, which is to say – not safe at all unless you know what you’re doing and can control php.ini, something most shared host users do not have the luxury.

    The best bet for PHP is to kill it by letting the current development team make PHP 6.0 into even more of a niche that PHP 5.x is, and ensure that hosters become more and more locked into the insecure PHP 4.x. When the hosters get sick of rebuilding their virtual hosts all the time, it will become uneconomical to allow PHP to be on their hosts. They will take it off, and ask people to move to safer languages / frameworks.

    It’s time for PHP to die.

    Update… I’m not going to re-write history, so I’ve left the above text for you to see.

    However, it’s not fair to the PHP community that we security folks argue amongst ourselves whilst their apps continue to fall victim to the same attacks, time after time. I will spend more time on the architecture and create a BoF at the conference to present it after spreading it around my coterie of PHP friends for advice and comment. I’d love to have everyone who has been so passionate about this article come see us at OSCON and see what I have in mind.

  • OSCON 2006 – See you there!

    Just a quick note as to the quietness of the blog. I’m working on a few things:

    • my slides for OSCON (webappsec 150 tutorial, and updating my Ajax presentation to include the latest research and make it a bit more (ahem) controversial to liven things up)
    • doing demos for the above
    • my slides for OWASP Melbourne, July 2006 meeting (this coming Wednesday! Details)
    • reconstructing my work laptop
    • the OWASP membership packs and other executive director project items
    • administrating Aussieveedubbers
    • writing a fresh Ajaxy UltimaBB installer
    • writing a proposal for a workable security architecture for PHP 6 which I want to present to Chris when I go to OSCON, and maybe earn myself an audience with Rasmus and the other PHP luminaries to discuss it over a beer or two and thus decrease my trolliness to those folks.

    and plus Tanya would like my body sometime as well. I’ve given up TV. Woe is me!

    See you at OSCON 2006.

    I’m also making an appearance at BlackHat and Defcon, and will be in SF in between those two conferences, and possibly in Salt Lake City before OSCON (depends on work). If you want a Thawte Notarization for the Web of Trust (free *real* fully trusted S/MIME certificates!), please bring photocopies of your photo ID and I’ll do it for free.

  • Ajax Security Presentation up

    Here’s the quick and dirty preview of the new Ajax chapter of the Guide 2.1. It’s also some of the first real guidance anywhere on Ajax security – period. It was interesting to find so many apps adopting Ajax, but so little information on how to secure it.

    If anyone wants to proof the new chapter, please join the OWASP Guide development.

  • PHP Security Architecture: SABSA approach

    There are only a few acknowledged industry security architectures. SABSA (best documented in Enterprise Security Architecture by Sherwood, Clark and Lynas) is probably the best known.

    The various artifacts from this architecture include:

    Enterprise security layers

    SABSA Security Architecture

    Each of these layers needs to be thought about in a considered way:

    (Business) Drivers

    Why do you want X / How will it be used / Who will use it / Where should it be located / When will it be used?

    Answering these questions will help understand if something already exists (with PHP most likely), and understand the communities we need to talk to to understand their needs and desires.

    Then a risk assessment can be carried out to determine the relative risks of each area, and understand likely vulnerabilities based upon existing exploits.

    Occasionally, this process will pick up areas where there are missing areas of functionality in PHP. This then ends up on the roadmap for later versions.

    Conceptual Layer

    Training and awareness – DR / BCP – audit and review – authorization – administration – incidents – standards, etc

    Often these areas are well covered. The trick is to bring them under the one roof and ensure we’re all driving in the same direction. Some of the issues in a standard security architecture simply don’t apply to a language, which is cool as it means less work.

    Logical Layer

    Policy – classification – security services management – interop standards (WS Security et al) – audit trail, etc

    This is usually left to the programs written in PHP, but PHP needs to provide these services. The OWASP Guide provides a great deal of best practices, so the main activity here is to determine if the standard PHP frameworks contain adequate API in each area. For example, PHP is sadly lacking a secure audit class.

    Physical layer

    For PHP, this is mostly about configuration, but also the rawest possible implementation of the security trumvirate: confidentiality, integrity, availability. Again, PHP may need to grow to allow all of the areas here:

    certificate mangament

    Component layer

    A major win for security architectures in the last few years is the move away from crunchy on the outside, soft on the inside “edge” hardening towards trust boundaries. Identifying data flows from trusted components to other less trusted components is key to understanding the security risk.

    Therefore, this can be used to identify those API which normally perform this transition on behalf of programs, such as echo/printf/ IO in general, and so on. Each of these major trust boundaries needs to be investigated to ensure that there is a safe way to make the transition, whilst a raw / unsafe way remains for those few programs that need the raw / unsafe way.

    Conclusion for now…

    Well, that about wraps up this explanation. In the next installment, I’ll start enumerating the current risks and identifying business drivers. This is an important first step to creating a security architecture which will be robust.

  • PHP Security Architecture – Contextual Overview

    Overview

    The problem with PHP is that it has no security architecture. What do I mean by security architecture? A single pervasive vision for security, which will last for approximately five years with little or no design maintenance. A robust security architecture creates a balance between functionality and risk, and ensures that by default, simple activities and normal features create as little risk as possible.

    There is no point in a “safe” mode which prohibits most scripts of any consequence. For example, safe mode prevents most gallery applications from running. This wouldn’t be a bad thing if you’re a gallery hating hoster who wanted to prevent such apps from running, but this is not the case 99 times out of a 100. What is worse though, is that safe mode is trivially worked around if you want to completely 0wn the host using an attack script, but hard to work around if all you want to do is save some images to disk. The new security architecture must make balanced choices which allow apps to do their stuff, but not allow attack scripts to do their stuff.

    PHP has had several disjunct goes at implementing “security” features, but unfortunately, failed to implement them correctly. All these efforts requires modern safer programs to include code which tests if these options are enabled, and if so, to then undo their handiwork. Often such code is buggy and slow. For example, many hosters (incorrectly) have register globals enabled as many customer scripts “need” them. However, safer PHP scripts do not need register globals as they follow the usual OWASP model of validate! validate! validate! from the correct source ($_GET, $_POST, etc). So they have to undo the registered globals, requiring even more work and slowing each and every script down. If they get it wrong (and often they do; some programs actually look to see if register globals if off and put the old bad behavior back!) All this is wasted work.

    One of the key findings of the major sources of PHP vulnerability relate to many distinct configuration flavors. Hosters often run insecurely to maximize compatibility, and with “register globals”/”magic quotes” and “safe mode”, apps have at least 8 common combos which may or may not work for them. This makes testing significant PHP apps basically impossible. The new security architecture must provide a single correct configuration which programs can rely on, so there is no reason to enable these unsafe features. This also means that it is easy for auditors and reviewers to find code which relies on unsafe features, and even easier to find code which relies on the new security architecture so they can concentrate on the really dodgy stuff – bad design and silly processes.

    The pervasive security architecture explicitly reduces attack surface area of any PHP 6.0 script to manageable levels, and controls all security features in a cohesive and orthagonal way. A key goal is to ensure that existing scripts will not need to be modified (but also do not benefit … unless it is easy and safe to do so), but new applications which are aware of PHP 6.0 will automatically get the safest programming experience.

    Of course, it is possible to write insecure programs in any language if you try hard enough. What I want is the easiest way is also the safest way.

    Security Architecture Objectives

    The major objectives for the PHP Security Architecture are:

    • By default, the new architecture uses a low attack surface area approach, disabling any features which have a security outcome
    • The easiest way to do something, is also the safest way
    • If we can provide security without coding, then that will happen (think freebie XSS protection)
    • Backward compatibility is not broken, but hosters and admins are free to enable this mode (yes, by default unless you ask for the new architecture, the old scripts will not run)
    • Unsafe constructs and patterns, like mysql_query() which cannot be made safe at any price, do not run in the new architecture. At all.
    • Safe constructs, like PDO are unchanged and require no porting
    • The basic architecture pattern is “deny unless permitted” as it applies to operating system and network resources
    • Never introduce another broken security idea into the new security architecture. ie, no more “register globals” or “magic quotes”. Either the new feature is the lowest risk way of achieving an outcome, or it is not introduced. This will require significant peer review.

    Compliant scripts invoke the new security architecture, but once invoked the entire script must be compatible with the new architecture. The new security architecture has to be wholistic and apply to all functions. But as this is a lot of work, the initial effort has to be to secure the securable, and remove access to the unsecurable.
    Bad security patterns in need of solving

    There is no point in fixing broken API, so I will not delve into straight security “fixes” for existing PHP applications. However, I have reviewed the top five PHP related issues and worked out their root causes.
    The five things are:

    • File inclusion attacks, usually resulting in remote command injection
    • Remote command injection
    • Validation failures, particularly XSS attacks
    • File system attacks
    • and lastly, configuration related attacks which makes the attack so much worse

    Creating secure patterns and fixing APIs which remove these issues permanently will advise the security architecture’s overall look and feel, and it will help us create “safer” PHP-like constructs. There is no point in producing Java-like or .NET like constructs on top of PHP – PHP developers use PHP for a reason: it’s a pretty simple language to pick up and fast to make things happen.That is not to say that there will be no J2EE or .NET influences, particularly if one of those does something very well, and PHP currently does not have an equivalent API. For example, if we need a new API for feature X already present in another platform, then there is little reason to create an API with tiny detail differences. All that means is that programmers moving from other platforms to PHP need to learn the PHP nuances, but the more likely instance is that they will get it wrong and there will be subtle bugs. A typical example is that in .NET, structured exception handling is pervasive, whereas in PHP, we use PHP’s loose typing to return bools, occasionally -1, occasionally throw an exception and sometimes a string. We should be careful about return results like this, particularly if we pick up an API wholesale from somewhere else.

    Sandbox

    The sandbox as it stands in the runkit is insufficient. What we need is isolation so that each application has a level of isolation from the underlying environment, and other applications. Hosters often run hundreds of users on each host and many applications may exist in each account, such as a CMS, blog and gallery … just as I do here. All are in PHP. The apps can see and change each other’s resources like config and temporary files, which is not an ideal situation.
    Obviously, some apps require less isolation than others, and some require tight integration (a CMS and an integrated forum software for example), so a model must exist which allows such integration without opening up an entire full trust model as today.

    Bringing old features into the fold

    There is no point in creating a massive new API just for security architecture, but there needs to be a way to identify those areas which are affected. Luckily, a great deal of the API is already in PHP, so it’s “just” a matter of securing the boundary in the core between PHP applications and the underlying operating system.

    However there are gaps in PHP requiring new API and ideas to allow basic security activities

    • The idea of an intrinsic authorization model which code can rely upon to be there
    • Privilege levels / trust model, running as the lowest possibile privilege and allowing impersonation and elevation of privilege without secret storage
    • Secret storage and other crypto API, particularly as it relates to database connections
    • Implementing encrypted connections to databases and LDAP stores by default unless unencrypted is required

    Conclusion… for now

    There is much work to do. I will blog my thoughts here regularly and refine the overall approach. I will obviously find some hidden corners of PHP of which I am currently completely unaware, so I will take advice from anyone who has experience in these areas.

  • PHP Insecurity: Failure of Leadership

    About a week or so ago, I wrote to webappsec in response to Yasuo Ohgaki (書かない日記) post about some issues with PHP’s security model.

    For some time, I’ve been worried about the direction of PHP. As many of you know, I helped write XMB Forum and now help write UltimaBB. XMB in particular is an old code base, and UltimaBB, a descendant from XMB. I’ve done a lot to protect that code base from attack, and luckily, we’ve been missed despite some doozy and silly security issues. After writing PHP forum software for three years now, I’ve come to the conclusion that it is basically impossible for normal programmers to write secure PHP code. It takes far too much effort.

    PHP needs a proper security architecture, and support for newbie programmers. PHP’s raison d’etre is that it is simple to pick up and make it do something useful. There needs to be a major push by the PHP Development team to take this advantage, and make it safe for the likely level of programmers – newbies. Newbies have zero chance of writing secure software unless their language is safe.

    Think about Logo for a minute. Logo can do some interesting things, but it is not a commercially useful language because it cannot do much. But it is an excellent teaching language. PHP is like Logo – it’s a simple and easy way to get into serious web development. It is possible to write large applications in PHP, so it is useful at that level. But it is inherently unsafe as it can do far, far more than Logo.

    There are so many ways to break PHP that it is impossible for even experienced security professionals like me to code in it securely all the time. There are nearly 4000 function calls, and many of them have unintended consequences or have been inappropriately extended by something else.

    At every turn, the PHP Development Team have made truly terrible “security” choices:

    • register_globals
    • magic_quotes_gpc (and friends)
    • PHP wrappers (see below)
    • safe mode
    • output, XML, LDAP, and SQL interfaces that intermingle data and query elements, which by their very nature are impossible to protect against injection attacks

    All of these are broken. They are disjunct and have no security model. Some of the features, like PHP wrappers, are not well documented, and are a clear and present danger to PHP scripts and worse, they do not obey the weak “safe” mode restrictions. I bet few PHP coders are aware of them, let alone their security impacts.

    http://php.net/manual/en/wrappers.php

    PHP coders cannot rely upon their script running in a Unix or Windows environment, so they must code to the least common denominator. Hosters rarely upgrade to the latest PHP, even though it is safer. Even though programs could be ported to safer interfaces like PDO or the OO mysqli parameterized queries, programs cannot support this mode as it’s too rare. Even PEAR modules are hard or impossible to import in a shared environment, so favorites like PECL or ADODB which might help are not available, so programs ship with outdated and vulnerable libraries.

    So why this whinge?

    PHP must now mature and take on a proper security architecture, an over arching security model which prevents or limits attack surface area until the application explicitly asks for it. There can be no other way. If you look at Bugtraq, every day, 10-50 PHP applications are broken mercilessly. This cannot continue. Hosters cannot pay the price for the PHP development team’s lack of security expertise.

    I wrote back to webappsec that we as security experts should offer our counsel to the PHP Development Team. The only response I received from Yasuo-さん. His response included an exploit of the PHP wrappers (as above) which is completely unaffected by any safe mode implementation. He also suggested I contact Rasmus Lerdorf, one of PHP’s creators who leads the PHP development team.

    I e-mailed Rasmus, and although it’s the new year, I have yet to receive a reply. I get a lot of e-mail, but I make an effort to reply to all of it. I wish others would do the same – it is only polite. [ Edit: 24/1/2006 – I have a reply from Rasmus. Apparently, he saw Chris’s blog and thus this rant, and replied. ]

    It is time to stop complaining. The time for forgiving PHP’s weaknesses are over – it must stop, and stop now. PHP 6.0 is still in development, and it should be so clearly more secure than anything before it, that hosters will upgrade to it, in the same way they have not upgraded to PHP 5.0.

    It is time to いたします。

  • PHP Insecurity: File handling and remote code execution

    For better or worse, there are a lot of novice programmers hammering away at PHP scripts all over the planet. It is one of the most common web scripting languages. However, it’s simply too hard for a newbie PHP programmer to write secure PHP code. As I’ll demonstrate, it’s also impossible for even security minded PHP professionals to keep their applications secure due to the way PHP manages change to its ever-growing API. Their culture of “add stuff, but stuff the security implications” has to stop. Don’t get me wrong, I love change. I just don’t love the way the PHP project goes about it.

    Let’s take a non-hypothetical instance. Some functions are very familiar to Unix folks, like fopen(), fread(), fclose() and so on. In Unix, the semantics of these functions and the security issues surrounding them are well understood. However, in PHP, fopen() and friends are heavily overloaded, and gain new functionality between even minor PHP releases. For example, by default, PHP’s fopen() and several friends can open any file on the Internet. Producing a canonical filename which is safe is basically impossible in PHP.

    Take a typical PHP application using templated languages. A typical implementation will enumerate a directory to see what files are available (English.lang.php, русски.lang.php, etc) and then try to “fix” it up. The attacker will then try to substitute ../../../../../etc/passwd or something similar. Nothing new here for our Unix friends. But what about going offsite? Well, the top vulnerability for PHP applications in 2005 is remote file inclusion and it uses this exact same mechanism.

    The usual type of thing I see all the time:

    $language = $_POST[‘language’] + “.lang.php”;
    include ($language);

    Of course, the security people reading this are going “nononononno!”. But to the average PHP programmer, why should it be any harder? PHP just made a basic idea very hard to get right. This is not to say J2EE or ASP.NET are invulnerable to this type of boneheaded programming, but they don’t allow you to include files from over the Internet and then evaluate their contents.

    What about if we move to file_get_contents() instead of including the result? file_get_contents is rarely used as it is a PHP 4.3.0 and later construct, and PHP coders are reluctant to use new fangled calls when old ones will do. However, it is no better! It STILL allows us to read the file directly from a URL or via a wrapper, like php://output (which acts like echo… with the usual association of data… XSS city), or php://filter/resource=http://www.example.com … and this is NOT restricted by allow_url_fopen. Who comes up with these settings?

    Programmers are usually surprised at the wide number of places what used to be local file operations are able to be used for remote file and file filters. The job is made harder because PHP keeps on changing its mind about what is available. What used to be a safe application with PHP 4.2.x is no longer safe in PHP 4.3.x or PHP 5 – just because PHP changed.

    Accompanied by extremely fragmented documentation (ie “see Appendix L” or read the usually extensive comments to see how the functions ACTUALLY work), it takes experience to program PHP’s file operations. With a very low barrier of entry, PHP needs to keep these advanced features to those who know what they’re doing. However, it’s far too late. PHP is used by programmers of many different skill levels. The average Joe programmer has no help in hell of writing a safe PHP application.

    In the meantime, let me plug Chris Shiflett’s brand spanking new PHP Security book from O’Reilly:
    Amazon Listing

    If you want to write secure apps in PHP, you need that book.