XSS vulnerability is mainly linked to two parts of the web app:
Source- such as user input fieldSink- displays the input data
Front-end
Sanitize and validate the user input on the front-end using JavaScript.
Input Validation
e.g email field won’t accept input if the email format is invalid:
function validateEmail(email) {
const re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test($("#login input[name=email]").val());
}Input Sanitization
We should always ensure that we do not allow any input with JavaScript code in it.
We can utilize the DOMPurify JavaScript library, as follows:
<script type="text/javascript" src="dist/purify.min.js"></script>
let clean = DOMPurify.sanitize( dirty );This will escape any special characters with a \.
Direct Input
Never let user input directly with certain HTML tags:
- JavaScript code
<script></script> - CSS Style Code
<style></style> - Tag/Attribute Fields
<div name='INPUT'></div> - HTML Comments
<!-- -->
We should avoid using JavaScript functions that allow changing raw text of HTML fields like:
DOM.innerHTMLDOM.outerHTMLdocument.write()document.writeln()document.domain
And the following jQuery functions:
html()parseHTML()add()append()prepend()after()insertAfter()before()insertBefore()replaceAll()replaceWith()
Back-end
Input Validation
An example of E-Mail validation on a PHP back-end is the following:
if (filter_var($_GET['email'], FILTER_VALIDATE_EMAIL)) {
// do task
} else {
// reject input - do not display it
}Input Sanitization
For example, for a PHP back-end, we can use the addslashes function to sanitize user input by escaping special characters with a backslash:
addslashes($_GET['email'])For a NodeJS back-end, we can also use the DOMPurify library as we did with the front-end, as follows:
import DOMPurify from 'dompurify';
var clean = DOMPurify.sanitize(dirty);Output HTML Encoding
We have to encode any special characters into their HTML codes, which is helpful if we need to display the entire user input without introducing XSS vulnerability.