Seven principles for preventing vulnerabilities in PHP programming
7. Use Test Programs
It is essential to use automated tests alongside manual testing. To test an individual feature, it is often sufficient to use a self-written test program that is familiar with a lot of input values and the corresponding output values and compare the test results with the real results.
However, if the program you are testing is a bit more elaborate, it is no longer effective to write your own test programs. Fortunately, PHP has many test systems, such as PHPUnit [1], SimpleTest [2], or TestPlan [3].
PHPUnit and SimpleTest both serve to test the individual functions and instructions of the program – for example, whether variable values are valid or whether functions and function blocks return correct values. Thus, both PHPUnit and SimpleTest are suitable only for PHP environments. The manual for PHPUnit [4] provides a very good introduction to automated testing – knowledge that is easily transferable to SimpleTest, which has sparse documentation. Both are functionally and conceptually comparable.
TestPlan, on the other hand, checks to see whether the program returns expected values with specific user input; that is, it tests the response to certain inputs. For this purpose, TestPlan has its own scripting language that is optimized for performing basic interactions on web pages, such as entering data in forms or clicking on links. The programmer can then search the output for key words or character strings. This way, programmers can easily check to see whether the application works from a user perspective. If you select the input values skillfully, you can also discover critical situations (see the box titled "TestPlan in Practice").
TestPlan in Practice
Installation of TestPlan is relatively simple and explained well on the homepage [3], except for how to set the TESTPLAN_HOME environment variable correctly; for this article, it would be:
export TESTPLAN_HOME=~/testplan-1-0-r6/
On the author's Fedora test computer, it was not necessary to set JAVA_HOME.
The first simple test in Listing 1 checks the number of links on the author's homepage, thereby demonstrating multiple items from TestPlan's scripting language: It supports loops, can count, extracts things from the output, and even generates output itself. Thus line 5 selects the links in the %Response% output with parameter a, which corresponds to the HTML tag for a link. The href parameter in line 6 points to the URL returned by line 7.
Listing 1
Count Links
01 default %Cmds.Site% http://www.eggendorfer.info/ 02 GotoURL %Cmds.Site% 03 04 set %Count% 1 05 foreach %Link% in %Response://a% 06 set %URL% as selectIn %Link% @href 07 Notice %Count% Link: %Link% %URL% 08 set %Count% as binOp %Count% + 1 09 end
Listing 2 contains the simple counting test from Listing 1, but it is more complex: Here, TestPlan logs on to Facebook for the author and verifies whether HTTPS is enabled. This check is performed in two stages: First, the Check function ensures that the desired text is found on the page. If that is successful, the test script continues running. It then reads the message, removes the HTML from it, and uses a regular expression to check whether enabled is present. (Frequent tests in the form of Listing 2 will, however, cause Facebook to become suspicious, and it will require a CAPTCHA for login.)
Listing 2
Test Facebook
01 default %Cmds.Site% https://www.facebook.com 02 GotoURL %Cmds.Site% 03 04 SubmitForm with 05 %Form% id:login_form 06 %Params:email% someone@somewhere.com 07 %Params:pass% somesecurepassword 08 %Submit% key:enter 09 end 10 11 set %Count% 1 12 foreach %Link% in %Response://a% 13 set %URL% as selectIn %Link% @href 14 set %Count% as binOp %Count% + 1 15 end 16 17 Notice %Count% Links on Facebook homepage. 18 GotoURL https://www.facebook.com/settings?tab=security 19 20 Notice Check if HTTPS is enabled. 21 Check //span[contains(text(),'Secure browsing is currently')] 22 set %all% %Response://span[contains(text(),'Secure browsing is currently')]% 23 if strMatches %all% ^(Secure browsing is currently).* (enabled)\.$ 24 Pass HTTPS enabled 25 else 26 Notice HTTPS disabled 27 Notice Try to enable HTTPS. 28 Notice Subsequently start test again. 29 GotoURL https://www.facebook.com/settings?tab=security§ion=browsing&view 30 set %id% %Response://form[@action='/ajax/settings/security/browsing.php']/@id% 31 set %fb_dtsg% %Response://form[@action='/ajax/settings/security/browsing.php']/input[@name='fb_dtsg']/@value% 32 SubmitForm with 33 %Form% id:%id% 34 %Params:secure_browsing% 1 35 %Params:fb_dtsg% %fb_dtsg% 36 %Submit% value:Save changes 37 end 38 Notice Test HTTPS again 39 Fail HTTPS 40 end
If enabled is present, the script reports this test as having been passed (see Figure 3); otherwise, the test will automatically try to enable HTTPS itself (Figure 4, line 6-00). Because Facebook assigns a form a new, seemingly random ID on each new access, you'll have to employ a small trick. With the XPath expression in line 30, it is possible to read the ID. The result is deposited in the local variable %id%. This is also the case for the contents of a hidden input field in line 31. With these values, you can address the desired form on the page (line 33), filled out correctly and posted to Facebook.
If you now want to test automatically whether Facebook has really enabled HTTPS – which is necessary if the test is to continue, you must now write a small test to see whether Facebook has logged the user out again. Depending on the result, the script must log on again if necessary and then run the test again. The TestPlan language includes the possibility of calling up external test modules, so it is sufficient to implement the HTTPS test once – your own test script will then call up the module in several places. This approach simplifies the maintenance of the test.
Fundamentally, TestPlan's own language is powerful and easy to learn, but it is poorly documented. A bit of initial experimentation is therefore necessary. TestPlan is worth using because of its flexibility – and not just for your own web applications, but for small (and of course, legal) attacks as well.
In all cases, it must be clear in the developer's mind under which conditions the program runs correctly, where the limits are, and which inputs it will not tolerate. This knowledge is transferred into the tests, which reduces the likelihood of error.
Is All This Worthwhile?
Unfortunately, systematic testing of web applications is still not very widespread. Cost and time pressures are the most common reasons for the lack of focus on testing. That is strange, because as soon as attackers take over your website, nobody thinks about time and budgets anymore. Even those who do not want to include loss of revenue and reputation in the equation should keep in mind that, once suitable test processes are established, the overhead for maintaining those processes is quite manageable. The knowledge gained from systematic testing helps prevent the same mistakes from happening again, and the quality of future work improves.
Infos
- PHPUnit: https://github.com/sebastianbergmann/phpunit/
- SimpleTest: http://simpletest.org
- TestPlan: http://testplan.brainbrain.net
- PHPUnit manual: http://www.phpunit.de/manual/3.6/en/index.html
« Previous 1 2 3
Buy this article as PDF
(incl. VAT)
Buy Linux Magazine
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters
Support Our Work
Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.
News
-
Mecha Systems Introduces Linux Handheld
Mecha Systems has revealed its Mecha Comet, a new handheld computer powered by – you guessed it – Linux.
-
MX Linux 25.1 Features Dual Init System ISO
The latest release of MX Linux caters to lovers of two different init systems and even offers instructions on how to transition.
-
Photoshop on Linux?
A developer has patched Wine so that it'll run specific versions of Photoshop that depend on Adobe Creative Cloud.
-
Linux Mint 22.3 Now Available with New Tools
Linux Mint 22.3 has been released with a pair of new tools for system admins and some pretty cool new features.
-
New Linux Malware Targets Cloud-Based Linux Installations
VoidLink, a new Linux malware, should be of real concern because of its stealth and customization.
-
Say Goodbye to Middle-Mouse Paste
Both Gnome and Firefox have proposed getting rid of a long-time favorite Linux feature.
-
Manjaro 26.0 Primary Desktop Environments Default to Wayland
If you want to stick with X.Org, you'll be limited to the desktop environments you can choose.
-
Mozilla Plans to AI-ify Firefox
With a new CEO in control, Mozilla is doubling down on a strategy of trust, all the while leaning into AI.
-
Gnome Says No to AI-Generated Extensions
If you're a developer wanting to create a new Gnome extension, you'd best set aside that AI code generator, because the extension team will have none of that.
-
Parrot OS Switches to KDE Plasma Desktop
Yet another distro is making the move to the KDE Plasma desktop.

