324 Chapter 15 Implementing Secure Transactions with PHP and MySQLWhen writing sensitive data, you might be tempted to encrypt it first.There is usually little value in this approach tho
Trang 1322 Chapter 15 Implementing Secure Transactions with PHP and MySQL
Figure 15.4 SSL breaks up, compresses, hashes, and
encrypts data before sending it.
Compression schemes rely on identifying repetition or patterns within data.Trying to apply a compression algorithm after data has been turned into an effectively random arrangement of bits via encryption is usually pointless It would be unfortunate if SSL, which was designed to increase network security, had the side effect of dramatically increasing network traffic
Although SSL is relatively complex, users and developers are shielded from most of what occurs, as its external interfaces mimic existing protocols
In the future, SSL 3.0 may be replaced by TLS 1.0 (Transport Layer Security), but at the time of writing,TLS is a draft standard and not supported by any servers or browsers.TLS is intended to be a truly open standard, rather than a standard defined by one organization but made available for others It is based directly on SSL 3.0, but con-tains improvements intended to overcome weaknesses of SSL
Screening User Input
One of the principles of building a safe Web application is that you should never trust user input Always screen user data before putting it in a file or database or passing it through a system execution command
We’ve talked in several places throughout this book of techniques you can use to screen user input.We’ll list these briefly here as a reference
Compress
Calculate MAC
Encrypt
Packetize
<html><head><title><My Page</title>…
Our data
d><title> M
<html><hea y Page</ti Data Packets
Compressed data
Message Authentication Code
Encrypted Packets
TCP Packets headerTCP
Trang 2n The addslashes()function should be used to filter user data before it is passed to
a database.This function will escape out characters which might be troublesome to
a database.You can use the stripslashes()function to return the data to its original form
n Magic quotes.You can switch on the magic_quotes_gpcand magic_quotes_run-timedirectives in your php.ini file.These directives will automatically add and strip slashes for you.The magic_quotes_gpcdirective will apply this formatting to incoming GET, POST, and cookie variables, and the magic_quote_runtime direc-tive will apply it to data going to and from
databases
n The escapeshellcmd()function should be used when you are passing user data
to a system()or exec()call or to backticks.This will escape out any metacharac-ters that can be used to force your system to run arbitrary commands entered by a malicious user
n You can use the strip_tags()function to strip out HTML and PHP tags from a string.This will avoid users planting malicious scripts in user data that you might echo back to the browser
n You can use the htmlspecialchars()function, which will convert characters to their HTML entity equivalents For example,<will be converted to <.This will convert any script tags to harmless characters
Providing Secure Storage
The three different types of stored data (HTML or PHP files, script related data, and MySQL data) will often be stored in different areas of the same disk, but are shown sep-arately in Figure 15.1 Each type of storage requires different precautions and will be examined separately
The most dangerous type of data we store is executable content On a Web site, this usually means scripts.You need to be very careful that your file permissions are set cor-rectly within your Web hierarchy By this we mean the directory tree starting from htdocs on an Apache server or inetpub on an IIS server Others need to have permission
to read your scripts in order to see their output, but they should not be able to write over or edit them
The same proviso applies to directories within the Web hierarchy Only we should be able to write to these directories Other users, including the user who the Web server runs as, should not have permission to write or create new files in directories that can be loaded from the Web server If you allow others to write files here, they could write a malicious script and execute it by loading it through the Web server
If your scripts need permission to write to files, make a directory outside the Web tree for this purpose.This is particularly true for file upload scripts Scripts and the data that they write should not mix
Trang 3324 Chapter 15 Implementing Secure Transactions with PHP and MySQL
When writing sensitive data, you might be tempted to encrypt it first.There is usually little value in this approach though
We’ll put it this way: If you have a file called creditcardnumbers.txton your Web server and a cracker obtains access to your server and can read it, what else can he read?
In order to encrypt and decrypt data, you will need a program to encrypt data, a pro-gram to decrypt data, and one or more key files If the cracker can read your data, proba-bly nothing is stopping him from reading your key and other files
Encrypting data could be valuable on a Web server, but only if the software and key
to decrypt the data was not stored on the Web server, but only existed on another machine One way of securely dealing with sensitive data would be to encrypt it on the server, and then transmit it to another machine, perhaps via email
Database data is similar to data files If you set up MySQL correctly, only MySQL can write to its data files.This means that we need only worry about accesses from users within MySQL.We have already discussed MySQL’s own permission system, which assigns particular rights to particular usernames at particular hosts
One thing that needs special mention is that you will often need to write a MySQL password in a PHP script.Your PHP scripts are generally publicly loadable.This is not as much of a disaster as it might seem at first Unless your Web server configuration is bro-ken, your PHP source will not be visible from outside
If your Web server is configured to parse files with the extension php using the PHP interpreter, outsiders will not be able to view the uninterpreted source However, you should be careful when using other extensions If you place inc files in your Web direc-tories, anybody requesting them will receive the unparsed source.You need to either place include files outside the Web tree, configure your server not to deliver files with this extension, or use php as the extension on these as well
If you are sharing a Web server with others, your MySQL password might be visible
to other users on the same machine who can also run scripts via the same Web server Depending on how your system is set up, this might be unavoidable.This can be avoided
by having a Web server set up to run scripts as individual users, or by having each user run her own instance of the Web server If you are not the administrator for your Web server (as is likely the case if you are sharing a server), it might be worth discussing this with your administrator and exploring security options
Why Are You Storing Credit Card Numbers?
Having discussed secure storage for sensitive data, one type of sensitive data deserves spe-cial mention Internet users are paranoid about their credit card numbers If you are going to store them, you need to be very careful.You also need to ask yourself why you are doing it, and if it is really necessary
What are you going to do with a card number? If you have a one-off transaction to process and real-time card processing, you will be better off accepting the card number from your customer and sending it straight to your transaction processing gateway with-out storing it at all
Trang 4If you have periodic charges to make, such as the authority to charge a monthly fee
to the same card for an ongoing subscription, this might not be an option In this case, you should think about storing the numbers somewhere other than the Web server
If you are going to store large numbers of your customers’ card details, make sure that you have a skilled and somewhat paranoid system administrator who has enough time to check up-to-date sources of security information for the operating system and other products you use
Using Encryption in PHP
A simple, but useful, task we can use to demonstrate encryption is sending encrypted
email.The defacto standard for encrypted email has for many years been PGP, which
stands for Pretty Good Privacy Philip R Zimmermann wrote PGP specifically to add privacy to email
Freeware versions of PGP are available, but you should note that this is not Free Software.The freeware version can only legally be used for non-commercial use
If you are a U.S citizen in the United States, or a Canadian citizen in Canada, you can obtain the freeware version from http://web.mit.edu/network/pgp.html
If you want to use PGP for commercial use and are in the United States or Canada, you can get a commercial license from Network Associates See http://www.pgp.com for details
To obtain PGP for use outside the USA and Canada, see the list of international download sites at the international PGP page:http://www.pgpi.org
An Open Source alternative to PGP has recently become available GPG—Gnu Privacy Guard—is a free (as in beer) and Free (as in speech) replacement for PGP It contains no patented algorithms, and can be used commercially without restriction
The two products perform the same task in fairly similar ways If you intend to use the command line tools it might not matter, but each has different interfaces such as plug-ins for email programs that will automatically decrypt email when it is received
GPG is available from http://www.gnupg.org You can use the two products together, creating an encrypted message using GPG for somebody using PGP (as long as it is a recent version) to decrypt As it is the creation of messages at the Web server we are interested in, we will provide an example here using GPG Using PGP instead will not require many changes
As well as the usual requirements for examples in this book, you will need to have GPG available for this code to work GPG might already be installed on your system If
it is not, do not be concerned:The installation procedure is very straightforward, but the setup can be a bit tricky
Installing GPG
To add GPG to our Linux machine, we downloaded the appropriate archive file from www.gnupg.org Depending on whether you choose the tar.gz or tar.bz2 archive, you will need to use gunzipand taror to extract the files from the archive
Trang 5326 Chapter 15 Implementing Secure Transactions with PHP and MySQL
To compile and install the program, use the same commands as for most Linux pro-grams:
configure (or /configure depending on your system) make
make install
If you are not the root user, you will need to run the configure script with the prefixoption as follows:
./configure prefix=/path/to/your/directory
This is because a non-root user will not have access to the default directory for GPG
If all goes well, GPG will be compiled and the executable copied to /usr/local/bin/gpgor the directory that you specified.You can change many options See the GPG documentation for details
For a Windows server, the process is even easier Download the zip file, unzip it, and place gpg.exe somewhere in your PATH (C:\Windows\ or similar will be fine) Create
a directory at C:\gnupg Open a command prompt and type gpg You also need to install GPG or PGP and generate a key pair on the system that you plan to check mail from
On the Web server, there are very few differences between the command-line ver-sions of GPG and PGP, so we might as well use GPG as it is free On the machine that you read mail from, you might prefer to buy a commercial version of PGP in order to have a nicer graphical user interface plug-in to your mail reader
If you do not already have one, generate a key pair on your mail reading machine Recall that a key pair consists of a Public Key that other people (and your PHP script) use to encrypt mail before sending it to you, and a Private Key, which you use to either decrypt received messages or sign outgoing mail
It is important that the key generation is done on your mail reading machine, rather than on your Web server, as your private key should not be stored on the Web server
If you are using the command-line version of GPG to generate your keys, enter the following command:
gpg –-gen-key
You will be asked a number of questions Most of them have a default answer that can
be accepted On separate lines, you will be asked for your real name, your email address and a comment, which will be used to name the key
My key is named 'Luke Welling <luke@tangledweb.com.au>' I am sure that you can see the pattern Had I provided a comment too, it would be between the name and address
To export the public key from your new key pair, you can use the command:
gpg export > filename