Thursday, February 23, 2017

HTTP GET vs. POST in HTML Forms - Security Considerations Explained with a Sample

This blog post explains security considerations when using HTTP GET as the request method compared to HTTP POST. Here for accessing the form’s data posted to the server, I use a PHP file for demonstration, but you can use any other technology (JSP, ASP.NET etc.).

Here I have a simple login page written in HTML.


This is the sample source code of login.html file.

<html>
   <head>
      <title>login page</title>
   </head>

   <h1>Welcome to My Site !</h1>

   <form action="validateuser.php" method="get">
      Username : <input type="text" id="username" name="username"/>
      <br>
      Password : <input type="password" id="password" name="password"/>
      <br>
      <input type="submit" value="login"/>      
   </form>
<html>

When you click the login button, the browser will redirect you to the web page/URL defined in the action of the HTML form. In this sample, I have a PHP file named validateuser.php and both the login page and this file are deployed in apache web server.

In the HTML form of the login page, the method is defined as get.
Therefore, in the validateuser.php file also we need to access the form data using $_GET[‘parameter name’].

This is the sample source code of validateuser.php file.

<?php

   $username = $_GET["username"];
   $password = $_GET["password"];

   //perform authentication

?>

Now enter some value for username and password and click the login button.

Browser will redirect to the validateuser.php page. However, since the HTML form’s method was defined as get, all the form’s data (here username and password) will be added as query parameters in the URL.

The risk here is, the URLs users request from the server (here Apache web server) are printed in the access logs of the server. Therefore, anybody having access to the filesystem of the web server would see the query parameters in the URLs printed in the log file. (By default in linux operating system, if you install apache server, the logs are added to the /var/logs/apache2/access.log file)


Therefore it is not recommended to use HTTP GET method when you need to send sensitive data in the request.

Now let’s do a small modification to the login page and set the method to post.

<html>
   <head>
      <title>login page</title>
   </head>

   <h1>Welcome to My Site !</h1>

   <form action="validateuser.php" method="post">
      Username : <input type="text" id="username" name="username"/>
      <br>
      Password : <input type="password" id="password" name="password"/>
      <br>
      <input type="submit" value="login"/>      
   </form>
<html>

In the validateuser.php file I retrieve the HTML form’s data using $_POST[“parameter name”].

Here’s the source code of validateuser.php file.

<?php

   $username = $_POST["username"];
   $password = $_POST["password"];

   //perform authentication

?>

Now if you fill the form in the login page and click the button, data (username and password) will not be added to the URL as query parameters, but will be included in the body of the request.


If you check the web server logs, you can’t see the form data in the request.


Therefore, if your HTML web form sends sensitive information when the form is submitted, it is recommended to use HTTP POST method so that the data will not be sent to the server in the URL as query parameters.


Tharindu Edirisinghe (a.k.a thariyarox)
Independent Security Researcher

No comments:

Post a Comment