I'm trying to reduce vulenrabilities in an old code base, specifically XSS attacks. The general pattern is:
$.ajax request to a PHP file which returns text/plain JSON (via json_encode($data))$(selector).html, $(selector).append, or occasionnally document.getElementById(id).innerHTML =Here's a simplified example of the data flow: page.html
<head>
<script src="script.js"></script>
</head>
<body>
<table id="myTable"></table>
</body>
script.js
$.ajax({url: "phpFile.php"}, function(data){
data = JSON.parse(data);
$("#myTable tbody").html(data.redcuce(row=>"<tr><td>"+row.text"+</td></tr>", ""))
}
phpFile.php
//database query resulting in $data = [text->'<img src="x" onerror="alert(1)">', text->'Innocent value']
echo json_encode($data);
Some of the data retrieved is user input, so if a field contains <img src="x" onerror="alert(1)">, this executes when rendered in the table.
I've passed the below sanitising function to JSON.parse to sanitise the data
const sanitiseJson = (key, value) => typeof value === "string" ? DOMPurify.sanitize(value, { USE_PROFILES: { html: true } }) : value;
This uses the DOMPurify library, which would be very easy for me to implement with search and replace.
As I understand it, this will remove potentially malicious HTML from the JSON object. This will prevent XSS attacks in this scenario.
Edit: note I'm well aware that .html() etc is not the proper way to insert data, but this is an old, large code base (45k+ lines) and it's heavily entrenched, so my question is more about if this is an 'acceptable' solution in a pinch or if it doesn't come close
From my limited testing it seems to work, and as I (poorly) understand the way the data is processed I can't see how this would be circumvented easily