Cross-site scripting (XSS)

An XSS attack is when malicious code runs in your codebase without your knowledge. These attacks can gain access to sensitive data, such as passwords or tokens. They can also be used to gain access to a database or gain admin access in a system.

Cross-site scripting attacks can be performed both on the server and in the browser.

Forms of attack

Unsanitised user input

Attackers can use unsanitised forms to sneak code into a codebase. Inputs allow users to send code to an application. The system can potentially execute the code if it has not stripped it out.

If a backend application executes SQL statements send via an input, it could expose sensitive data or perform destructive actions.

Frontend applications with user-generated content are potentially vulnerable to XSS attacks. JavaScript can read data from localStorage or insecure cookies. If the application stores sensitive information in these locations, it can be read by anyone who submits code via an input.

It's not enough to only strip out <script> tags from an input to prevent XSS attacks through JavaScript. JavaScript code can be defined directly on DOM elements using inline event handlers.

An example of such an attack could look like this:

<img
    src="some-source-that-does-not-exist"
    onerror="alert('This will be called because the image cannot load')"
/>

When the browser loads an image element with an invalid source, it fires the onerror event.

Package managers

Another way attackers could inject malicious code is through package managers such as NPM. NPM packages are renowned for having hundreds of dependencies, each of which could contain malicious code.

Mitigating and preventing attacks

Validate form data

On API endpoints, it's important only to accept the data you expect and ignore everything else.

Sanitise input data

It's important to sanitise input data from users, both on the frontend and backend.

Store data safely in the browser

Applications should not store sensitive data such as tokens in localStorage.

Applications can store sensitive data in cookies, but only if the cookie has the HttpOnly attribute. Only servers can read HttpOnly cookies. Using server cookies only works if the backend and frontend are served through the same domain or if API calls are made through a proxy.

Update dependencies

Always keep external dependencies updated. NPM has an audit command to check for and update packages with security vulnerabilities.

Authentication scaffolding

Starter kits for Laravel, Vue and React.