A Secure Wrapper For Downloading HTTPS Resources Using file_get_contents()
Today, I’ve released v1.0.0 of the padraic/humbug_get_contents package on Packagist.
With the release of PHP 5.6, there was a significant security improvement in how PHP handled SSL/TLS protections, namely that it enabled a secure set of default options. Previously, SSL/TLS was disabled by default. No peer verification, no certificate checking, and a lack of configuration options had combined to create a serious problem. You can find this problem easily by searching for file_get_contents() on github and locating a call to this function used to retrieve any HTTP resource while also having zero configuration.
An excellent example of this is Composer which uses file_get_contents() instead of curl to ensure maximum compatibility with using systems. Of course, this beggars a question. If all the SSL/TLS protections are off by default in PHP 5.3-5.5…what’s stopping some irksome hacker from injecting bad code into our Composer downloads?
This issue was originally addressed in the Composer Installer. Around that time, PHP 5.6 also had its SSL/TLS support overhauled, significantly improved and enabled by default. That still left PHP 5.3-5.5 vulnerable by default. It also left the main Composer application and other uses vulnerable on these PHP versions.
This package includes a simple standalone function that can be used as an alternative to file_get_contents (which it wraps) in any code where HTTP requests are likely. On all versions of PHP less than PHP 5.6, it will enforce a safer SSL/TLS context configuration.
So, writing code targeting PHP 5.3 to 5.5? Using file_get_contents() to access any HTTP(S) resources/downloads? Don’t want to be vulnerable to Man-In-The-Middle attacks?
The actual configuration itself closely matches that implemented for PHP 5.6, though it will vary somewhat due to limitations in earlier PHP versions. The most obvious is that on PHP 5.3 to 5.5, TLS 1.1 will be commonly used. PHP 5.6 would typically end up using TLS 1.2 by default.