Earlier this month, 27 members of the Ibuildings team attended the PHPNW11 conference in Manchester. We will publish two personal reviews of the event by two of our software engineers - here's the first one.
Beware of the dark side, Luke!
For the morning of the tutorial day at PHPNW11, I decided to attend "Beware of the dark side, Luke!", a security tutorial by Arne Blankerts. While web developers tend to give more emphasis to the security issues directly related with their application (such as XSS, CSRF, SQL injection or Session security), Arne's tutorial was very interesting because it focused also on direct machine access, remote OS access, installed software exploiting, and hardware exploits.
Security is not an absolute concept, it consists of layers. How secure your data is from someone who's trying to obtain it depends on the effort someone is willing to put in versus the time/money you're willing to spend preventing that access.
This bring us to the first topic of the tutorial, data centre security. Even if you went all the way to prevent remote attacks, can your hosting provider guarantee that someone won't just be able to enter their data centre, and flee with your disk full of client data?
And consider this - if your data is valuable enough to someone, and you have a backup system powered by your hosting company, what if that system is shared by other clients? Can an attacker get a machine and backup service on the same hosting company as you, and use this machine to try to get data from the backup server?
The point here is that there's always something that someone can do to get to your data. How far you need to go to prevent that depends on whether the data is worth that amount of effort. So, the first step towards security is to decide where to host your application. If you deal with very sensitive data that is of great value, you'll probably want to go with a secure data centre, encrypted disks, non-shared backup servers and all data, sent and received, should be encrypted. It's up to you to decide if you need all of this, none of this, or something in between.
The tutorial then proceeded to remote access security. The first step is to disable password-based SSH login and only allow key-based login. This prevents brute force attacks to get your password. Of course, external root access should also be disabled - if you need root access, just give Sudo capabilities to a standard user, or use su.
Under no circumstances should you use FTP. The FTP protocol is very insecure; not only does it send all your data in plain text over the network, but it also sends your login credentials in plain text. It also uses random port numbers for communication, making it easier for an attacker to take over an existing connection and receive/send information to your server.
Apache and PHP
After this, we started taking a look at security from the Apache and PHP perspective. We discussed why PHP's safe_mode is broken and in fact makes you more vulnerable to security issues than protecting you. For this reason, safe_mode should never be on, and is scheduled to be dropped out of PHP soon. On the other hand open_basedir should always be used.
All software exposing, such as Apache version, PHP version, or even if your server is using Apache and PHP, should be hidden from someone accessing your server. Always set expose_php to off on your php.ini file.
If possible, use php-fpm instead of mod_php. It will give you not only security advantages, but also performance improvements. With mod_php every request will cause Apache to load PHP and all of its modules, even if those requests don't require PHP to prepare the response, as for example static pages, or static images. With php-fpm, a number of PHP processes are always running, ready to reply to Apache requests that happen to need PHP.
From here, we moved into hardware issues. Custom hardware issues. Again, this is something that requires your data to have enough value to someone, that they will go all the way to get a piece of hardware into your system. One good example is a modified USB dongle that can be casually dropped on a desk and that eventually someone will plug into their computer, or be social engineered to do it. From this point on, a hacker can have access to that computer.
Web Application Security
Next we moved into the security issues that PHP web developers are more familiar with - the exploits an attacker can run directly into your application.
Some rules of thumb to avoid being vulnerable to XSS attacks, include making sure to filter input for the right context, always escape output contextually, always prefer whitelisting to blacklisting, and never try to read user intentions and repair their input, which sometimes can make an attack even worse.
After XSS, we dived into sessions, and possible attacks through sessions. First we looked into some problems with sessions, such as coming from an untrustworthy source, being outdated or belonging to a user other than the one we’re expecting. We also noted that PHP doesn’t validate session id, which means a session id can contain malicious characters or not point to an actual session.
We then proceeded to discuss why session data should never be trusted. Unless specifically overridden, PHP stores all session data on the same path. This means that if your application is running in a shared hosting environment, an attacker sharing hosts with you can read and write to your session data, and this can even lead to code execution.
The most effective protection against session hijacking is probably fully switching to HTTPS. In case this is not possible, always use different session ids for HTTP and HTTPS.
Typical protection against CSRF includes using tokens. But for the tokens to be safe, you must not use predictable seeds for your token. An md5 of time(), for example, is easy to fake. Assuming that there's a session when comparing the token with the one supposedly stored on the session, can allow for a CSRF attack, if you fail to check whether the session really contains a token.
This can happen if your application uses the same name for session variables in different contexts.
Captchas are hard to read, and can be easily crowdsourced. They're also vulnerable to the same implementation failure mentioned regarding CSRF. If the code validates the provided value against a value that is supposed to be in the session without checking for its contents, an empty attempt to get into the page, without an active session, can pass the captcha validation.
In addition to using prepared statements, always make sure field names, table names and sorting fields don’t come from user input, use associative arrays as whitelists for those situations. Always make sure the user can’t send values other than int when setting limits on the number of results.
Use PDO instead of the MySQL extension.
Never store plain text passwords. Use salt when encrypting a password and reapply hashing multiple times. Do a quality check on user-supplied passwords. If possible, advise your users not to use common words or common words with characters replaced by numbers (for example replacing and O by 0 or an A by 4 and so on).
And finally we took a look at clickjacking and ways to avoid it, such as setting X-FRAME-OPTIONS to deny for no iframe embedding, or setting it to SAMEORIGIN to allow only frames from the same host.
Web Services Tutorial
After lunch, I went to the Web Services tutorial, presented by Lorna Mitchell, one of the organisers of PHPNW11.
We started by defining what a web service is: a way for an application to communicate, allowing for integration with other applications, exposing data and/or functionality, letting you refactor your application without the need to change the way others communicate with it. This allows you to have a common API from where different front ends or even 3rd party applications can get data or functionality.
We then discussed JSON vs XML, and why it is preferable to provide both kinds of output if possible. After that, we defined ‘Heartbeat Method’, and what it is used for. It was established that without documentation, examples, and a help point, a Web Service isn’t helpful at all, as people won’t be able to use it.
We then got into HTTP status codes, HTTP verbs and how to use them correctly and in a RESTful way. Still on the subject of HTTP protocol, Lorna spoke of the correct use of HTTP headers and how web services should be stateless, and all information needed should be on the request. Then we looked into some types of web services such as RESTful, RPC (XML-RPC, JSON-RPC or Soap). We looked in more detail into REST resources and collections. On how hypermedia allows a service to be self-documented, and allows URLs to change because they are provided by the API itself.
After a session of questions and answers, the tutorial day was over and everyone headed over to the pre-conference social at Kro Piccadilly to meet other developers and tech people all around.
The first conference day started with an outstanding keynote by Ian Barber, "How to Stand on the Shoulders of Giants". Ian spoke about how great ideas often come from the wish to solve a personal problem and not from the intention of creating something revolutionary. He also spoke about how innovation often builds upon the work of others, and how any of us can one day build something great, if we just keep trying to build the tools that will help us get where we want.
After the keynote, I decided to go to Sebastian Marek’s talk "Magic Behind the Numbers - Software Metrics in Practice". Sebastian spoke about metrics to evaluate the complexity of a software project. He presented ways to look for the complexity and try to reduce it. He spoke of sonar, php_depend, php_cpd, phploc, PHPMD and a lot of other tools that can help one get to the bottom of where complexity lies within their application. I then attended Sebastian Bergmann's talk on "PHP Tester’s Toolbox". Sebastian, the author of PHPUnit, covered various testing tools for PHP, reviewing their pros and cons and comparing them to PHPUnit.
After lunch, I went to see my colleague Alistair Stead's talk on "Varnish your PHP Application, Make it Fly!" in Track 2. Alistair went through Varnish’s configurations details, how the options one takes during the configuration relate to the type of website on which Varnish is being applied. He showed some actual stats on how Varnish can speed up a Magento ecommerce website, and gave some details on how to use both together.
After Alistair's talk, I headed to Track 1 to watch another Ibuildings colleague - Rowan Merewood’s talk on "Estimation or 'How To Dig Your Own Grave'", which ended up being one of the best of PHPNW11. Rowan’s computer was having issues connecting to the projector, and to make things worse, the previous talk in Track 1 went on longer than expected, leaving Rowan even less time to set things up. After a while the audience started being amused by all these attempts to make the laptop work with the projector, but the solution ended up being the switch of Rowan's laptop for Ben Longden’s MacBook Pro. For some more amusement of the audience, Ben's laptop seemed to be unable to show the slides in fullscreen and the remote control to change the slides wasn't working either. At this point, Rowan recruited Ian Barber to manually change the slides through the talk, and it was time to start. His presentation was flawless, a great choice of images, every detail was taken care of, to the point that his clothes matched the slide theme. The talk focused on how to make project estimates, and how to avoid some common pitfalls that often ruin estimates. During the talk, some Twitter users were rating it as one of the best of the conference, which I will have to agree with.
In the evening, there was an open tab at the hotel bar, where the more than 350 participants met for some drinks and some more PHP-related talks. Later, a few of us decided to take a walk around Manchester and get to know the city and some of its iconic locations such as the legendary Factory.
All photographs in this post copyright (c) Stuart Herbert