{"schema_version":"1.9.0","id":"GHSA-hj66-6f7g-4r5v","published":"2026-09-29T17:53:41Z","modified":"2026-10-13T16:00:32.098776410Z","aliases":["CVE-2026-49264","PYSEC-2026-4113"],"summary":"Oauthlib : Unsafe JSONP callback injection in RevocationEndpoint allows arbitrary JavaScript response generation","details":"### Summary\n\nWhen `enable_jsonp=True`, oauthlib's `RevocationEndpoint` reflects the user-supplied `callback` parameter directly into JavaScript response bodies on both success and error paths without validating that it is a legal JSONP callback name. This allows arbitrary JavaScript response generation instead of a restricted function call, making the documented JSONP revocation feature unsafe for browser-based JSONP consumption when attackers can influence `callback`.\n\n### Details\n\nThe issue is in `oauthlib/oauth2/rfc6749/endpoints/revocation.py`.\n\nWhen `enable_jsonp=True` is passed to the `RevocationEndpoint` constructor, two code paths wrap the response body using the user-supplied `request.callback` parameter:\n\n```python\n# Error response path (line 72-73):\nif self.enable_jsonp and request.callback:\n response_body = '{}({});'.format(request.callback, response_body)\n\n# Success response path (line 81-82):\nif self.enable_jsonp and request.callback:\n response_body = request.callback + '();'\n```\n\nThe `request.callback` value comes from HTTP request parameters, either the query string or POST body, via the `Request` class in `oauthlib/common.py` (lines 394-395), which merges query and body parameters into `_params`. Any value the client sends as `callback` is used verbatim.\n\nThere is no validation of any kind on the callback parameter:\n- No check that it is a valid JavaScript identifier\n- No whitelist of allowed characters\n- No escaping or sanitization\n\nA safe JSONP implementation must validate that the callback is a legal JavaScript function name (e.g., matching `^[a-zA-Z_$][a-zA-Z0-9_$.]*$`). Without this, the attacker controls the JavaScript code returned in the response body. This is the standard mitigation used by jQuery, Express.js, Google APIs, and other major JSONP implementations.\n\n**How the injection works:**\n\nAn attacker sends a revocation request with a crafted callback value:\n\n```\nPOST /revoke HTTP/1.1\nContent-Type: application/x-www-form-urlencoded\n\ntoken=anything&callback=alert(document.cookie)//\n```\n\nThe server responds with:\n\n```\nalert(document.cookie)//({\"error\": \"invalid_client\"});\n```\n\nThis is syntactically valid JavaScript. `alert(document.cookie)` executes as a statement, and `//` comments out the rest of the line. The attacker has full control over the code that appears before the `//`.\n\n**Execution context and attack surface:**\n\nJSONP works by having a browser load a remote script via `