Writing Secure Web Applications

The following points are helpful to secure your websites from all kinds of attacks.
1. Sanitize browser input.
All input from web browsers, such as user data from HTML forms and cookies, must be stripped of special characters and HTML tags.
This is by far the most common vulnerability in web applications. Everything from directory traversal problems to cross-site scripting problems can usually be traced to the simple lack of proper stripping of user input.
There are two separate dangers with browser input data:
a. Input containing special characters such as ! and & could cause the web server to execute an operating system command or have other unexpected behavior.
b. User input stored on the server, such as comments posted to a web discussion program, could contain malicious HTML tags and scripts. When another user views the input, that user's web browser could execute the HTML and scripts.
2. Don't put everything in the HTML directory.
Don't put everything in the HTML directory:
Most web applications use many types of files:
* Static files: HTML headers, footers, JPEG images and other raw non-changing content.
* Parsed HTML: static HTML mixed with executable code, such as PHP and ASP files.
* Include files: Libraries and routines shared by parsed HTML and other files.
* Data files: Database or flat text files written by the web application
Most beginning web developers dump all their files in the HTML directory... the "public_html" "htdocs" or "C:\inetpub\wwwroot" directory on the web server.
Web servers use a "permission by directory" model: files are treated according to the directory they are in. Every file in the HTML directory can be accessed by a web browser if the URL is known. Every file in the cgi-bin directory can be executed.
If your web applications write data files (such as a guest book application or message board), don't put the data files in the cgi-bin directory or html directory. Every file in cgi-bin can be executed, including data files. Every file in /public_html can be read by a browser. Never assuming an outside will never guess the name of a file in those directories, because eventually... they will.
For example, if your web app places a data file named "card_numbers.dat" in /public_html, any outsider who guesses the file name can view it's contents in their browser. Likewise, if library file "user_validation.pl" is placed in cgi-bin it can be run, even though the code in that file should only be read by other executable files.
Place data files is a directory outside of both /html and /cgi-bin. For example, create a /data directory outside the cgi-bin and public_html directories so the files cannot be executed or read from a browser. Likewise a create /include directory so library files and header code cannot be executed or read from a browser.
3. No to hidden fields.
Many CGI programs rely on so-called "hidden" form fields to store state information, settings and previous input data. However, HTML "hidden" fields are not hidden and not secure. Users can see them simply by viewing the HTML source of your form in their browser. It's easy for a user to change "hidden" fields... they only have to same the HTML form to their computer, edit the HTML then re-submit the form.
Contents of hidden fields should be sanitized and validated just like any other user input field. Hidden fields should not be used to set access modes or privileges for a CGI program (such as an 'admin' mode or 'paying user' privilege) without also using some form of user validation, such as password and username access restrictions.
A better way of preserving state information and settings is to store data in a file or database on the server then use an HTTP cookie or unique URL ID to reference the file. This is more difficult to program, but important data stays on your server.
4. Use POST instead of GET
HTML forms can be submitted using either GET or POST methods. POST is preferred, especially when sending sensitive information.
The GET method sends all form input to the web application as part of the URL. For example:
http://www.yourdomain.com/cgi-bin/cart. ... d=happypup
When the web application is called using GET, the above input is visible on the browser's URL location window. However, a more dangerous problem is that URLs are logged in many places:
* The web server access log
* The web browser's disk cache and history file
* In firewall logs
* In proxy server and web cache logs such as Squid.
All this logging allows others to see the data sent from HTML forms using GET.
The POST method sends form input in a data stream, not part of the URL. The data is not visible in the browser location window and is not recorded in web server log files.
The POST method is also more practical... there's a limit to how many characters can be sent using the GET method, but POST can send an almost unlimited amount of data from an HTML form.
However, even though POST information is generally not logged, like all other plain text information sent from a browser it can still be sniffed as it passes across the Internet. However, sniffing must be done in real time as information is sent across the Internet and requires the attacker to have physical access to the data lines between the web browser and web server. The risk of information being sniffed is far less than the risk of information being gathered from log files.
1. Sanitize browser input.
All input from web browsers, such as user data from HTML forms and cookies, must be stripped of special characters and HTML tags.
This is by far the most common vulnerability in web applications. Everything from directory traversal problems to cross-site scripting problems can usually be traced to the simple lack of proper stripping of user input.
There are two separate dangers with browser input data:
a. Input containing special characters such as ! and & could cause the web server to execute an operating system command or have other unexpected behavior.
b. User input stored on the server, such as comments posted to a web discussion program, could contain malicious HTML tags and scripts. When another user views the input, that user's web browser could execute the HTML and scripts.
2. Don't put everything in the HTML directory.
Don't put everything in the HTML directory:
Most web applications use many types of files:
* Static files: HTML headers, footers, JPEG images and other raw non-changing content.
* Parsed HTML: static HTML mixed with executable code, such as PHP and ASP files.
* Include files: Libraries and routines shared by parsed HTML and other files.
* Data files: Database or flat text files written by the web application
Most beginning web developers dump all their files in the HTML directory... the "public_html" "htdocs" or "C:\inetpub\wwwroot" directory on the web server.
Web servers use a "permission by directory" model: files are treated according to the directory they are in. Every file in the HTML directory can be accessed by a web browser if the URL is known. Every file in the cgi-bin directory can be executed.
If your web applications write data files (such as a guest book application or message board), don't put the data files in the cgi-bin directory or html directory. Every file in cgi-bin can be executed, including data files. Every file in /public_html can be read by a browser. Never assuming an outside will never guess the name of a file in those directories, because eventually... they will.
For example, if your web app places a data file named "card_numbers.dat" in /public_html, any outsider who guesses the file name can view it's contents in their browser. Likewise, if library file "user_validation.pl" is placed in cgi-bin it can be run, even though the code in that file should only be read by other executable files.
Place data files is a directory outside of both /html and /cgi-bin. For example, create a /data directory outside the cgi-bin and public_html directories so the files cannot be executed or read from a browser. Likewise a create /include directory so library files and header code cannot be executed or read from a browser.
3. No to hidden fields.
Many CGI programs rely on so-called "hidden" form fields to store state information, settings and previous input data. However, HTML "hidden" fields are not hidden and not secure. Users can see them simply by viewing the HTML source of your form in their browser. It's easy for a user to change "hidden" fields... they only have to same the HTML form to their computer, edit the HTML then re-submit the form.
Contents of hidden fields should be sanitized and validated just like any other user input field. Hidden fields should not be used to set access modes or privileges for a CGI program (such as an 'admin' mode or 'paying user' privilege) without also using some form of user validation, such as password and username access restrictions.
A better way of preserving state information and settings is to store data in a file or database on the server then use an HTTP cookie or unique URL ID to reference the file. This is more difficult to program, but important data stays on your server.
4. Use POST instead of GET
HTML forms can be submitted using either GET or POST methods. POST is preferred, especially when sending sensitive information.
The GET method sends all form input to the web application as part of the URL. For example:
http://www.yourdomain.com/cgi-bin/cart. ... d=happypup
When the web application is called using GET, the above input is visible on the browser's URL location window. However, a more dangerous problem is that URLs are logged in many places:
* The web server access log
* The web browser's disk cache and history file
* In firewall logs
* In proxy server and web cache logs such as Squid.
All this logging allows others to see the data sent from HTML forms using GET.
The POST method sends form input in a data stream, not part of the URL. The data is not visible in the browser location window and is not recorded in web server log files.
The POST method is also more practical... there's a limit to how many characters can be sent using the GET method, but POST can send an almost unlimited amount of data from an HTML form.
However, even though POST information is generally not logged, like all other plain text information sent from a browser it can still be sniffed as it passes across the Internet. However, sniffing must be done in real time as information is sent across the Internet and requires the attacker to have physical access to the data lines between the web browser and web server. The risk of information being sniffed is far less than the risk of information being gathered from log files.