Apache Security - Ivan Ristic [146]
As was the case with cookies, the recipient field can be manipulated to send email to any email address. Spammers were quick to exploit this type of fault, using form-to-email scripts to send unsolicited email messages.
Many form-to-email scripts still work this way but have been improved to send email only to certain domains, making them useless to spammers.
POST Method
Some believe the POST request method is more secure than GET. It is not. GET and POST both exist because they have different meanings, as explained in the HTTP specification:
GET request methods should only cause information about a resource to be transmitted from the server to the client. It should never be used to cause a change of the resource.
POST request methods should be used only to make changes to resources on the server.
Because a casual user cannot perform a POST request just like that—a GET request only requires typing the URL into the location field, while a POST request requires basic knowledge of HTML—people think POST requests are somehow safe. An example of this misplaced trust is given in the next section.
Referrer Check Flaws
The referrer field is a special header field added to each request by HTTP clients (browsers). Not having been created by the server, its contents cannot be trusted. But a common mistake is to rely on the referrer field for security.
Early versions of many form-to-email scripts did that. They checked the Referer request field (also known as HTTP_REFERER) and refused to work when the contents did not contain a proper address. This type of check has value. Because browsers populate the referrer field correctly, it becomes impossible to use the form-to-email script from another web site. However, it does not protect against spammers, who can programmatically create HTTP requests.
* * *
Real-Life Flawed Authentication Example
One of the worst authentication implementations I have ever seen was based on two misconceptions:
POST offers protection.
The Referer request header cannot be faked.
It worked like this:
An application supported one entry point that could be accessed by typing the URL in the browser. This entry point basically led to the login page.
Other pages were never accessed through normal links. Instead, every page contained an invisible form using a POST request method. Links consisted only of JavaScript code that caused the form to be submitted. Maybe you can see where I am going with this.
On the server side, all pages required the use of the POST request method and checked the Referer header to verify it existed and contained the domain name of the site.
This scheme worked on casual users, but was ridiculously easy to subvert. You only needed to fake one request to get in (without authentication taking place), and you were free to continue using the application as a normal user.
* * *
Process State Management
Process state management is difficult to do in web applications, and most programmers do not do it when they know they should. This is because most programming environments support stateless programming well, but do not help with stateful operations. Take a user registration process, for example, one that consists of three steps:
Choose a username.
Enter personal details.
Perform registration.
Choosing a username that is not already in use is vital for the process as a whole. The user should be allowed to continue on to the second step only after she chooses an unused username. However, a stateless implementation of this process does not remember a user's past actions. So if the URL of the second step is easy to guess (e.g., register2.php), the user can type in the address and enter step 2 directly, giving as a parameter a username that has not been validated (and possibly choosing an existing username).
Depending on how the