I have a Actix/Web project using Askama for HTML templates.
When outputting a value in Askama using {{ example_variable }} it is automatically encoded in a way to prevent XSS.
The problem I have now is that I also often request data using AJAX and parse the response in my HTML, this is prone to XSS-attacks.
I somehow need to encode my response to not allow XSS-queries.
For example this function which gets called by AJAX:
Which works. But then no string is shown while I'd rather have that the XSS-string is displayed but does not get executed/interpreted. And if I have to do this for each output I'm afraid I may miss a line somewhere. Is there a more efficient way?
Hmm, the function you provided won't execute anything, because its content type is JSON, not HTML. It's your template interpolations that are vulnerable (but I'm sure you already knew that).
Askama should be doing this sanitization for you already. In fact, I see some clear indicators just with a brief look through the docs: Escaper in askama_escape - Rust (docs.rs) There's a whole crate called askama_escape that it uses for this purpose.
This might be more about how you handle the response in the client, and the right solution depends on whether you already have some frameworks you’re working with.
With nothing special, you can use innerText to avoid XSS, like
It’s not really safe to construct HTML using concatenation, on either the server or the client. If you don't want to use a template library on the browser, you can do something like
let td = document.createElement('td');
td.innerText = row.value;
let html = '<tr>' + td.outerHTML + '</tr>';
but you’re going to have a horrible time keeping track of which strings are safe and which are not.
My preference if you don't go for a full framework like Vue, Svelte, React, Lit, etc., is to use something standalone like Lit HTML:
let content = html`<tr><td>${row.value}</td></tr>`;