Creating Secure Web Pages and Web Forms: What You Need to Know
Fred is a busy small business CEO. He hired a cheap developer online to setup his secure medical web site for him. The developer got an SSL certificate and setup pages where patients can make appointments and the doctor can receive patient requests and notices, “securely”. However, the developer didn’t have any real training in security and none in HIPAA and as a result, PHI was being sent in the clear, there were no audit trails or logs, SSL security was not enforced, and may other serious issues plagued the site.
Luckily, Fred was made aware of the situation before a serious security breach happened (that he knew of); however, he had to re-do the site from scratch, more than doubling his time and money costs.
Creating a web site that has “secure” components requires more than slapping together some web pages and adding an SSL Certificate. All a certificate really does is create a thin veneer of security — one that does not go very far to protect whatever sensitive data necessitated security in the first place. In fact, naive attempts at security can ultimately make the data less secure and more likely to be compromised by creating an appetizing target for the unscrupulous.
So, beyond paying big bucks to hire a developer with significant security expertise, what do you do? Start with this article — its purpose is to shed light on many of the most significant factors in secure web site programming/design and what you can do to address them. At a minimum, reading this article will help you to intelligently discuss your web site security with the developers that you ultimately hire.
What is Involved In Web Site Security?
Web site security is a deep and complex topic. We will only be hitting the high points. The focus of this article is to address the security issues involved with a web site form that is designed to securely collect information from your visitors. What could be simpler, right?
Well, not quite. Here are some of the issues that need to be considered:
- SSL – Is the form secured so that data is transmitted from the end user securely and does your site therefore evoke trust?
- Web page content – Is the HTML content sent to the end user protected from Cross Site Scripting (XSS) issues and does it avoid loading objects insecurely and/or from third parties?
- Script Security – Are the scripts or programs that process the submitted data written with security in mind? Do they have any vulnerabilities?
- Infrastructure – Is the web site hosting provider you are using trusted and known for good security? Are you on a shared server when you should be on a dedicated one?
- The Data – What do you do with the data once it is submitted? Is that data secured?
SSL – Web Security Starts Here
An SSL Certificate is absolutely required for a secure web site. The SSL Certificate allows:
- the data sent to and from your web server and your users to be encrypted
- your users to trust that they are connecting to your web site securely and know that your site is secure
To get an SSL certificate, you can either order one directly from a third party, like Thawte, or contact your web hosting provider and to see if they can obtain one for you. In either case, your web host will need to install the certificate on the server where your web site is hosted, and then you will need to make changes to your site to take full advantage of the secure channel that you have added.
SSL and Encryption
By far the most significant reason that people use SSL to secure their web site pages is to provide encryption of the data sent to and from their web site and the end user. When the end user visits a page of yours that is protected by SSL, their web browser communicates over a secure channel with the web server, and so that all data transmitted is sent over this encrypted channel. This helps to prevent eavesdropping and “man-in-the-middle” attacks on the data (more on these below).
Without SSL encryption, there is little or no protection of the data. We will no review how to make sure that you set things up correctly to make maximal use of SSL and to prevent it from being circumvented.
SSL and Trust
The most overlooked and misunderstood aspect of SSL is the establishment of trust. That is, enabling your end users to trust that they are connecting to your actual web site. What else could they be connecting to, you may ask?
- Someone with access to the network between the end user and your site could be trying to intercept and read all the web traffic. This is a man-in-the-middle who is eavesdropping, and it is trivial to do without SSL security. Even with SSL security, it is easy to do if the man-in-the-middle can present the end user with an SSL Certificate for your domain name that they trust and which looks good (i.e. like a forged ID card).
- The users could be visiting another web site that is pretending to be yours (i.e. it looks just like yours). This “phishing” web site could be trying to collect information from your users for their own purposes. Unless your users can identify that this site is not legitimate, they could easily be duped into revealing user names, passwords, and personal information. How could they end up at a phishing web site like this? This can happen by, for example, clicking on a web site link emailed to them in a malicious email or by them going to a misspelled version of your web site address. No site is immune from such attacks, but you can mitigate them.
So, how can your SSL Certificate help mitigate the possibility of eavesdropping, man-in-the-middle, and phishing?
SSL Certificates are signed by a third-party authority, the so-called “Certificate Authority“. This can be:
- You, if you sign your own certificates
- A bargain priced authority like Go Daddy
- A respected authority like Verisign or Thawte.
If you sign your own certificates, then your web site will generate trust warnings when anyone comes to visit it. These can be made to “go away” on a per-visitor basis if the visitor chooses to permanently trust your self-signed certificate. However, this is never recommended for a public web site as self-signed certificates provide no inherent trust that they are legitimate (anyone can generate one and pose as your site), they look amateurish, and they are annoying to the end user. Self-signed certificates should only be used in internal or test environments.
Inexpensive Certificate Authorities do the absolute minimum to verify the identity and legitimacy of requests for SSL certificates (so they can keep their prices down). As such, certificates authorized by these authorities, while providing great encryption, may be somewhat suspect. Hackers and other malicious third parties may be able to get a legitimate certificate for your web site from these cheap third party providers. Hence, users who see sites secured by certificates from these providers may be somewhat leery. Use of certificates from these providers is recommended only when cost is an issue and user trust and the user’s perception of the security of your site is not a significant concern.
The more respected authorities issue certificates only after making comprehensive checks on the legitimacy of the request. Thus end users will have much more trust that certificates issued by such agencies belong to your actual web site. These certificates are recommended for anyone wishing to establish trust and respect in their web site visitors and end users.
If you want to maximize trust and make it very easy for your end users to identify your site as legitimate and to be able to easily tell if someone is trying to trick them with a fake certificate, you will want to use an “Extended Validation” (EV) certificate. These cost more, but are well worth it in terms of the security and trust that they provide. See: Extended Validation (EV) SSL Certificates.
Securing your Web Form with SSL
Once your web site has an SSL Certificate and it has been installed by your web host, your web pages can be accessed with addresses that start with “https://” instead of just “http://”. The “s” in “https” means “secure”. Note:
- When you are connected to a web page using a secure address like “https://yourdomain.com”, the web browser will show a “lock” icon to let you know that the connection is secure.
- Web pages that end in “.shtml” are not necessarily secure. The “s” there means “server” (i.e. server-parsed page) and not “secure”. So, for example, “http://yourdomain.com/index.shtml” is not a secure page, but “https://yourdomain.com/index.html” is a secure page.
- In most default web server configurations that have SSL enabled, you can access the same page both securely and insecurely. I.e. both “http://yourdomain.com/form.html” and “https://yourdomain.com/form.html” work and show the form — the only difference being the use of SSL or not.
So, lets say that you have a web form located at “http://yourdomain.com/form.html”. You have gotten an SSL Certificate and your web host has installed it. Next you want to:
- Make sure people connect securely to your form page
- Make sure that no one can connect to your form page insecurely
These two goals might sound the same, but they are not.
Make sure people connect securely to your form page
Since your regular web site pages are probably insecure, you need to make sure that the links to your secure form page are absolute links starting with the prefix “https://”. This will ensure that anyone clicking on these links will be taken to your form page on a secure connection.
Wrong Links: Relative links are not recommended because, if the user is on an insecure page of your site, relative links will always take them to insecure versions of the destination page. So relative links like the following should be avoided:
<A href="/form.html">Fill out my form!</a>
<a href="form.html">Fill out my form!</a>
Correct Links: Absolute links will ensure a secure connection by specifying that SSL must be used via the link prefix “https://”. For example:
<a href="https://yourdomain.com/form.html">Fill out my form!</a>
Be sure that ALL links to all secure pages of your site use this secure format with the “https://” prefix.
Make sure that no one can connect to your form page insecurely
So, now all of the links on your site will take your users to the proper secure version of your form. However, as mentioned before, most web hosts leave the insecure version of the form there and can still be accessed by users if they enter the address directly (or if you missed some of the links in your updates). As a next step, you should ensure that it is not possible to access the form page via an insecure connection. This is locking down or enforcing the use of SSL for this page.
There are several different ways that this can be done. Some of these include:
- Separate space for SSL pages: If your web host has this feature, you can configure your web site so that web pages for secure (SSL) connections are stored in a different directory from those for insecure pages. If you enable this feature, you would put your form page and any other secure pages in the secure directory and make sure that there are not any copies of these pages in the insecure directory. Thus, any insecure requests for these pages would result in a “page not found” error. You could, then, implement some server-side redirection rules where if someone does request the insecure page, they are automatically redirected to the secure version (this can be done using .htaccess files and the “Redirect” directive). If you did this, then secure AND insecure requests for the page would take the user to the secure version with no errors, warnings or issues for the end user.
- Scripted pages: If your form page is generated by a server-side script (i.e. PHP, Perl, Python, or JAVA), then your script itself can look and see if the request is secure or not (e.g. by looking at the server environment variables). For secure requests, it can render the form as usual. For insecure requests, it can either give the user an error or redirect the user seamlessly to the proper secure location.
If my form is posting securely to a secure form processing script, then why does the form itself need to be secured?
This question is usually asked when the secure form processing script is managed by a third party (e.g. SecureForm) if securing the form itself with SSL (which would require that the web site owner undergo the expense of actually getting an SSL Certificate for his/her web site) is needed?
The answer is based on the following facts:
- The data sent from your end users to the server will be secure and encrypted during transmission. This is enough for some applications, such as HIPAA compliance.
- The form itself will be sent to the end user unencrypted. If there is nothing sensitive in the form itself, this may be OK.
- End users who are non-technical will have no way of knowing if their data will be submitted securely until they actually try it. Many end users will not want to submit their data to an insecure form on your site for this reason.
- End users have no way of knowing if they are viewing your site, or a phishing site, or if there is eavesdropping going on — as there is no certificate to validate. Many users will not trust the connection and will not want to submit their data through your site.
- If your form page is insecure, it is very easy for any malicious party to perform a man-in-the-middle attack to eavesdrop on connections and to set up phishing sites. It is very hard or impossible for your end users to tell if this is going on.
If you do not SSL-secure your web form itself, you make it very vulnerable to attack and provide no way for your end users to trust your site. If there is nothing untoward going on, you do have transmission security to rely on; however, that minimal level of security is not recommended for production web sites or anywhere that compliance is required.
Other Aspects of Web Forms Security
Proper use and locking down of the SSL connection for encryption and trust is only part of web form security. There are many other aspects that you must be concerned with in order to protect your users, your application, and your company’s reputation. These include (but are not limited to):
- Secure Server-Side Programming: The scripts and programs that accept and process the data from your form must be created with security in mind. They must validate all submitted data as needed, not making any assumptions about its format and content. They must not provide avenues for attack such as “SQL Injection” and use of submitted content as actual file names or URLs for loading remote content. They should log any strange errors or problems for later analysis. They should provide a mechanism, if possible, for blocking undesirable actions or users from using the scripts.
- Validation: Validation of all input data is something that is part of the above two points. However, it is so essential, that we will repeat it and go over some of the fundamental points:
- Always de-taint submitted data. What does that mean? It means to never trust the submitted data and to take pains to ensure that the submitted data matches what you expect. For example, if you have a select list that sends your script a number as the value, do not assume that you are actually getting a number! Instead, check that it really is a numeric value or convert whatever is submitted into a number.
- Remove disallowed content from text submitted by users. I.e. special characters, embedded codes and other things that “should not be there” should be checked for and removed or blocked.
- Make sure the submitted data is not “too big” to be used.
- Do not assume anything — program defensively.
- Preserving State with Hidden Form Fields or Cookies: If your program remembers things from one page to another by saving the data in hidden form fields, then your program must also make sure that the content of those fields was not tampered with! One good way to do this is to make a hash of all the data, together with a secret value, and to include that hash in the form data as well. Then, when the form is submitted, you can recompute the hash and compare it with what passed from the form. If they match, you are OK; if they do not, then the data has been tampered with. No one can break this scheme without knowing your secret value or without breaking your hashing algorithm. This method can also be used to validate data saved in cookies.
- Third-Party Applications: If you install programs from third parties on your web site, then you must take care that there are not any known security issues with these programs, and you must be sure to update these programs as soon as new versions are released. If you let your web site languish with an older, vulnerable version of a program on it, it will become a target for hackers as they constantly search the Internet for such web sites. Your site will likely be hacked in these cases, possibly causing loss of business, deactivation of your web site, and tarnishing of your web site’s reputation. Using a third-party application is quick and easy, but you need to make sure to pick a good one, and that places the burden of keeping it updated on you. An exception is using a third-party application that is hosted by the third party itself (like the LuxSci SecureForm service). In these cases, the third party ensures that the program is always updated with anything needed to address any security issues that may arise — the burden is on them and not you. If you choose a good, respectable vendor, then you should have no problems.
All of these things, and more, are critical to the development of a secure web application.
Securing the Data After it Arrives
Ensuring that your users’ data is transmitted securely to your web server is certainly critical, as is ensuring that your application itself is secure and will not be hacked. However, what happens to that data after your program receives it? Do you still need to protect it in any way? Does it need to remain encrypted? How do you access or receive the data? Many people forget that getting the data from the web server to them securely may require just as much preparation as getting it from their users in the first place!
In the following subsections, we will look at three different ways of saving and retrieving your users’ data and see what is needed in each case to preserve the data security from your users to your eyes, and then to being saved on disk and in backups.
1. Emailing the data to you
By far the most common action that data processing scripts do is email the submitted data to the web site owner’s email address. The web site owner knows when there are new submissions just by checking his/her email and can access the data immediately there. As most people running web sites checks their email fairly often, this integrates well with their business operations.
However, the standard ways of sending email are completely insecure. To understand why, see The Case For Email Security. So, what can be done to still use email, but ensure that the data is secure and viewable only by the intended viewers?
- Have your web site script encrypt the data
- Send this encrypted data (or a link to download the encrypted data) to the intended viewers via regular email.
As the form data is encrypted within the email message, most insecurities inherent in email are obviated.
For more details on securing your emailed form data in this way, see Recipe: Completely Secure Collection of Web Form Data using SSL and PGP or S/MIME. You can also use the SecureForm service to have your form data emailed to you securely without the need to program anything yourself.
Saving the data in a database
Many web site owners like to have the submitted form data saved in a database (even if it is also being emailed to them). Why?
- The data is saved online and potentially accessible from anywhere
- If the emailed copies of the data are lost, the copies in the database are still there
- The data in the database can be accessed through a web browser if there is a suitable user interface
- The data is presumably backed up for you
Ok, so if storage in an online database is for you, then you need to:
- Optionally – use some kind of encryption, like SSL or PGP, to ensure that the data is stored in the database in an encrypted manner. Why? The contents of database tables are not encrypted or secure in general. Storing unencrypted data makes that data available to anyone else with access to the database or its backups.
- Provide a user interface that allows you to access the database data. This user interface must be secure, have strong access controls, and should provide a means for decrypting the encrypted data for you.
If you are really interested in security, the database option actually requires quite a lot of work or cost to make a solution that is secure and usable. For this reason, most small organizations do not end up using secure database storage for important form data.
SecureForm provides a secure database storage and retrieval option that does all of the above and more.
Saving the data in files
The file storage option is the “quick and dirty” alternative to secure database storage. Essentially, your program will:
- Make a file containing all of the form data
- Encrypt that file using PGP or SSL
- Save that encrypted file in a directory on the web server that is not accessible from the web site or save it in an online file sharing service (e.g. WebAides).
Then, the web site owners can login to the web server using Secure FTP and download these files as needed. They can be decrypted locally when the data must be accessed. Or, on the case of the files being saved in an online file share, other simpler mechanisms for accessing the data are available.
This solution is secure and provides a good backup to securely emailed data.
How Secure is Your Web Host
The choice of web hosting provider and environment is critical for the security of your web site application.
- A web hosting provider that does not specialize in security will likely not have an especially secure infrastructure, and the software they use is more likely to have unpatched vulnerabilities. This will result in your web site being significantly less secure.
- If your web hosting provider does not have good security and privacy policies or is generally not well trusted in terms of the sanctity of your data, you may have a problem. System administrators and technical support staff at the provider can access your web site application and raw data. If the data is not encrypted, they can read and copy it. They can modify the application to capture and store information. Do you have a good sense that this will not happen?
- Are you on a dedicated or shared web server? If you are on a shared web server and another web site on that server or the server itself is compromised, then your web site and data could also be compromised (depending on the nature of the issue). If you can afford it, dedicated servers and virtual private servers provide your site with a much higher level of security than a shared hosting account will offer.
Other Technical Security Tips
There are many, many other considerations in developing and maintaining a production secure web site. It would be impossible to cover or even list them all here. However, here are some more interesting and useful tips.
Use secure cookies
If your secure site is using cookies for anything, be sure to set the “secure” cookie flag. This will ensure that these cookies are never sent insecurely over the Internet when the visitor arrives at any insecure pages of your web site (they are not sent at all to insecure pages) and thus helps preserve the security of the contents of these secure cookies.
Prevent Form Spam
Form spam occurs when automated programs find your web forms and try to submit data through them so as to send you spam. Form spam can result in hundreds or thousands of useless form posts each day. Once you start getting form spam, stopping it will be your desperate goal. There are two primary ways:
- CAPTCHA – This method requires end users to read text embedded in an image and type that text successfully into a form field. This is then validated by the back-end program. Since most spam programs cannot read text embedded in images, it will successfully block almost all automated form spam. However, CAPTCHA does require that the users perform one more step and can be a little annoying.
Minimize the need for trust
A good rule of thumb is to minimize the need to trust third parties, and to trust only the trustworthy.
- If you do not trust your internal IT staff, do not host your web application on your own servers or give them access to the server used.
- If you do not fully trust the third party hosting your web site, be sure to encrypt the form data as soon as possible. This helps ensure that the data is not saved anywhere in plain text and also is not backed up in plain text, thus minimizing your exposure to nosy people at the web hosting provider. Further, be sure that the private keys and passwords needed to decrypt the data are NOT stored on the web host’s servers, if possible, so that they cannot decrypt the data themselves (and so no hacker who has broken into their systems can do so).
- Ensure that only authorized staff can access the submitted form data. Ideally, it should always be encrypted and only authorized people should have the capability to decrypt it.
These are just a few obvious points. As you evaluate your web application itself and the flow of data, ask yourself “who can access the raw data and how” at each stage. Are there stages where you are trusting people who should not be trusted? Are you using “security by obscurity“? If so, re-evaluate.
Forced use of strong encryption in SSL
The strength of encryption used by SSL is a function of both the user’s web browser and the server. Even if your web server supports very good encryption, like AES256, the browser may choose a weaker level of encryption so as to make things slower. Internet Explorer is notable for choosing weaker encryption in the interest of speed.
You can modify your web server configuration so that only levels of encryption that you approve can be used to access your site. For more information, see 256-bit AES Encryption for SSL and TLS: Maximal Security.
Use OpenID and/or Two Factor Authentication
If your web site uses logins to access “member’s areas”, you can support OpenID so that your users can use very secure methods to login to your site, such as smart cards and biometrics, without you needing to do anything special to support these access methods explicitly. Your users, if they use OpenID and are security conscious, can lock down their access to your site themselves. OpenID also provides a single sign on across multiple sites for your users — making use of your site easier. For example, see Extreme WebMail Login Security with OpenID.
Two factor authentication is almost standard on very secure sites now. It mens that you require both a password and something else (e.g. a token texted to the person’s phone) to validate their identity. Without both, the user cannot login. See DuoSecurity for a good solution that is free for small web sites.
Some Further Reading
For more details on aspects of web site application security, see also:
OWASP Guide to Building Secure Web Applications: http://www.owasp.org/index.php/Category:OWASP_Guide_Project
World Wide Web security FAQ: http://www.w3.org/Security/Faq/www-security-faq.html
CERT advisory 97.25.CGI: http://www.cert.org/advisories/CA-1997-25.html
CERT advisory CA-2000-02 http://www.cert.org/advisories/CA-2000-02.html
Secure Programming for Linux and Unix HOWTO (David A. Wheeler): http://www.dwheeler.com/secure-programs/
Preventing HTML form tampering: http://advosys.ca/papers/web/60-form-tampering.html