There are several programming practices that can make running PHP scripts safer. The most important one is probably using some common sense. Think about what can go wrong with a particular solution to a problem. Does it have any flaws that can be abused? Are there situations in which your solution does not work? Do I really want to permit user to run arbitrary SQL queries on my database? Running PHP scripts is much safer then running CGI scripts, but there is still a lot that can go wrong. Turning safe mode on can limit the consequences when things do go wrong. If there is a bug in your scripts that can be used to wreck your web site (or worse, your database), someone will find and use it. It is up to you to minimize the risk of this happening. Of course, good backups are essential, as always. Foolproof Software Web based applications, such as on-line catalogs, will often be running for extended periods without close supervision. If problems arise, you won’t be there to take immediate action. Usually your users are the first to notice problems, so you should make it easy for them to report problems. More often than not, these problems can be traced back to the scripts that make up the site. For instance, your users could be doing things you hadn’t thought of. Alternatively, it could be that your scripts are behaving in unexpected ways because you neglected to check the return value of an important function that fouled up. By trying to write foolproof software, you can prevent many of these problems. For instance, you should check the return values of database functions. If the database crashed, you could show your users a page with more information on the problem instead of a screen full of errors. You could even have your scripts page you in case of serious problems, such as a crashed database or a hard disk filling up. You also need to make sure you check all data received from users, but more on that later. If you write your software in such a way that it can cope with errors, your software will not only be more reliable, but it will also require less maintenance. The time this saves you could easily offset the extra time taken during development. Storing and Exchanging Sensitive Information Obviously, you should avoid sending sensitive information across the Internet in a way that makes it easy for outsiders to get hold of, such as using GET, POST, cookies or encoding information in the URL. Using an SSL capable web server is probably the easiest way and the best way, since it encrypts all information flowing between your web site and a visitor’s browser. Sometimes you will not have access to an SSL capable web server, so you will need to come up with something else. Maybe you don’t even need to send the data to the browser. Maybe you can just store all this sensitive data in a database and send the key to the browser, so you can easily find the data when you need it. You could also send all the data in an encrypted form. What this essentially comes down to is the use of sessions. PHP4 will have native support for sessions and there is a good library of functions allowing you to use sessions with PHP 3 (among other things): PHPLIB (phplib.netuse.de). You could also build something yourself. You could place all relevant information in an array, serialize it, and encrypt it. You could then send it to the browser in a cookie or store it in a form variable. Prepare the data in an array for transfer across the Internet: $encrypteddata now contains an encrypted version of the array. The extra bin2hex step is necessary because mcrypt_ecb outputs binary data. You will need to use bin2hex, urlencode or another, similar function before you can use it in a cookie or a form variable. You decrypt the data with the same process in reverse. Keeping tabs on the contents of files is almost impossible if you are not using a PHP module running in safe mode or a PHP CGI running under suEXEC. In such a situation, storing your data in a database may be the only way of keeping other people/scripts from reading your data. That is, if you have your own database. Checking User Input The Perl programming language (www.perl.com) has a feature called ‘taint checking.’ When taint checking is in effect, you cannot run some functions with tainted variables without getting a fatal error. A variable becomes tainted when its value is based in part or completely on data supplied by a user. Because this data should be considered insecure, this can really improve security. PHP does not have this feature, but PHP does have the escapeshellcmd function. For instance, suppose you had never heard of PHP’s mail function and wanted to provide users with an easy way to request a list of products you are selling. You could write a small HTML file and have the following script send them an email. This script has a very big security hole just waiting to be abused. You trust the data you receive from your users. What if someone were to use the following email address: The command executed by the system function would look like: This line actually consists of three commands. The first produces an error message about --bla being an invalid option, the second would mail your password file to this crafty person, and the third does nothing at all. If you use the escapeshellcmd function, you can avoid this particular problem. Placing the following line at the top of the script fixes this nasty bug. This is a rather naÏve example, but it should make it very obvious that you need to check the data you receive from a user, especially if you use the data they supply in calls to functions like system and exec. Even if you use the escapeshellcmd, you should still pay attention to the ways you use user-submitted data. Another way of making sure people will not be able to abuse your scripts is only allowing carefully checked input. For instance, if people need to enter an email address, check that it is really a valid email address. While regular expressions may be difficult to use, they do work. For more information on regular expressions, see Chapter 6 (Expressions and Statements) An example of a function to check user input is shown below. It will validate if a string contains a valid IP address. Conclusion Security is a state of mind. When you develop scripts, you should be thinking about what you can do to make the scripts safer. A secure web server running on a secure server gets you a long way, but you still need to be security conscious yourself. ©1998 Wrox Press Limited, US and UK.
blog comments powered by Disqus |
|
|
|
|
|
|
|