CSS injection + open redirect bug bounty writeup - By pomitly

tldr;

An annoyingish attack chain to get css injection + open redirect + a cool ZWSP trick to fail login

The target

As this was a private invite, I cant due to policy state the name of the program. What I can say was that it was a fortune company in the vacation industry. The site I was targeting was in charge of handling the login for all general staff for this company.

Step 1 - finding the open redirect

This step was the easiest of the bunch, I found it as just as you would any other open redirect. There was a parameter in the url named something like: error_url=. To which - though normally set back onto the site - an attacker can change to any website. The issue with this is that an it only fires IF an error occurs with the login process. That is were the next bug comes into play

Step 2 - forcing an error

Though an error does trigger if the user enters incorrect credentials onto the website, this is unlikely to occur, and such is a pretty useless finding. There was open other parameter though in the url that caught my eye: username=. Though this would usually be harmless under normal curcumstances - all it does is automaticly embed whatever username you put in there as the user in the login parameter - we can use it to our advantage here.

Remember how the last bug, the open redirect, only triggers during errors? What I though to do was to FORCE an error through embeding the users expected username with... basicly nothing. Or so it would appear. One cool thing about unicode, is that it offers a very wide veriety of characters to choice from, one of which being the zero width space. View one at https://unicode-explorer.com/c/200B. Its ID, for those who care, is U+200B.

Using this zero width space we can inject it into the username= parameter and FORCE the login to error out every time. Say we are sending this exploit email to a user named carlos. We would send them a url with the username=carlos. Now when they go to login, there username is embedded and appears exactly the same to them, but the server itself recognizes it as distinct and gives you an incorrect login error every time.

Chain that with the formerly useless open redirect, and now we have a good open redirect at the login page.

Step 3 - increasing exploit believability and impact with css injection.

The issue with the 2 exploits above is that it gives the user no reason to understand WHY they are being redirected. As such they could very well deside that the redirect is illegitimate and not actually continue on filling out there credentials at our phishing site we have redirected them onto.

That is were css injection comes into play. Though css injection is many times diregarded as useless, what interesting thing you can do with css is desplay text. Take the following poc for example:

const style = document.createElement('style'); style.id = 'poc-css-test'; style.textContent = ` .error.bad-login { display: none !important; } #usernameField::after { content: "Due to updates, the login page is being temporarly migrated to attacker.com. Redirecting now..."; } `; document.head.appendChild(style);

As you can see with just native css, one can display text on a page. The issue is, from the raw url there didnt appear to be any place to inject my css into.

Thankfully, I did a little more digging and came across something very interesting. Within the js on the site, another parameter was mentioned to be enabled, and yet not used by default... and its name was css=. This was basicly a gold mine for me, as it allowed me to input any attacke, and it would load on the site!

Chaining all the exploits together, one can send over a link to the company login page that: - redirects users to an attacker phishing page - before redirecting let the user know about the redirection, one can put any pretext they want here

What I learned:

- even the most random knowledge can be helpful in web hacking, like the zero width spaces - investigate page js well for hidden values, they can be very useful - the company I report to doesnt take client side bugs :(