• Stars
    star
    306
  • Rank 135,625 (Top 3 %)
  • Language
    HTML
  • License
    GNU General Publi...
  • Created over 6 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Stealing CSRF tokens with CSS injection (without iFrames)

Stealing CSRF tokens with CSS injection (without iFrames)

A post here details a method for stealing sensitive data with CSS injection by using Attribute Selectors and iFrames. Because this method requires iFrames, and most major websites disallow being framed, this attack isn't always practical.

Here I'll detail here a way to do this without iFrames, effectively stealing a CSRF token in about 10 seconds.

Once the CSRF token is stolen, because the victim is already on an attacker website, the attacker can go ahead and complete a CSRF attack against the user.

Background

As the original post describes, CSS attribute selectors developers to select elements based on substring matches of the value of attribute tags. These value selectors can do one of three things

  • Match if the string starts with the substring
  • Match if the string ends with the substring
  • Match if the string contains the substring anywhere

One practical use case for this is to color all href attributes that start with "https://example.com" a special color.

An unfortunate by-product of this is, sensitive information can sometimes be stored in html attribute values. Most often, CSRF tokens are stored this way: in value attributes on hidden forms.

This allows us to match CSS selectors to the attributes on the form in question, and based on whether the form matches the starting string, load an extrenal resource such as a background image, which signals to the attacker the first charecter.

Using this method, they can walk down the string, and exfiltrate the entire secret value.

To pull this off, the victim server needs to allow or be vulnerable to arbitrary CSS being rendered. This can occur through CSS injection, or a feature on the website allowing you to include stylesheets. Note: the website does not need to be vulnerable to XSS.

To render the victim's CSS, the original paper proposes using iFrames. The limitations of this are of course if the victim website disallows being framed.

There is also a space/time tradeoff of either loading all possible charecters at once in paralell, or multiplexing them one at a time. In my example to save time, I've elected to load them all at once. In some senarios where the injection is small, multiplexing may prove to be the more viable option.

Without iFrames

To do this without iFrames, I've used a method similiar to one I've discussed before: I'll create a popup and then alter the location of the popup after a set timer.

Using this method, I can still load the victim's CSS, but I no longer depend on the victim being frameable. Because the initial pop-up is triggered via user event, I am not blocked by the browser.

To force a hard reload, I have the pop-up load a dummy window between CSS injections. This can be seen below

var win2 = window.open('https://security.love/anything', 'f', "top=100000,left=100000,menubar=1,resizable=1,width=1,height=1")
var win2 = window.open(`https://security.love/cssInjection/victim.html?injection=${css}`, 'f', "top=100000,left=100000,menubar=1,resizable=1,width=1,height=1")

Without a backend server

The original paper describes exfiltrating data to a backend server, however becuase the CSRF is a client side attack, if we can come up with a way to do this without a server, we save a lot of overhead and complexity.

In order to recieve the victim's resource loads client side, we can make use of Service Workers, which can intercept and read request data. Service Workers currently only apply to requests coming in from the Same Origin, and so for my demo I've cheated and put both the victim and attacker pages on the same origin.

Soon though, chrome may merge in this experimental feature which allows cross origin requests to be intercepted by service workers.

With this addition, we can make our attack 100% client side, and force users to perform CSRF actions in under 10 seconds of clicking the link, as seen in the demo below:

Demo

As explained above, becuase I don't want to run a web server (github pages is great) I'm cheating and using service workers to intercept and mock the server side component. As a result, for now, this demo only works in Chrome.

First I've created a very simple victim, that has a DOM based CSS injection, and placed a sensitive token on the page. I've made this DOM based to again, remove the need for a server. You may notice I've also included some protection against script tag injection, by encoding less than and greater than signs.

    <form action="https://security.love" id="sensitiveForm">
        <input type="hidden" id="secret" name="secret" value="dJ7cwON4BMyQi3Nrq26i">
    </form>
    <script src="mockingTheBackend.js"></script>
    <script>
        var fragment = decodeURIComponent(window.location.href.split("?injection=")[1]);
        var htmlEncode = fragment.replace(/</g,"&lt;").replace(/>/g,"&gt;");
        document.write("<style>" + htmlEncode + "</style>");
    </script>

Next, our attacker forces a load of the victim's CSS, and using the method described above, we steal the sensitive token one charecter at a time.

On the recieving end, I've defined a service worker that intercepts the requests, and sends them back to the domain via post-message, and then we store the token in local storage for future use. You can imagine a back end web server filling this function, and posting back the CSRF token to the attacker domain via web socket or polling.

ONLY TESTED IN CHROME RIGHT NOW:

demo

If everything works, after clicking somewhere on the page, you should see the CSRF token exfiltrated one charecter at a time from the victim page.

Final thoughts

Interestingly enough, reflected CSS injection is actually more deadly than stored CSS injection, because stored CSS injection would require a server to update the CSS for the victim before rendering.

For some time CSS injection has gone back and forth on severity. It used to be IE allowed users to execute Javascript in CSS. This demo hopefully shows that CSS injection, and rendering untrusted CSS on your domain can still lead to serious security vulnerabilities

More Repositories

1

Pastejacking

A demo of overriding what's in a person's clipboard
HTML
1,419
star
2

WPA2-HalfHandshake-Crack

This is a POC to show it is possible to capture enough of a handshake with a user from a fake AP to crack a WPA2 network without knowing the passphrase of the actual AP.
Python
545
star
3

Snapper

A security tool for grabbing screenshots of many web hosts
Python
290
star
4

truffleHogRegexes

These are the regexes that power truffleHog
Python
192
star
5

gcploit

These are tools we released with our 2020 defcon/blackhat talk https://www.youtube.com/watch?v=Ml09R38jpok
Python
155
star
6

XSSJacking

Abusing Self-XSS and Clickjacking to trigger XSS
HTML
126
star
7

windowHijacking

A demo of altering an opened tab after a timer
HTML
125
star
8

AttackingAndDefendingTheGCPMetadataAPI

This repo gives an overview of some GCP metadata API attack and defend patterns
78
star
9

Damn-Vulnerable-Redis-Container

An example of obtaining RCE via Redis and CSRF
HTML
74
star
10

XSSOauthPersistence

Maintaining account persistence via XSS and Oauth
JavaScript
69
star
11

whatsinmyredis

A CSRF demonstration of stealing local Redis data, and encrypting all Redis instances on a local network
CSS
53
star
12

inputProtectionShield

Eagle
42
star
13

CORS

JSON API's Are Automatically Protected Against CSRF, And Google Almost Took It Away.
34
star
14

CSRF-PoC-Genorator

This is a simple CSRF Proof of Concept generator that supports multiple form encodings and methods
HTML
28
star
15

mimikittenz4Linux

Steals cleartext passwords from webservices, by reading the memory of browsers
Python
27
star
16

santaHog

Scans packages in npm and pypi for secrets
Python
27
star
17

clientHashing

A demonstration of secure hashing done client side
JavaScript
22
star
18

bygonessl

A tool to discover bygonessl vulnerabilities using the facebook API
Python
19
star
19

logger

Simple javascript logging of fingerprint, IP address and user agent
JavaScript
17
star
20

SmartHealthCardViewer

Smart Health Card Viewer, view your California Smart Health Card Vaccination record
JavaScript
8
star
21

BitRush

An open source project for bitcoin mining on an FPGA
VHDL
7
star
22

domainAbandonedDetector

Detects abandoned domains referenced in HTML
Python
7
star
23

dxa4481.github.io

This is my resume, in HTML/CSS
Python
6
star
24

JayPi

Translating JTAGENUM to Python for the Raspberry Pi
Python
6
star
25

redirect_demo

HTML
6
star
26

gpsIoTTracker

This simple python module takes GPS locations of a moving object, and measured signal strengths of an IoT object and uses trilateration and the method of least squares to solve for the location of the object
Python
5
star
27

Veyebrations

We are creating a system that translates measured distances of physical objects into vibrations to assist the blind
Eagle
4
star
28

JohnWilliams

JavaScript
4
star
29

coolSVGXSS

simple demo of XSS in an SVG
HTML
4
star
30

security_reports

A simple template that can be used to deliver security reports either for bug bounties, internal reports, or consultancy work
HTML
4
star
31

penguin

A restful single page app tool sharing application
Python
3
star
32

VibrationAPI

An example of the HTML5 vibration API
HTML
2
star
33

Tutorials

Learning new things
JavaScript
2
star
34

dotGitFinder

JavaScript
2
star
35

HIVStats

This application makes HIV statistics very accessible
HTML
2
star
36

log_handler

The backend log handler for logger.io
JavaScript
2
star
37

SocialEngineeringPresentation

A simple presentation on social engineering
HTML
2
star
38

SoundMaker

This uses the open hardware provided by arduino to modify an arduino PCB into making a sound board
Eagle
1
star
39

fingerprint-page-count

Counts how many times a user has viewed a page based on his browser's fingerprint
JavaScript
1
star
40

blog

HTML
1
star
41

SeriousApiarist

Controlled builds, tests, static analysis, releases, and deploys with validation and 2FA and live streaming to your CI
Go
1
star
42

serverConfigs

The server configuration files for security.love and e-q.pw
1
star
43

serviceworkerCSRFLogout

HTML
1
star
44

insecureLamp

a very simple insecure web application designed to turn a lamp on and off
Python
1
star
45

FingerprintPressure

This simple demo shows given an image of a fingerprint, you can determine how hard the person was pushing down
Python
1
star
46

AccelerometerAPI

A brief demonstration showing browsers can access a device's accelerator data without promoting a user. This app shows the total acceleration vector magnitude
HTML
1
star
47

CORS-pdf

This is a simple demo that shows you can host a PDF cross origin in chrome, and track a user's interaction with the PDF with the default chrome PDF viewer.
HTML
1
star