I have read a couple of books recently about different vulnerabilities in order to be able to better protect my projects/websites. Today, I want to share a story about how I managed to use this knowledge in practice.
This material is posted for educational purposes only. The author is not responsible for its usage by other Hackread visitors. The company was notified in advance of 48 hours of the vulnerability and already received enough data to fix it. All vulnerabilities are now fixed.
How it all began
It was quite an ordinary day. I finished several work tasks and made myself a cup of coffee. At the same time, I decided to read one article about trading strategies. I wanted to create my own trading bot. In the column to the right of the article, several other articles and ads were displayed.
I do not remember what exactly made me click the advertisement and visit that site, but when I opened it, I noticed one interesting feature. The link led to the landing page with a registration form and one field was already filled in – the promotional code. Please forgive me for not sharing the exact website URL. So, I compared the promo code that was in the input field with the one in the address bar. They were completely the same.
What can we do about it?
Obvious and trite – we may try to change it. If the promo code gets compared with its corresponding value in the database, we will see an error message with a high probability. But when I changed the input, there was no request to the server. It turned out that the input is checked only when you press the registration button.
So, seems it is possible to do something more interesting. I changed my promo code right in the address bar. I found that I could change the values of the input field using the address link.
The next step was to look at the HTML code. The web browser lets us make a right mouse click on the input field and inspect the item code.
It became immediately clear that I could change the value of the input field. I tried adding a weblink. For this, I just changed the link in the address bar and it also changed the page content. Result: I found an XSS vulnerability.
So, what is next?
I thought it was worth digging deeper. Inserting weblinks is somehow trivial and not interesting. I tried to insert a new block and add an image. What was needed for this? Just the same – change the URL. I do not think it is necessary to describe HTML and CSS.
I also noticed that the same way the site accepts third-party js-scripts: both through a third-party source and by direct typing the code, however, in the second case, Google Chrome automatically detects XSS and renders the error page instead of the service page.
How to exploit this vulnerability
Everything is simple. You can start with collecting data from all new users, and finish with phishing sites and using someone else’s account as your own. You can replace all links on the page with your own or replace the input form. You can make all new users to be your referrals. And of course, you can substitute the request to the server from the form so that it does not check the promotional code.
What the developers forgot to do
It is also very simple. They forgot to validate user inputs. SQL injections do not work there, the service uses WordPress, and it, in turn, processes all incoming lines.
Therefore, we can:
- When rendering the page, check whether the promo code corresponds to the one in the database. It is slow and not always justified.
- Run new promo codes through regular expression like /^[A-Z0-9]+$/. It will help validate values and protect against vulnerabilities. And it works faster than a request to the database. And the effect is the same – XSS is removed.
I wanted to show this situation to the owners of the service and, ideally, to receive a reward. The company, by the way, is not big and does not have any bug bounty program. The owners of the service were notified about their security problems. I had been negotiating via email and LinkedIn with those who are at least somehow involved in the development. All the conversations came to:
“Please tell us how you did it, but we, of course, will not pay for the vulnerabilities.”
Please do not think that they completely refused to pay. Instead, they offered their services for free. But I refused to get this type of payment because I am not actually interested in anything they offer now.
I hope each programmer will validate all input data and will not forget about the Query String. And I also hope that the article will help someone to notice such a problem with his site in advance and fix it.