Xebia Background Header Wave

Security testing is a whole profession on its own, which requires knowledge of niche tools, experience with various technologies, and a bit of destructive mindset. But it doesn’t mean security testing should be left only to the experts.

Today, we will show you how you can extend your functional testing knowledge to unveil the hidden vulnerabilities in your web application using nothing but your browser!

a person in a hoodie sitting in front of multiple monitors with green text over black screen
You won’t need an environment like this, but feel free to grab a hoodie if it will get you in the mood

A simple feature to test 

Let’s set the stage; imagine that you are supposed to test the following feature:  

Payment Confirmation Screen

As a user, I want to be able to enter my name and address details and confirm the provided payment amount.
Acceptance Criteria:
  • Confirmation shall not be possible if name or address is empty.
  • User shall not be able to change the payment amount.
  • If the user is a premium member, no shipment fee shall be added.
  • If the user is not a premium member, a 5 Euro shipment fee shall be added.
Out of scope:
  • Premium member registration
  • Payment amount calculation
  • Validation of name and address (they shall be accepted as long as they are not empty)

For testing, you will be provided with a screen where a predefined payment amount is filled, and the user is not a premium user. Calculation of the payment amount, premium member registration, and passing this data to the screen is already tested. 

Now, visit the exercise page if you haven’t already, think of which tests you would execute, try them out, and see if the implementation looks correct. 

If you have identified some potential security issues, congratulations! You already have a tester mindset where you don’t limit yourself with just validating the acceptance criteria. Continue reading to see if you have caught all hidden flaws. 

If you think that the implementation looked good, keep reading to start a new chapter in your testing approach!

 

Frontend and Backend; connected but independent 

When you focus on the user interface (UI), you can conclude that it satisfies all the provided acceptance criteria. You cannot submit the form with empty input, you cannot modify the payment amount, and there is no option to change the premium status. Everything is fine, right? Well, not really.

When working on a web application, a common fallacy is to consider frontend and backend as a whole, like inseparable parts of a single application. This mindset can affect testers to focus on end-to-end (E2E) tests, performing all the actions and verifications on the UI level.

However, frontend and backend are two independent components, only connected with APIs in between. While the backend is in a remote server, the frontend resides in the client’s machine (usually inside a browser). This brings up two problems:

  • The user can modify the frontend (not just the UI, but also the user scripts and local data)
  • The user can skip the UI altogether, and directly use the APIs.  

This is why a common rule of thumb is to “ensure that the backend validates every data it receives“. And that is also why, as testers, we need to ensure that this practice is being followed.

Let’s see what this means for our example.

Modifying the frontend

Most web browsers come with a set of developer tools which lets you peek behind the curtain. These tools can be used to inspect (and modify!) all elements of the frontend that resides in your computer.

In the examples we will use Chrome’s developer tools, you can refer to your own favourite browser’s documentation to achieve a similar effect. (see Safari, Firefox, Edge). You can usually open the developer tools by right clicking on any page and selecting “Inspect” or “Inspect Element”.

Is a required field really required? Or a read-only field read-only? 

If you have tried submitting the form with an empty name or an address, you have realized that the browser doesn’t allow you to do it. At first glance, the acceptance criteria appear to be satisfied. But is it really so?

Go back to the example page, and right click on the “Name” field, and click on “Inspect”. The developer tools window should open with the name field selected.

Double click on “required” attribute and just delete it. Now, you will see that you can submit the form with an empty name field.

You can do the same with the address field, and these are potential bugs for the system. On the other hand, it is not much of a security threat to be able to create an order with an invalid recipient. It would be even better if we could get some monetary gain.

For that, try inspecting the “paymentDue” field. You will see that it has a readonly attribute, which can be removed in a similar way. Or you can just update the hardcoded “value” attribute to something more affordable. In fact, you can even give negative values a try!

Frontend is more than the user interface 

Aside from the UI, frontend contains JavaScript, CSS, and various local storage options. You can take a look at the Sources tab in the developer tools and check the form-script.js file which contains the scripts used for this page. However, in most modern websites the scripts will be much larger and obfuscated, so they will not be as easy to understand and modify as the UI itself.

For this example, let’s have a look at the most (in)famous form of local storage: cookies. In the developer tools, go to the Application tab, and click on the entry under the Cookies section. It will list all the cookies from the site. Some of them might be confusing, but “isPremiumMember” looks interesting. Try setting its value to “true”, and submitting the form again.

If only becoming a premium member was this easy on all platforms!

You might be thinking that this is just a goofy little example, but I had personally come across a popular website where you could set the isAdmin flag to “true” in the cookies to have all the administrator rights!

Note that the change you make in the UI are temporary, and they will not be there after a refresh. The cookie on the other hand will be persistent until it expires, or gets overridden by the web page.

How about skipping the UI altogether? 

As we have mentioned, backend and front are independent, and connected to each other via APIs. In the developer tools, you can switch to the Network tab and observe the API call made when you submit the form.

Et voilà! All the parameters we were chasing are plainly available in the API call. You can call this API using a tool like Postman, or from your terminal with commands like cURL, and play freely with the parameters! 

Do we not need frontend validations then?

No! They are still important for user experience, and they should still be tested. However, they should not be the trusted to ensure security. In fact, the backend should always be responsible for validating and sanitizing the data it receives. 

Conclusion

As you’ve seen, security testing is not just for experts. With a bit of curiosity and a willingness to explore, you can uncover vulnerabilities in web applications using nothing more than your browser and its developer tools.

So, what are you waiting for? Start practicing your security testing skills today! Visit the visit the exercise page (or in fact any other web site), experiment with the frontend and backend, and see how far you can push the boundaries.

Remember, security is an ongoing process, not a one-time event. Keep practicing, learning, and sharing your findings to help make the web a safer place for everyone.

And meanwhile, don’t hesitate to reach out to us if you want to improve your testing approach, or improve the security of your system with the help of our domain experts!

Questions?

Get in touch with us to learn more about the subject and related solutions

Explore related posts