Chris Cornutt (@enygma) asked on Twitter, “If you were just starting to learn about writing secure PHP apps, what would you want to know?” While I replied via Twitter, I figured I’d post my own short list here. I’d certainly consider this a beginner’s list, but it’s the kind of basic stuff I wish I had known.
- There’s nothing inherently secure about POST requests nor data retrieved from the $_POST superglobal. POST parameters are sent within the body of the message instead of the URL, which allows for longer key/value pairs than using a querystring, but it’s just as visible as any GET parameter.
- Anything transmitted to/from the server is inherently readable by anybody unless you specifically take precautions, such as transmitting via HTTPS.
- There’s no automatic/magic security or sanitization built in to most standard PHP functions nor frameworks. It’s often there, but you have to consciously use it.
- Just because it looks like an image, responds like an image, doesn’t mean it’s an image. (Or other type of included file.)
- 3rd party resources have access to anything on the page, regardless whether it’s visible, behind HTTPS, or obfuscated. Serving your site via SSL isn’t a magic bullet. Javscript can still access elements on the page and do nasty stuff (XSS), and you’re still vulnerable to CSRF attacks.
- Just because something is only “visible” server-side doesn’t mean it’s inherently secure. For example, any variable can be made global, and all the data within it can be read by any PHP script or method within that script. Case in point: the widely-used Akismet plugin for WordPress includes a dump of $_SERVER in each spam check it makes. This isn’t specifically a problem with Akismet, it’s just illustrating that code can be exposing stuff you didn’t think about, and may be exposing things you didn’t realize. You can do some really evil stuff.
- Just because you got a file from a reputable source, doesn’t mean it’s safe or good.
Some of those are web security but I didn’t know I needed to care when I started doing PHP and web development. I shudder to think of some of the code I wrote that’s still out there.
Related links
- WebSec library of articles (lots of great info, nicely presented and easy to follow)
- Deep dive into PHP security (easy, but long, read)
- Three security issues you thought you’d fixed (video)
- Developing Secure Widgets: Secure iFrame Communication in a Pre-postMessage World (video)
- Built-in PHP filtering
- MySQL bind params and WordPress: $wpdb->prepare()
- Validating Sanitizing and Escaping User Data (written for WordPress, but the ideas are valid regardless of platform)
Aside: One of the reasons I love WordPress is that it gives you all the tools to write secure code out-of-the-box. Other Frameworks like Zend and Symfony do, too, but they’re not as obivous.
One thing to note, several of these are already covered on my site http://websec.io in various articles. There were some good ideas here, though – thanks for the suggestions!
LikeLike
Thanks Chris — and I corrected the spelling of your Twitter handle. 🙂 (The link went to the right place, so I’ll blame autocorrect then look sheepish.)
I don’t think any of this stuff is that groundbreaking, really. Just stuff that counters a lot of assumptions and mistakes I made when I started with PHP and web development. ….And I just lost about 20 minutes digging around websec.io.
LikeLike
When I first tried CodeIgniter (in another age), this was the one thing that I liked most about it. You just needed to set a boolean switch to true in config and CodeIgniter would automatically run a XSS filter on all incoming data and when you use $_GET or $_POST etc in the app you can assume the data is safe in that regard.
LikeLike
Very cool. Reminds me of one of my favourite parts of Zend Framework, Zend_Form and Zend_Validate. You still have to know the methods exist, and you still have to know what to look for, but it makes it so much easier to implement.
LikeLike
Yeah, same with Laravel. It has an escape functionality when outputting data, so instead of:
you can do
and Laravel would escape the data before output but I don’t think there’s an XSS filter in it. So I just plug in my XSS function on startup to filter all incoming data.
Seems like the thinking these days is not to filter out stuff but just escape before output. I’m still not hooked to that though yet, still want to filter out stuff on input and escape on output – makes me sleep better! 😉
LikeLike
“Just because it looks like an image, responds like an image, looks like an image” –> “Just because it looks like an image, responds like an image”… 🙂
LikeLike
Hah, thanks 🙂
LikeLike
You’re welcome! 🙂
As for your article — ‘Better late, than newer!’. We all remember our ‘noob’ period and all mistakes that we makes while we grows our skills… 🙂
LikeLike