Basic security testing of website input fields – Look for lack of input limitations

, ,

If a website has an input field that lacks any kind of limitations on the input then you don’t need to know how a hacker might use this to gain access to the system, you only need to know that a hacker can.

Years ago I was testing a web application and found that for a particular input-field, used to enter a name of an object, I could send in at least a gigabyte of data. I knew that this could potentially be a problem and shared my concerns with the developer sitting next to me. He lighted up and suggested me to send in a simple popup-script to see if the product was possibly vulnerable to script or XSS-attacks but when I tried it in the input field nothing happened. But when I tried it in the input field below the first one I got a popup showing that the system was wide open for attack. This incident taught me that I don´t need to know exactly how hackers can gain access to a system to learn how to spot the security holes.

The lesson was reinforced when I was performing a lecture on security testing. I shared a simple XSS script with my students together with the experience I mentioned above. One of my students started to google “Order here” and went to the first web shops on the list. and entered the script into the first search field he could find. Ten minutes after having been presented with the script he had found out that one of the biggest sites for purchasing academic literature in Sweden was vulnerable for at least Reflective XSS attacks but the possibility for more serious Stored XSS or other types of script attacks should be investigated. I tested the search field some more; Did they have any limitation on the length of the book name to search for? Well, at least no limitations up to a million characters (I simply stopped testing longer strings at that point). Conclusion: The site that did not have any limitation on the input was also the one which had an obvious security risk and potentially open to XSS attacks.

I reported this to the site by sending the information to their customer support (they lacked any other way of getting in touch with them). After a couple of months, the site was patched and I could no longer execute that script. Today, however, over a year after I had reported the security hole, I tried another variant of a script intended to reveal XSS vulnerabilities and managed to get a pop-up alerting me that the site was still open for attacks. Even though there are lists of these scripts that one can simply follow and copy paste into an input field, far from every site bothers to tests this and thus expose themselves for attacks. This taught me that if an input field lacks basic limitations on input then I should look deeper for more issues that can affect security.

So what basic security tests can you perform on a Web site input field?

1)   Test how many characters you can enter and check if there is a reasonable limitation. For example, if you have an input field where you can enter your first name you probably do not need more than 16 characters (for a lot of other types of input fields that a number of chars can, of course, be too limiting). If you are allowed to enter a million you should raise concerns. A very useful tool to check the possible number of characters that can be entered is using a counterstring (you can read more about it here: http://www.satisfice.com/blog/archives/22). In a counterstring you can see exactly the position of any given character has inside the string.

Lacking input restriction might be a sign of other security checks missing but can also be specifically used by hackers. An intruder might try to send in great amounts of data and hope that the system crashes and either grant administrator/root access or reveals unintended information. If the system is not properly setup it might reveal information such as server or database names or ip:s that the hacker can connect directly to.

By restricting the number characters it also limits the type of scripts that an attacker can use.

Couterstring in a search field
Using a counterstring I can see that I can enter 524288 characters for doing a simple search which is the default length for a for html input tag. Performing the search will result in an error that input is too long which is a little bit curious.

2)   Test if there is a limitation of possible characters. Again, if you have an input field for entering a name you probably don’t need strange characters such as “<>/\;,!”. These characters are used when sending scripts into the input field and if they are blocked it will make it more difficult for an attacker.

Possible to enter special characters
These characters will probably not be used by an actual user but might be used to send in scripts.


3)   Check if XSS attack scripts are possible to execute. Check OWASP’s excellent collection of scripts: https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet. Simply copy the scripts into your input field and if they result in a popup, you have a problem. You don’t necessarily need to understand exactly how the scripts can be used to breach the system, only that a hacker can potentially use that hole. You can read more about XSS at https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)

Popup when entering a script into the search field
This pop up came after entering a script into a search field thus showing the site is at least vulnerable to Reflective XSS attacks. In this particular case I am actually not sending in the text “XSS” but I’m sending in code that translates numbers to ASCII text. Several other types of scripts are blocked but obviously there are holes.

4)   Make sure the checks on input fields are not only located on the client side but also on the server side. If the checks are done locally on the attacker’s’ computer before sending the message to the server, the hacker can bypass those checks by sending a direct and unfiltered message to the server. An excellent tool to make this kind of test for web pages is Fiddler. Using it you can manipulate the HTTP message sent to the server and then check on the server if the message was filtered or rejected.

5)   Using Fiddler, I would also recommend making sure that encryption is always enabled. You don’t need to understand how a hacker might sniff traffic and use the data sent, you only need to understand that a determined hacker might use it for something evil.

6)   If the site uses any type of SQL-database you might want to read up on SQL-injection and how to prevent them: https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet.

7) Check that if you are sending in data that the communication is encrypted. You don´t need to know exactly how an attacker can use personal information that is picked up in an unsecured network, you just need to know that it can be used against a person. An easy check to do is to simply look at the address bar, making sure the page is using HTTPS. Using HTTPS does not provide complete security of course but it is one piece of the puzzle making it more difficult for an attacker.

Https enabled
This particular page is encrypted using HTTPS thus making it harder for an attacker to listen in on.

8)   Make sure that the site administrator can be directly contacted so he or she can act swiftly if someone spots a security issue. If there is no way to contact anyone responsible for the site then a friendly person who spots something potentially serious might just give up and let it be, leaving the security hole open.


The steps above can be done by any tester, even with limited experience, and can prevent several basic attacks. But the steps will not guarantee good enough security and there is a lot more things to test. What I have described should be considered the bare minimum of what you should test and if your system is critical in any way you might need a security expert to analyse the system. For a more complete picture of security risks and how to mitigate them, I strongly recommend reading more at https://www.owasp.org.

To investigate and look for lack of limitations is of course not limited to input fields for websites. You have similar issues with desktop apps and generally everywhere where you can add something into a program. An attacker can exploit limitless inputs to create memory or storage problems to gain access to the system. Inputs in desktop or mobile apps might need slightly different testing but are not necessarily less important from a security perspective.

And again remember that you don’t necessarily need to understand exactly how an attacker can breach a system if you understand that lack of limitations on inputs can be a way in.

Update 2016-02-02 – I have updated with the correct naming of the Reflective XSS vulnerability I made an example of. Thanks for pointing it out Jari!


Checking as an enabler for testing


You have waited a long time for this and finally you get software to test from development. Energized and excited you install the program and fire it up. It all looks great, the new interface is stunning. You are ready to beat the crap out of this software. So you roll up you sleeves and hit the first soft button. The screen turns blue. Not that exited any more, a bit pissed off is a better word of how you feel right now. So you put on your friendly face and walk back to the developers, explaining what happened and kindly asking them to fix this problem.Now, back at your desk waiting and waiting and suddenly a new version of the software is released. Wohooo you shout, time to get busy. Installation works great and it fires up, now the shivering moment arrives, you hit the same soft button and it takes you just where you expected it, to the registration page. Great, the devs have done a fine job! Now I can type in my contacts to register. But there is alway a but, I can’t type anything into the input fields, WTF!!! Have you ever been into a similar situation? I sure have a couple of them in my pocket. Isn’t it frustrating when you just have to gently poke at a software and it falls apart? You never come to the point where you actually can practice your testing skills because the bugs just pop up in your face without you doing anything in particular. Why does this happen?

Most of the time it is because there is a lack of checking the software before you are expected to test it.
Michael Bolton wrote a series of wonderful posts about testing vs. checking.
I think this is an important distinction to make and it has served me very well rhetorically when discussing and describing its different purposes and how it brings different values.
However, I see tendencies that some look down on checking and it is not as “fancy” as testing, it is second class.
This however does not serve us good. There is no point in comparing which is “best” since it is not a competition. It is not that if you do testing you do not need checking or (as some agile folks seem to believe) that if you do checking you do not need testing. If you believe so then you have misunderstood the whole concept and I strongly recommend you to go back and read Michaels blog posts very carefully. So checking is an activity that is algorithmic and can be automated, the verdict is pass or fail. Its purpose is to confirm that what we already know about that specific part/function/scenario still is true.  With checking we want to make sure that what previously worked in the product still works. Testing however, is a heuristic based sapient activity. It is exploration, learning and evaluation of a product and our motive for testing is to find new information. We ask new questions to the product to uncover the unknown. So what I mean by checking as an enabler for testing is that we need checks to inform us that our existing believes of the product are still intact. When we have that information we can start testing, that is go further then we did last time by starting at the point we previously stopped at. Checking provides us with a solid foundation to stand on that will give us confidence to start testing.

But we should put checking where it belongs, that is where it provides most value. Most often that is as close in time to the developed code as possible to provide fast feedback. It is developers who often can do this cheapest and at the same time benefit the most from having frequent and rapid checking of their code. There are some really good practices out there that includes checks, like TDD (Test Driven Development), BDD (Behavior Driven Development) and others. What bothers me is when I see testers being requested to do these checks instead of doing testing. These practices are not testing practices, they are development practices. Checking is only one of the benefit with them. When you put a tester to do this task then you tend to loose all the other good and valuable benefits of the practice. Benefits such as knowing when to start coding and when to stop coding, clean and simple design, fast feedback to developer about the code, confidence for the developer to continue coding, improved developer ownership of quality of the code, keeping short iterations with new code before running checks and many more values. Why would someone want to take all that away from the team by putting the tester to do the checks?
When developers do this I very seldom encounter the scenario I described at the beginning. This saves the whole project a lot of time and it keeps stability to ensure the development moving forward. It also keeps a lot of frustration away from the team.
To conclude this, don’t look down on checking. Checking is a very important activity but it is not necessarily most beneficial to put testers to perform this. Use checking as an enabler for testing!


Using an External Test Team

, , ,

An objection that we have heard to using an external test team, especially in an agile setup, is that since the developers do most or all of the testing now, they would lose a valuable experience and a chance to learn if the test is outsourced to an external team.

The way I see it, there are a couple of fallacies in this concern. First of all, even though there usually is a higher level of developer tests in agile, these tests are not a substitute for manual tests, they are a complement. Second, if the developers learn from their own testing, they are less likely to find new points of views; they’ll learn, but mainly within their existing box.

Regarding the developer tests; these are to a large extent automated white box tests that the developer or continuous integration system run as an integrated part of the check-in and release process. These tests are invaluable for two reasons, they give early feedback to the developers and they can test things that are not possible with black box testing. However, these tests cannot replace the analytical and exploratory skills of a human tester. The developers tests are great at weeding out bugs that potentially would waste the time of a human tester, which allows the tester to focus on much more complicated tests and harder to find bugs. A symbiosis of automated developer tests and human analytical and exploratory tests brings the best of two worlds together.

When talking about learning and education, there are a couple of benefits of bringing in external testers. We are all limited to look for bugs in areas and situation that we can imagine would happen. This also applies to developers and relying on only developers for testing will bias the testing towards the areas and situations they think of. IF working with an external team of testers, another point of view is added and more areas and situations will be covered. When bugs are found, developers and testers can have a dialog about them and the developers can learn to see new areas and situations.

Tools can to some extent also bring in a new perspective and find bugs in areas where developers are not looking. However, most tools need to be configured and if this configuration is done by the developers, there is still a risk that the tool will biased towards the point of view of the developers. Also, a tool cannot have a dialog with the developers about the thought process behind a bug, limiting the understanding and learning that can be made from bugs a tool finds.

Finally, by bringing testers into the picture and take some of the testing job off the developers, time will be freed up for the developers. This time can  be used for training that will help the developers prevent bugs, not just fixing them.