pentesterlab.com
Open in
urlscan Pro
54.87.134.91
Public Scan
URL:
https://pentesterlab.com/blog/php-security-is-improving
Submission: On July 23 via manual from BR — Scanned from DE
Submission: On July 23 via manual from BR — Scanned from DE
Form analysis
0 forms found in the DOMText Content
10010101 101110 11001 001 101 0111 101101 01101 Home Exercises Blog Bootcamp AppSecSchool Go Pro Login | Sign up IS PHP REALLY GETTING BETTER? Share There’s been a lot of chatter about PHP being insecure, but as Luke Stephens points out in his article, "People who say 'PHP is insecure' are uninformed", this is far from the truth. He breaks down why this belief is outdated and misinformed. One thing this article does not cover is something a lot of people don't realize: Programming languages change over time. PHP from 15 years ago is different from today's PHP. BLAST FROM THE PAST... If you are old-school, you probably remember Stefan Esser (i0n1c) and "The Month of PHP Bugs". Basically, Stefan spent March 2007 dropping vulnerabilities in PHP—not PHP applications, but PHP itself. This "Month of PHP Bugs" was started to increase awareness about PHP's lack of security. At the time, the PHP Hardened team was working on providing hardened versions of PHP (the "suhosin" patch). You can still find details about those bugs on web.archive.org: "The Month of PHP Bugs". Around this era, PHP applications were extremely common and had a very poor security track record. All of this didn't help PHP's reputation. But it was 17 years ago, and a lot has changed since then. One main thing is that PHP has reduced the number of surprising behaviors for developers. Let's dive in! PHP HAS CHANGED AND IS CHANGING The PHP language has evolved significantly over the years. Many tricks to find vulnerabilities in PHP applications or exploit vulnerabilities in PHP have been rendered obsolete with new versions. Let's look at some of the significant changes! NULL BYTES... PHP used to rely on C functions to access files. C functions are notoriously bad at handling NULL bytes (\x00 or URL-encoded %00). If you pass the string /etc/passwd\x00hacktheplanet to read a file, C functions will stop at the NULL byte and read the file /etc/passwd. This behaviour created a lot of vulnerabilities or made a lot of weaknesses exploitable. PHP moved away from this with PHP 5.3.4 by fixing CVE-2006-7243. PCRE_EVAL Another surprising behavior in PHP was available when you had control over a regular expression. The infamous PCRE_EVAL or /e could be used to have the result evaluated as PHP code, allowing for quick remote code execution. For example, in the snippet below: echo preg_replace("/test/e","get_current_user()", "test"); will end up replacing test with get_current_user() and execute get_current_user() as PHP code... An real-life example of the danger of this can be found by analyzing CVE-2005-2086: a remote code execution impacting PHPBB. This behavior was removed in PHP 7.0.0 (released in December 2015) LOOSE COMPARISONS Loose comparisons have also been a big issue in PHP. Why does "php" == 0 or why does "1`uname`" == 1? This unexpected behavior was changed in PHP 8.0. Look for the little stars in the image below and the notes below the table: While we're at it, why is declare(strict_types=1); so rarely used by PHP applications? ASSERT AND RCE PHP 8.0 also impacted the ability to gain remote code execution (RCE) by leveraging assert(). The contrived example below illustrates the issue: echo assert(trim("'".$_GET['a']."'")); and will lead to code execution. ASSERT AND RAISING... Another unexpected behavior of PHP was the fact that, by default, assert() wouldn't stop the execution of the code. Admittedly, you could change this behavior, but as good application security engineers know: "defaults matter". With PHP 8.0 (August 2023), the behavior has changed, and a failing assert() will stop the execution of the code by default! Before PHP 8.0, the following code: echo assert(true == false); echo "HACK"; will echo HACK in the default PHP configuration HASH_HMAC() Speaking of warnings, the following code illustrates a good trick to bypass a signature check - passing an array instead of a string: hash_hmac('sha256', array(), "HACKTHEPLANETWITHPENTESTERLAB"); This code returned NULL and raised a warning until PHP 8.0; since then, it has been raising a TypeError. HTMLENTITIES AND SINGLE QUOTES... Another trick to find quick bugs in PHP applications was to look for values echoed in a page in JavaScript using single quotes. This used to work because PHP didn't escape single quotes by default. Again, in application security, defaults matter! This behavior was changed with PHP 8.1. Before PHP 8.1: echo htmlentities("\"'<>"); //returns "'<> After PHP 8.1: echo htmlentities("\"'<>"); //returns "'<> SO, IS PHP GREAT NOW? Well, there are still some surprises and interesting behaviors that were recently fixed in PHP. For example, check out this bug in password_verify() (The first comment is worth reading just to learn how not to do application security). PHP 8.1 also introduced new features that may surprise developers and likely bring a few bugs: $_FILES[...]["full_name"]. It's worth keeping an eye out for this in your next reviews. CONCLUSION PHP has come a long way from its insecure past. While it has made significant strides in improving security and reducing unexpected behaviors, it's crucial for developers to stay informed about new features and potential security issues. Keeping up-to-date with the latest changes ensures that PHP applications remain secure and robust. Written by Louis Nyffenegger Founder and CEO @PentesterLab support@pentesterlab.com Privacy Policy Terms of Service Careers Logo © 2024 PentesterLab