2

I have an object that is stored in the server side of the application. It is never inserted into the DOM. The object looks like this:

{"id": "34245425", "field": false, "information": [{"message": "For input string: USER INPUT HERE"}]}

It adds backslashes before inserted quotes and always makes the backslashes break the string. So if you insert \" it will make it \\\" and so on. Does this prevent all XSS?

I have tried a payload like \";}]}alert(document.domain)/* and other payloads alike to no avail. I am a beginner in XSS.

3
  • 7
    Is your object inserted into the DOM at any point? It's unclear what you mean by "I have an object"
    – user163495
    Commented Dec 29, 2021 at 8:04
  • Well, it will break XSS that relies on quotation marks. But XSS is more than just that.
    – schroeder
    Commented Dec 29, 2021 at 8:22
  • 1
    @MechMK1 sorry for the late response, no its never inserted into the DOM as the object is stored on the sever side of the application.
    – declan22
    Commented Dec 29, 2021 at 21:50

1 Answer 1

4

its never inserted into the DOM as the object is stored on the sever side of the application

Well, that answers your top-level question: it's impossible to have XSS if the content isn't sent to the client, because it's a client-side attack.

Now, with that said, since your server is apparently processing JSON containing user content, you do need to worry about data corruption / content insertion / deserialization attacks (the last probably not relevant here unless you're doing something weird with that JSON). Assuming you're just storing JSON as strings (e.g. for serialization with a DB or file) and then parsing it using JSON.parse or similar, you're probably at no risk of arbitrary code execution in particular; if you try to JSON.parse('{"id": "34245425", "field": false, "information": [{"message": "For input string: ";}]}alert(document.domain)'), the result is just an error because that's not valid JSON. The only you'd be at risk for code execution is if you built that "JSON" using string concatenation, and then wrote it to a JS file and executed the JS (or passed the string to eval or equivalent, which... eval is already bad, eval anywhere near user-supplied content is crazy, never do that).

Calling JSON.stringify on any valid JS object is always safe, as is passing the result of that call to JSON.parse. Stringification will automatically escape any characters that need it; no need to do so manually. Therefore, one way to do this safely (if overcautiously) is the following:

let msg = 'For input string: ' + request.UserInput;
let input = {"id": "34245425", "field": false, "information": [{"message": msg}]};
let inputStr = JSON.stringify(input);

This is always going to be safe, because you're not mixing things that are strings (the value 'For input string: ', the user content) with things that aren't (JSON or the object itself); you build a string, and then use the language features to add it to the object and built-in APIs to convert that object to (and presumably later from) a JSON string. It is safe to combine the first two lines into one, ... "information": [{"message": "For input string: " + request.UserInput}]}; because the JS parser will still evaluate the string concatenation expression before assigning it to the message property, but I spread it out for clarity. This one is safe to do anything with.

Mind you, you can (and should) avoid string concatenation entirely. Two ways to do that:

  • Remove the seemingly-redundant "For user input: " so the second line of the block above just becomes input.information[0].message = request.UserInput; and the first line goes away entirely.
  • Nest the message subfields in their own objects, so the first two lines become input.information[0].message = {"inputString": request.UserInput}; or similar.

As a general rule, if you find yourself trying to write an XSS filter, or indeed any kind of sanitizer for a common format, you're doing at least one thing wrong. It might just be "not using a common, well-tested library", but it's reasonably likely to be "not using language or framework features that render the whole question moot" or "using a design where this is even necessary".


EDIT: Clarified the code examples to highlight the over-cautious approach

2
  • just for future reference, would this be exploitable if I were to insert it straight into the DOM? Thanks in advance.
    – declan22
    Commented Dec 31, 2021 at 3:07
  • 1
    Yes it would. You should account for other string delimiters like ' and `. It's not doing anything about the HTML parser, which will terminate a script block as soon as it sees a </script>, even if that's inside a JS string (this causes a JS syntax error but you can just start a new block ), and will un-escape HTML escapes such as &quot; before passing them to JS in inline event handlers. I might be forgetting other vectors, even. As I said, this is best left to well-tested libraries, or avoided entirely (putting user content into scripts is dangerous!).
    – CBHacking
    Commented Dec 31, 2021 at 13:54

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .