A look at the HTML source code behind Web sites can often reveal security issues that would never be uncovered by those blissfully ignorant of the code. This bug report will examine two common methods of maintaining state and passing data in Web-based systems–hidden form fields and the HTTP GET method–and demonstrate some of the associated security risks through an examination of HTML code.
A look at the html source code behind Web sites can often reveal security issues that would never be uncovered by those blissfully ignorant of the code. This bug report will examine two common methods of maintaining state and passing data in Web-based systems—hidden form fields and the HTTP GET method—and demonstrate some of the associated security risks through an examination of HTML code.
Security Risks in Hidden Form Fields
An HTML form allows a Web site user to provide input to the Web server/system via the ubiquitous text field, list box, radio list, check box, and other elements. Many e-commerce systems require the user to fill out multiple forms, one after another, to complete a purchase. Typically, this is done for usability and pageload time concerns. Placing all of the input fields on one page makes the form daunting. Additionally, the HTML code for that single form is then quite large, resulting in long page-load times for those impatient Web users.
Since HTTP connections are stateless, something must be done to maintain state—keep track of user information or order information, for example—among the multiple forms. Cookies are one option. Another option is hidden form fields—hidden text fields that contain state-related data. These hidden text fields are not displayed in the browser's GUI, but the information they contain is sent to the Web server when the form is submitted. (The HTTP POST method is what accomplishes this.)
Let's consider a real-world example to clarify the hidden form field concept. I recently tested a Web-based system that sold individual songs you could purchase for a small fee and download to your PC. (The exact nature of the system was somewhat different, but I need to disguise it for client confidentiality purposes.) A sequence of three forms had to be completed in order to make a purchase.
The first form contained a Java search applet that allowed you to browse the available songs by category—jazz, rock, classical, etc. Upon finding the song you wanted, you would select it and click the Purchase button to proceed to the second form. The second form displayed the details of the song you chose and required you to enter your credit card and contact information. The third and final form allowed you to review your selection and the credit card/contact information for correctness before committing to the purchase.
While testing the system, I selected the song "In the Mood" on the first form my browser's cookie option set to prompt me, but was not prompted to accept or reject a cookie. Since this signaled the site wasn't using cookies, I guessed that hidden form fields were being used to "remember" the song I had selected. To test this hypothesis, I brought up the HTML source code for the second form using the View Source in my browser. I was using IE, so the code came up in the Windows Notepad. I used the Find function in Notepad to search for the word “hidden” and found the block of code in Figure 1.
This registration form, accessed with the edited link, allowed me to register for the event at a $1 price, instead of the proper $20.
A question similar to that asked in the hidden form field situation can be asked here: Why did the Web site encode vital and sensitive pricing information in the link? A better design would have the link transmit only the event ID, like https://somedomain.com/events/signup.cgi?evtdbid=304.
Then, the server-side script could access the server-side database to pull the event name, date, time, and cost information. Why send all of this information