I have a service which allows the user to specify a callback function name that wraps the data being returned to support jsonp callbacks. I want to make sure that I am covering all of my bases in regards to preventing XSS attacks.

Note, I have read through the OWASP security checklist but none of the recommendations seem to directly address this question.

These are the currently supported methods for specifying the jsonp function where the function name is cbFn and cbFn is declared on its own, a method on an object, or being accessed from an object/array:


These return:

cbFn({data: 'data being returned'})
obj.cbFn({data: 'data being returned'})
obj['cbFn']({data: 'data being returned'})
obj[1]({data: 'data being returned'})

However the following requests also work and are the known XSS issues I want to circumvent:

// executes an anonymous function
// replaces the user's callback function with our own

Is it enough to just replace/remove the characters ()=> in the callback name to prevent XSS vulnerabilities? I want to allow the full valid javascript character set for function names, so restricting the valid character range to /[$_\w]+/ (alphanumeric plus $ and _) doesn't seem to be a good option.

  • 1
    If the returned response is JavaScript, you shouldn't worry about character limits. And to avoid MIME sniffing, specify X-Content-Type-Options: nosniff. This ensures that the response isn't interpreted as HTML even if XSS payloads are reflected in response unmodified. Aug 25, 2018 at 20:17
  • @1lastBr3ath if the returned response is JavaScript, you shouldn't worry about character limits This sounds like bad advice. You totally have to worry about this. If it wasn't super clear, I'm asking about how to make the callback function names provided in the request safe to prevent executing arbitrary js when its executed in the context of the user's site.
    – Geuis
    Aug 25, 2018 at 20:22
  • 1
    The user can execute anything in his/her site. S/he doesn't need your script to execute defined function. As long as your jsonp endpoint returns 'application/javascript', no browsers will render the content (except IE) which ultimately neutralizes your concern. Aug 25, 2018 at 20:25
  • From the examples it looks like you not only want to have a fixed callback name but that you want to allow to use expressions which ultimately result in a function, i.e. obj['cbFn'], obj.cbFN etc. I don't think this is a good idea since then it is hard to restrict something like this. Apart from that, why use JSONP in the first place instead of CORS? JSONP is more considered a hack needed at a time proper cross-origin-XHR (i.e. CORS) was not possible. Aug 25, 2018 at 20:29
  • 1
    @Geuis: The argument from 1lastBr3ath was that you don't need to worry about the callback names at all since the callback names are given by the third party and they are executed in the website of the same third party - so they could only do harm to themselves. Since you are worried about the callback names anyway you must envision that the JSONP gets included some other way apart from <script> - and that's where the argument about the content-type fits in. Aug 25, 2018 at 20:44

1 Answer 1


It sounds like you are asking from the context of the service provider protecting a remote client in which case the answer is simple:

As the service provider, you can't protect against XSS at all, and you might as well not bother

Keep in mind, I'm normally big on "defense in depth" and putting in security walls every step of the way. However I think this is literally one of the few places where your concern isn't worth worrying about. There are two reasons why:

1. Under normal usage the executing client has full control over the request, and so there is no reason to expect payloads like this

There isn't much more to say about this actually, because this isn't what you are concerned about. But just to say out loud: the client itself is providing the JSONP callback, and so if they choose to ask you to return actual javascript, then there isn't much of a reason for you to stop them (especially since doing so would be silly and I doubt anyone would bother). The only other time someone might request a "dangerous" callback from your server is if The remote client has had an XSS breach and malicious javascript has taken over the page. However, if that happens:

2. The malicious javascript has full control over the remote page and doesn't need you to execute arbitrary javascript anyway

Which is equally simple: if an attacker has managed an XSS attack against a client using your service, they don't have to inject malicious javascript into the callback. They can just replace the callback method in the local client with their own. In fact, that's much easier. As a result, there is literally no reason why someone would attempt to use your service as an XSS injection endpoint into the remote client. To put it simply:

If an attacker has managed an XSS attack against a client using your service, then they've already won and they have no reason to pass XSS payloads into your service. It would just reflect back on the page they have already taken over.

I suppose there might be some developer out there that came up with some crazy (dangerous) scheme whereby user input on their site is used to build the JSONP callback passed into your service, and it becomes a first-order XSS vulnerability weakness. However, there is no practical reason why anyone would ever do something like that (having used lots of these kinds of services myself, you would have to go out of your way to setup something that dangerous), so much so that I don't think it is worth spending any amount of your time trying to protect your users from that level of silliness. You're more likely to accidentally introduce negative side-effects to your regular users than protect someone against the level of poor-planning that would be required for this protection on your end to do anything.

  • WARNING TO READERS: this is effectively harmful advice, the very nature of XSS is the client is the target by an attacker 'client', ergo a client is an attacker and the harm is when you assume all/any client 'chooses' to do XSS. This "client itself is providing the JSONP callback, and so if they choose to" is ignorant to the OP question and nature of XSS
    – Stof
    Jul 5, 2022 at 1:20
  • "has full control over the remote client" is an assumption, and a poor one. XSS is misunderstood clearly. most/all of this answer assumes complete compromise is the only XSS but the majority of XSS is discrete and many variant requires zero target client compromise at all (reflected) for which JSONP can be leveraged. To assume complete compromise when defending against XSS is extremely harmful and not a threat model that truly exists
    – Stof
    Jul 5, 2022 at 1:27
  • Hi @Stof! I'm afraid you have misunderstood me. By full compromise, I'm not referring to the client being compromised (e.g. malware) but that the nature of XSS means that after a successful XSS attack the attacker has taken over control of the page (via JavaScript). After even a simple reflected XXS attack, an attacker could download new JavaScript libraries and replace the "normal" page with a completely new one. Again, XSS grants an attacker full control of the client. Jul 23, 2022 at 11:00
  • With that context, XSS in JSONP is not super important. In order to get an XSS payload in the JSONP request, an attacker would first have to manage an XSS attack against the client - then the attacker could initiate XSS against the JSONP provider. Here's the key though: if an attacker has already completed XSS against the client, what would be the point of attacking the JSONP provider with a reflected XSS attack? The only thing that success would give the attacker is the ability to compromise the client with XSS but THEY ALREADY DID THAT. It's legitimately pointless to attempt it. Jul 23, 2022 at 11:05
  • More importantly though: let JSONP die. This is what CORS is for. Jul 23, 2022 at 11:44

You must log in to answer this question.

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