Application Security : What is server side input validation? Why is it needed anyway?

TL;DR Don’t rely on client side input validation. Data sent from client side can be manipulated in many way beating any validation checks. The same input validation must be performed on the server side!

Most of the time when the development team receives penetration testing report, they may keep seeing the following words among the phrases:

  • .. Stored XSS ..
  • …. Cross Site Scripting XSS …..
  • … perform server side input validation ….
  • weak input validation 

Normally, by the time the report reaches to the development team hands, the timeline is already too tight and the roll-out deadline is imminent. Thus, the frustration ensued upon receipt of pentest report with lots of issues. So, some rephrased version of frustrated development team responses tend to be:

“I have developed the functionally correct application according to the application requirements but why does the penetration testing report keep coming back with a lot of issues?”.
There are input validation in place! How can this happen? Can you show me how you performed the testing?

Some rephrased version of project manager response tend to be:

I saw similar issues in previous phases. Why is the same issue happening again?

Thus, the main focus is this article is to help developer aware of the basic security testing approach so that to demystify the “hacking” of application in typical penetration testing. Let’s go through with a sample application.

A simple form submission application:

The following is very simple form submission application as follow:

  1. user needs to enter username and identification number
  2. upon submission, client side javascript will validate the username and identification number format. If validation fails, the submission will not proceed.
  3. after successful client side validation, the form will be submitted and the server will return welcome page with username and identification number value that was supplied by the user, without performing server side validation.
Simple Form Submission Page
User greeted by the welcome page after successful submission

So, the input validation has been performed according to business need. The functionality is correct. So, there should be no security issue right? The answer, unfortunately, is that there is security issues with this application.

The data transmission flow

Let’s take a look at the typical data flow in web application. Please refer to diagram below. So, for the sane people, the users will just access the application via browser and submit the form. The form data will go through the network. Subsequently, the data will hit the server and server would return the appropriate response (return flow is not shown in the diagram). In this context, it is reasonable to assume that client side javascript will help prevent invalid/dangerous data sending to the server.

The typical flow without any kind of interception
The javascript username validation rule prevents user from submitting the form against the rule
.It is likewise for the identification number
Users are forced to submitted correct data through the interface
Proper functioning welcome page with correct data

Looking under the hood

So here is the simple code snipper for this application. The front end was built with html/javascript powered by python flask backend.

Simple html front end code accepting the username and identification number
client side javascript rule to validate the user input
Server side code trusting the client side validation completely and not bothering to do additional “server side input validation”

But the people are insane!

So, unreasonable malicious user can change the data flow completely and bypass the validation checks. Now, look at the new data flow in the diagram below. A proxy tool can easily intercept/replay the HTTP Request and javascript deterrence is a mere minor inconvenience. I used the BrupSuite free proxy tool to intercept the traffic. There are many other active proxy tools out there which can change request data on the fly such as Zed Attack etc.

Contrary to how sane people should use the application, the insane people would go and put in a proxy between the data flow and start to manipulate
Step 1: The browser traffic is configured to redirect to proxy hosted at port 8080
Step 2: We submit the data normally adhering to validation rules dictated by client side javascript
Step 3: Due to proxy sitting between browser and the server, the raw traffic can be seen in proxy log
Step 4: From the raw traffic, change the affected variable to malicious value. Our javascript validation cannot be helpful here anymore. Client side javascript check no longer in control!
Step 5: The server unknowingly accept the client data, not bothering to do “server side input validation” and populate the page. Thus resulting in unintended behavior (eg. Website defacement, Phishing, XSS .. you name it)
Could it have been prevented if the value were validate again on the server side (flask python backend?) Yes! This is the sole reason why the pentest report recommendation tend to state “perform Server Side input validation”

Sample Fix : Performing Server Side Input Validation!

Now, let’s do same rule of input validation on the server side!.

Fixed Step 1: Now we say goodbye to the old code (line number 12–16). We introduce server side input validation check again (line number 24–28)
Fixed Step 2: Now we try to do some naughty thing with our proxy
Fixed Step 3: The server has full power! No longer allow naughty step to be done proxy and such tools. Now, the server side validation in place!

Conclusion

Let’s say that client side validation or javascript validation is just to deter casual sane user from abusing the application and also to promote a form of usability of the application. Malicious hackers or our well-intention penetration testers do not really concern with the input restriction enforced through client side in terms of UI restriction and validation. They see the application through different lens. I hope the very basic explanation on the testing approach will demystify the “hacking” process.

Code Securely and stay safe! It’s an insane world out there :D

Check the github page here for sample application code.