PHP, Security & PSR-9/PSR-10

Late yesterday afternoon the PSR-9 and PSR-10 drafts were moved into master on the php-fig/standards repository, moving them along to the next step and to get the wider perspective of the main PHP-FIG group’s opinions on it.

What are PSR-9 and PSR-10, you ask? Here’s a brief summary so far:

At the end of last year (2014) Lukas Smith made a proposal to the PHP-FIG group for a standard that would make reporting security issues with PHP projects and libraries a much more structured thing. The general idea is that a standardized document (or documents?) in a project’s repository would provide information about current and past security issues in a well-defined structure that could have some automated tooling around it. Much discussion was had around what the proposal actually entailed and how it would integrate with the goals of the PHP-FIG process. As work progressed on it, a few others besides Lukas came on-board to help flesh out the standard and work out the kinks, including myself.

It wasn’t long before we realized that, while having a standardized method for reporting vulnerabilities was good there also needed to be a way to discover this documentation for a given project (more than just a “look for this file” kind of thing). So, the original PSR-9 was split, giving us the security advisory reporting standard (PSR-9) and the security disclosure workflow (PSR-10) to make discovery of the reports easier. Both PSRs have received the votes needed for entrance and consideration and, as I mentioned, work is moving forward on them in the wider PHP-FIG group.

So, what are the standards? Well, I’m not going to just copy and paste from the documents (you can find those here if you’re interested) but I will give a quick overview of what they contain and their goals.

Note: these standards are by no means complete so this information is a bit subject to change. I just wanted to share their current state though.

PSR-9

The main goal of the PSR-9 standard is to provide structure around the documentation a project provides to the wider community around security vulnerabilities that have been found (and fixed) and those that are still pending. The idea is that any given user could look at the document and have a security-centric view into where the project currently stands. Right now, with the exception of those participating in the security-advisories database, most projects make it a bit of a run around to try to figure out what issues have come up and what problems have been fixed. Sometimes it’s reported in the Changelog, other times it’s in the mailing lists and other times you just have to know what to search for in the project’s issue tracker to get the list. This PSR-9 aims to eliminate a lot of this hassle and give a single source for the information.

The security-advisories database has provided a great start around this same kind of information but with PSR-9 the burden of reporting this information falls on the project, not a single source. We’re not aiming to replace that database by any means, though. We just want to empower the projects to share the information in a vetted, well-defined way. The PSR-9 proposal provides a lot more context around the security issues too.

This information includes:

  • An entry for each vulnerability that includes a short summary, published date, link to more information and a unique reference ID
  • CWE and/or CVE information, if possible (not all vulnerabilities are reported as CVEs)
  • What versions the issue affects
  • Current status of the issue
  • A description of the remediation if resolved
  • A low/medium/high severity rating based on the impact to the project’s users

We discussed the versioning of this resource (multiple files) so new vulnerabilities could be added and a “history” of sorts could be tracked over time but nixed that idea in favor of a single file that would just evolve over time. A lot of this vulnerability metadata is similar to information currently reported by other projects, so it’s not too far of a stretch to see this dropped into a structured, easy to find document. Speaking of which, this brings me to the next proposal…

PSR-10

Where PSR-9 is about the structured vulnerability list, PSR-10 is about the discovery of said document. As we worked through the original PSR-9 ideas, we found that reporting the vulnerabilities was one thing and having a structured way to access the documentation was another. One is more about the concrete thing, the document, and the other is more around process.

The PSR-10 proposal isn’t quite as fleshed out at the moment, but there are a few main points that give us a starting place:

  • The document that represents the data for a project’s PSR-9 disclosure should live somewhere the project can directly reference it, such as the project’s website or other documentation page. This is the ideal place as it removes ambiguity around which version of the document is the “master”.
  • Projects may opt to have the source in their version control system with the caveat that it should be publicly facing (not require a checkout) and that the “master” branch should be visibly documented.
  • Projects would be allowed to split up the information by the version number of the release but, as this can get much more confusing quickly, it would need to be well documented

We discussed just having the document in the version controlled repository of the project, but this leads to other issues including the definition of which branch is the “master” for the document and how to deal with private repositories (remember, the goal is public disclosure). Ultimately is was worked out that a public-facing resource was the best option. One suggestion includes a custom “link” tag with a relation value of “php-vuln-disclosures” to help with automated discovery.

We’re all excited about these two standards moving forward and look forward to the feedback the wider PHP-FIG group can provide around them. Things will be developing a bit more quickly now (it was slow going mainly because of holidays and other personal issues around the end of the year) and our hopes are that these two standards can evolve and be worked out as soon as possible.

Keep an eye on the proposals as they evolve. I’d love to get any feedback on them or suggestions based on your own experiences that would help make things even better.

Speaking at AppSec USA 2015

It’s always good to step outside of your usual bubble and try something new every once and a while. I recently took this step and submitted for the AppSec USA 2015 conference happening in San Francisco on September. My topic? PHP security, naturally but it’s to a much more diverse audience. At PHP conferences its easy to take a lot of things for granted. You’re able to assume that most of the people in the room are developers and understand what PHP’s all about and have at least a little experience with it. At AppSec I don’t really have that guarantee so it’ll be interesting to see how it turns out.

Here’s my prospectus for those that are interested:

PHP Security, Redefined

Let’s be honest, PHP has had a rocky history with security. Over the years the language has been highly criticized for it’s lack of a focus on security and secure development practices. In more recent years, however, a resurgence has happened in the language and community, bringing secure development back into focus. With PHP 7 on the horizon, the language is making even more strides to improve some of its wayward ways of the past and reinvent itself. I’ll share practical code examples, tools, libraries and best practices that are making it easier than ever to keep PHP applications safe.

Come along with me as I guide you through both the language improvements and community encouragement making PHP a more secure place.

I’m hoping that, while the talk is more specifically about PHP security, that it will also be a good platform to help some in the information security community shatter some of their own misconceptions about PHP (ones that are probably stuck in the late PHP 4 to early PHP 5 days). I’m excited to get to talk about PHP7 too which, if all goes well, should be in its final stages by the time the conference rolls around in September.

When I got the acceptance email, I felt that same feeling down in the pit of my stomach I felt when I first was accepted to php[tek] so many years ago. Now it’s a good feeling, though – one that’s more excitement than worry, more encouragement than stress.

Social Security

Let me preface this by saying I think that sharing knowledge and experiences is a great thing. I love that there’s so many tutorials out there from people showing good practices in security and things they’ve learned along the way. Unfortunately, this is the same place where I see a major downfall. This kind of “social security” is a problem and it needs fixing so secure application development can really thrive.

Technology is great, especially PHP. Sure, there’ll be haters out there and they’ll throw stones at the glass house that is PHP hoping to break down the walls and push it off away from the public eye and into the “Not A Real Language” world. Fortunately, this will never happen especially with more recent improvements to the language and its consistent popularity among web developers. PHP is both easy to pick up but difficult to master, especially when it comes to the security of the applications written with it. Along with this low barrier for entry comes people sharing things either in tutorials or just articles that they’ve found to be useful or think is a good practice. The web is littered with articles like these, some being a bit more factual than others. *This is where the real problem is.*

Well-meaning developers post tutorials about things like preventing XSS with just htmlspecialchars or only fixing SQL injection with prepared statements and bound parameters. While these are good practices in themselves, they’re not the only thing that needs to be done to prevent these issues. Security is a complicated subject and there’s no one answer to any problem. Usually a robust solution involves multiple layers (defense in depth anyone?) to ensure the problem doesn’t pop up again or in another location. Even worse are the numerous older articles posted around the internet that have bad or old information. Sadly I see some of these that are *years* old being recommended as good resources to learn from.

I see two kinds of resources out there:

  • Those that are posts from individuals or groups and are wholly maintained by them
  • community resources such as the OWASP wiki

I’ve done some picking on OWASP in the past about the quality of their PHP materials and what seems to be their general feel around PHP and PHP-centric security. This time, though, I don’t want to talk as much about their content itself but about the process they follow for generating that content.

I appreciate what OWASP is going for application security, I really do, but I think the “everyone can edit” mentality of their content is very flawed. I know it’s just not feasible for a single organization largely made up of volunteers to manage and audit all of the content on their site. I get that, I really do, but when I see people referring to PHP resources that haven’t been updated since 2006 or 2007 it makes me cringe. And, because of the visibility of the group, those are the resources people find and recommend not knowing any different.

I think this is the crux of my opinion – having resources where anyone can contribute and not auditing those resources is a “Bad Thing” in my book. Unfortunately, in the case of the masses of tutorials posted out on the web, there’s not much that can be done about that. Those are there to stay and search engines will continue to ensure they show in results regardless of their quality or relevance to the current state of things.

I’m not saying I want people to stop contributing here, I just think there needs to be a balance. There’s a lot of regurgitation of the same kinds of advice out there (“let’s rehash the Top 10 again…”) but there’s also a lot of more innovative content that gets deeper into PHP security matters beyond just the prevention of the most common issues. In my experience, PHP developers are becoming more and more savvy about the security of their applications (even if it is a “negative deliverable” so to speak) and require tips and techniques beyond these simple ten point checklists.

Unfortunately, there’s just not a good answer here. As long as the web continues to be a free for all in terms of posting content developers will keep posting the same things or they’ll post bad suggestions (or ones that just don’t make any sense). The only thing I can think to do is to offer advice to those doing research or reading through PHP security content to ensure they’re getting the best information they can:

  1. Check the article date. If it’s older than 9-12 months, close the tab and move on. That’s not content you need to be reading.
  2. If the content talks about “preventing the most common vulnerabilities” in PHP applications, chances are it’s just another Top 10 article. If you know those already, skip it.
  3. Favor articles with links from things other than search engine results. If you come across an article from a recommendation on another non-linkbait site chances are the content is at least mildly useful.
  4. Consider the source. Do a little research on the author, if they don’t have much of a presence on the web around PHP-related things either take the advice with a large grain of salt or move on.
  5. Look for things that are well-written. Chances are if something is easy to understand or provides plenty of technical detail (and less hand waving “do this not that”) you’ve found something worth reading through.

These are just guidelines, obviously. Ultimately it’s up to your best judgement and research skills to determine the validity of the content and if it applies to your situation.

Invoke and Gatekeeper for Route Authentication & Authorization

As a part of a new project I’m working on (personal, not work) I came across a common need to enforce authentication and authorization handling in a bit more automated way based on the URL requested. I looked around for options and didn’t really find many that could be implemented somewhat simply but I did like the way Symfony defines their YAML to enforce auth* on the various endpoints. I set out to make something similar but a little simpler and ended up making Invoke.

It’s a super simplified version of the YAML-based routing and only has functionality for checking groups and permissions right now, but that’s not what I really wanted to talk about in this post. Invoke is fun and all, but I wanted to show how I’ve integrated it with another more robust tool I’ve written, Gatekeeper. The goal of Gatekeeper is to make a simple drop-in authentication system for applications to take care of a lot of the boilerplate user management needs. It comes with the usual CRUD handling for users, groups and permissions (RBAC) and also supports password resets, security questions and “remember me” functionality. Again, Gatekeeper is a cool library but it’s not the primary focus here. I wanted to integrate the two libraries so I could let each do what they do best – Invoke to check the current user against a set of criteria and Gatekeeper to provide the data for this validation.

Invoke lets you hook in your own users via a `UserInterface` that you can implement in your own application. In this case Gatekeeper has a concept of users too, but they don’t exactly mesh with what Invoke is expecting. So, let’s make an Invoke-compatible user object that it can use for it’s checks. This is the real key to the integration:

<?php
use \Psecio\Gatekeeper\Gatekeeper as Gatekeeper;

class InvokeUser implements \Psecio\Invoke\UserInterface
{
  private $details = array();

  public function __construct(array $details)
  {
    $this->details = $details;
  }

  public function getGroups()
  {
    $groupSet = array();
    $groups = Gatekeeper::findUserById($this->details['id'])->groups;
    foreach ($groups as $group) {
      $groupSet[] = new InvokeGroup($group);
    }
    return $groupSet;
  }

  public function getPermissions()
  {
    $permSet = array();
    $permissions = Gatekeeper::findUserById($this->details['id'])->permissions;
    foreach ($permissions as $permission) {
      $permSet[] = new InvokePermission($permission);
    }
    return $permSet;
  }
}
?>

Then, we’ll define the Invoke configuration in a YAML document:

event/add:
  protected: on
  groups: [test]
  permissions: [perm1]

In this case we’re telling Invoke that when it sees the requested URL of `/event/add` it should check a few things:

  • That the user is authenticated (protected: on)
  • That the user has a group with the “name” attribute of “test”
  • That the user has a permissions with the “name” attribute of “perm1″

If the user passes all of these checks, they’re good to go. Here’s how that would look in the execution of the Invoke code:

<?php

$en = new \Psecio\Invoke\Enforcer(__DIR__.'/config/routes.yml');

// If you're already using Gatekeeper for user management, you
// can just use this:
$userData = Gatekeeper::findUserById(1)->toArray();

// Otherwise you can push in your own user data
$userData = array(
  'username' => 'ccornutt',
  'id' => 1,
  'email' => 'ccornutt@phpdeveloper.org'
);

$allowed = $en->isAuthorized(
  new Confer\InvokeUser($userData),
  new \Psecio\Invoke\Resource()
);

if ($allowed === false) {
  // They're not allowed on this resource, forward to an error!
}

?>

The Invoke Resource by default looks at the current REQUEST_URI value so no options are needed when it’s created.

I’ve found this a pretty simple way to integrate these two libraries while still maintaining the correct separation of concerns enough to let each tool do their job. I’m always welcome to feedback on both projects or, of course, PRs if you find something that needs improving or a bug to fix.

Here’s more information about each of them:

Developer Security Outreach

I’ve been thinking a lot lately about how to try to bring the security and development communities together, most specifically for PHP (see these two posts for more on that). PHP has a long standing reputation for being an insecure language that it’s had to overcome. I like to think that evidence in more recent years is helping to dissuade that, but it’s an uphill battle. Anyway, that’s not what I’m hear to talk about. True to the title of the post, I want to talk about developer outreach as it relates to security and secure development practices.

While comments were made on my two previous post about the relationship going both ways, I want to focus in on things from the perspective of the organization with the bulk of the knowledge – the application security group/company. Yes, it’s good for developers to contribute back to shared resources so both parties can benefit, but with so many new developers coming to the language every day, I see a real need for engagement. There are a lot of groups and individuals out there on the security side that specialize in training and resources to help developers write their code more securely. They provide training classes and white papers on new technologies that can be used to get the ideas across, but usually only in a limited fashion. They write blog posts about the latest exploits and vulnerabilities or even speak at conferences with case studies and their own real-world experience in the world of application security.

So, take a step back – do you see a problem with this model? Most of these things I’ve listed involve talking at the developers and not with them. Sure, some of the training classes are more hands-on and can be much more effective at getting the speaker’s ideas across. However, these kinds of resources are mostly provided if requested or actively sought out by the developer. There’s a wealth of information out there about securing applications, even PHP ones, that’s tucked away and only shown when the right Google search is performed.

Is there a solution? In thinking about it some this morning, I see a pretty obvious one – developer outreach. I’ve mentioned this same idea before in another post, but that one was more targeted towards the OWASP group and the services/resources it provides. It still surprises me when I ask in my sessions at PHP-related conference how many people have heard of OWASP and some hands go up but a lot don’t. Likewise, there’s a lot of companies out there that provide application security training (such as the Denim Group, WhiteHat Security or even SANS) but those are still presented as passive resources. Developers, by their nature, are notoriously lazy. They try to find the most efficient, most robust solutions to problems. How much would they benefit from someone from the Denim group reaching out to them or even just the PHP community as a whole and sharing what they have to offer.

Am I suggesting they hop on the various community mailing lists and start spamming them with ads for their training courses? Of course not. Here’s what I am proposing:

If you provide training, resources or any other kind of resources that developers could benefit from to create more secure applications, find an advocate (or a few) in the community of your choice and request their help to get the word out. I’d even go so far as to suggest having someone dedicated to working with communities, maybe even different people for different communities. This person should be dedicated to not only sharing what kind of things the company/group has to offer the developer community but to also act as a guide to keep them on the right path.

There’s a security subculture in just about every language out there. The key for those with the security knowledge and resources to do is to tap into it. Break into the community with a sense of humility, an open mind to learn about its members and a passion for teaching and sharing knowledge on a personal level.

An Open Suggestion to OWASP (or How to Bridge the Gap)

In a previous post I made a call out to the security community (mostly the OWASP group) about some of the lacking involvement in the world of PHP. There were some good comments on the post, and there’s some I’d like to give my own feedback on to maybe explain things rolling around in my head even better.

First off, there was the comment I knew was coming even before I hit the “Publish” button. In this comment Ryan turns some of my comments back around and wonders if the lack of PHP involvement by OWASP is more of a reflection of how much involvement the PHP community has with it. While I agree with this to a point, I’d also suggest that it has to be a two way street when it comes to communicating effectively with developers. An organization that wants to provide information about how to secure applications should be involved with the groups it’s trying to help. Likewise, that group can’t effectively provide the information developers are looking for without guidance from those developers themselves. After all, what good would a guide about not using “safe_mode” be to people using PHP 5.4.0+? More on this topic later…

Another comment brought up a few more specific issues around the tooling that the OWASP group provides, suggesting that it’s less attuned to what PHP developers actually need and is more of a direct port of an existing Java or .NET version of a similar project. The influence is definitely there and it makes me wonder how much PHP experience the author had in the language (not just writing PHP but actually knowing PHP…there’s a difference). The PHP community is a rapidly evolving one by the nature of the language and if you’re not keeping up with trends, advancements in the language or where the state of security in the language is at, your tool will be deprecated before it even hits 1.0.

Finally there’s the comment I hoped I’d get from a representative of the OWASP group themselves, a member of the board no less, Michael Coates. I’m glad that the response was one of openness and a desire to make things better. It’s easy to see how, especially in a community that tends to err on the side of keeping things under a rock, that the group I was mentioning was paying attention. Michael’s comment asks for direct suggestions about things that can be done to help the situation I put out there. With the somewhat wide chasm between the two words, I can see a lot of room for improvement, but I think there’s one suggestion I’d make to Michael and the rest of the OWASP folks (including those already involved in PHP-related projects under the organization):

Get involved.

Sounds simple, right? Honestly, I think the biggest problem here is the communication between the two groups. I feel like the OWASP group, while having good intentions, sometimes comes across as more of a “we’re security professionals and we know how to write the tools correctly” kind of mentality. As a result, you end up with projects like the PHP ESAPI  or the work being done on the PHP Security Project that’s recreating tools that already exist in the PHP ecosystem for the sake of having a “one tool to rule them all.” Essentially what it ends up being is a mish-mash of tools that a developer could use to secure their applications. What it doesn’t end up being is a useful tool that PHP developers want to use to secure their applications.

The goals of the project are admirable, but their time could be much better spent encouraging the package mentality the PHP community has evolved over the past few years and enhance the security features of pre-existing and well-tested/vetted libraries already in wide-spread use. Let me illustrate with a list of things the owasp/phpsec project includes that already have packages that solve the problem:

– a database abstraction layer (not an ORM or even ActiveRecord, just a layer on top of PDO)

– a “download manager” that seems to not do much more than stream a file to the given output

– an encryption class that does some crazy stuff to encrypt a string

– A HTTP request class that most frameworks have anyway (or even HttpFoundation)

– A Logging class that can output to a database, file, mail or syslog (or just use Monolog)

– A cryptographically secure random number generator (how about RandomLib instead)

– A sort of “security scanner” that looks for a limited set of keywords (try Parse instead)

– A session handler that forces database use and doesn’t plug into the SessionHandler interface

There’s a lot of other features in the tool that could go on this list too, but it feels like there’s just a big disconnect here between the goals of the project to provide a useful library PHP developers will want to use. While I get the whole idea that other packages are “written by developers and not security experts”, there’s a lot of things they’re reproducing here that have already been solved.

So, my suggestion to the group working on the PHP Security Project is this – stop with the Not Invented Here development and get involved in the work that’s already been done to make these “decoupled libraries” people are actually using. Help show the PHP development community that you’re interested in being a guiding force for security concepts and techniques rather than building something in a silo most developers would never even use.

The PHP community gets better tools and OWASP gets known in the community as an organization that cares about keeping PHP safe. Seems to me like this is a win/win situation for both sides.

5797398751_e47d90690a_z

OWASP, A PHP Ostrich?

As a member of the PHP community for the last 10+ years, I’ve seen the topic of security come and go. PHP’s always had a bad reputation for being an insecure language and, honestly, that’s a valid point to make. It’s PHP’s own low barrier for entry and lack of a cohesive plan that’s made it such an “interesting” language to use over the years. I’ve also had a foot in the security community for the past few years and I’ve seen an interesting disconnect between it and the world of PHP.

I constantly see articles talking about how insecure PHP is compared to other languages and how no one should be using PHP if they’re concerned about protecting their users and data. As such, PHP seems to have been mostly dismissed by the security community as a sort of “toy language” that’s not suitable for the enterprise like Java or .NET are. I can’t tell you how many companies I’ve seen looking for people to fill application security analyst roles that only want Java or .NET experience. PHP makes up such a small part of their market that they don’t even bother looking. This is very surprising considering how much of the web is running on PHP (based on statistics, take that how you’d like).

This focus on the .NET and Java worlds has bled through to other parts of the security community too. Take the Open Web Application Security Project (OWASP) group as an example. If you’re a member (I am) or even just a casual reader of the information they have to offer, there’s a very clear bias towards these two languages. There’s been a few initiatives they’ve started over the years to try to enhance the PHP-related information they provide, but sadly a good bit of it is falling out of date and isn’t as useful as it once was. Things like the PHP Security Cheat Sheet  have had a few additions and wording changes, but even then there’s quite a bit of information that’s just missing from its content.

There’s something that concerns me more than just incomplete content on a wiki page, though. I was looking through some of the PHP security libraries that are being worked on by OWASP members (such as phpsec) and noticed something interesting. There is a lot of “Not Invented Here” going on there. Sure, PHP developers are guilty of this too, but it seems this hints at a larger point: is the OWASP group doing more harm than good by not embracing some of the well-known security tools that exist outside of their own organization? In fact, the only PHP library the OWASP group has on Packagist is their RBAC (role-based access control) tool that seems to ignore standards like PSR-4 (or even PSR-0) for autoloading, separation of concerns and good design practices that have become well-used in the PHP community in recent years.

So, what’s my point in all of this? I think the OWASP project can do better, honestly. They’re users of the PHP language but, with a few exceptions, don’t seem to be a part of the PHP community. They almost have their head in the sand when it comes to some of the practices that have come to define the language and community around it. It feels like PHP is an after-through on most of their initiatives and that there’s not much reaching out to the PHP community as a whole to find reusable packages that fit their needs, are more robust, well tested and proven.

The security community inside PHP is growing up and I think having large projects like OWASP understand it and be a part of it can help the news of this renaissance spread even further. PHP developers, more than ever, need as much up-to-date information and tools to help protect their applications. Consider this a call out to both fellow OWASP members and PHP developers as a whole to get involved in the wider security community, share these new advancements and openly share ideas across these borders.

Shatter those old conceptions of what PHP was and replace them with new techniques, practices and knowledge across communities. Only then can we help the wider web understand that PHP isn’t what it once was.