2

We integrate a third-party app, using a javascript code that we need to send an email and name.

This email and name come from a previous step registration form.

Because we need to print on the page that email and name we encode it.

some.survey({
    email: "test@test.pt",
    name: "Mon & Sons",
    properties: {"one":"123","two":"345"}
});

The issue is that the third party before printing is encoding again our string, showing in the browser like: "Mon & Sons".

Does anyone know how to get around this?

foxtrot
  • 1,056
  • 1
  • 8
  • 24
  • I would just decode the string before sending to the call to the external service. (as @sbgib has answered). Another option is to have 2 properties "nameEncoded" and "nameRaw" send nameRaw to the external service. – Vetras Sep 17 '20 at 10:47
  • @Vetras The nameRaw can't be used. Is open to XSS attacks. – foxtrot Sep 17 '20 at 10:56

2 Answers2

1

Here's a way (based on https://stackoverflow.com/a/784698):

function DecodeHTML(txt) {
  var el = document.createElement("div");
  el.innerHTML = txt;
  return el.innerText;
};

DecodeHTML("Mon & Sons");
//"Mon & Sons"

Edit: watch out for XSS attacks, however. It is possible that the third-party app is doing this to escape any ' into ' and " into ", so you may want to build on the above idea to prevent this, depending on your needs. For example, if you're going to display this information on a HTML page, do so by only setting innerText of an element in that page, e.g. nameelement.innerText = nametext;

sbgib
  • 5,580
  • 3
  • 19
  • 26
  • Nice point with the innerHTML, but I don't have any control over the third-party app. I was thinking if I can have any different approach when sending the data. Thanks. – foxtrot Sep 16 '20 at 10:17
  • If you follow the above link, there are solutions for doing the inverse. I'm not quite clear on how the data is changing across these various steps vs. how you want it to change, but if you are able to both encode and decode the HTML special characters, then you should be able to apply that at whichever stage you need to. – sbgib Sep 16 '20 at 10:28
  • I see, thanks, but as you said, I'm concern about being exposed to XSS attacks, if I need, in some way to not output encode the data. – foxtrot Sep 16 '20 at 10:44
  • That's fair. If you think about it though, the name is just a name, so that can be printed as text (as above), so even if someone tries an XSS attack using that, it won't be parsed. For the email, you could use the above function, or more secure still, a function that performs string replaces of specific characters; and then validate the result. If it's a valid email address, that should be ok: https://social.technet.microsoft.com/Forums/exchange/en-US/69f393aa-d555-4f8f-bb16-c636a129fc25/what-are-valid-and-invalid-email-address-characters – sbgib Sep 16 '20 at 10:52
  • 1
    I've manage to do an XSS attack using the name, registering using . The browser parsed the name as code. – foxtrot Sep 17 '20 at 07:31
  • If I do this, it gets parsed as text: <- temp1.innerText = ''; > "" Not sure how you're parsing it. – sbgib Sep 17 '20 at 07:36
  • The question is more that is possible to inject in the name XSS. Don't know exactly how you tested, but is pretty easy, checking the source code of the page. – foxtrot Sep 17 '20 at 09:02
1

sbgib was almost right about how this would work. So, we now output the string as encoded, and decode it with Javascript, before sending it to the external service.

function DecodeHTML(txt) {
  var el = document.createElement("div");
  el.innerHTML = txt;
  return el.innerText;
}

some.survey({
    email: "test@test.pt",
    name: DecodeHTML("Mon &amp; Sons"),
    properties: {"one":"123","two":"345"}
});
foxtrot
  • 1,056
  • 1
  • 8
  • 24