Cross-Site Scripting in swagger-ui
Description
Affected versions of swagger-ui are vulnerable to cross-site scripting. This vulnerability exists because swagger-ui automatically executes external Javascript that is loaded in via the url query string parameter when a Content-Type: application/javascript header is included.
An attacker can create a server that replies with a malicious script and the proper content-type, and then craft a swagger-ui URL that includes the location to their server/script in the url query string parameter. When viewed, such a link would execute the attacker's malicious script.
Recommendation
Update to 2.2.1 or later.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
swagger-uinpm | < 2.2.1 | 2.2.1 |
Patches
1331d2be070d8Escape curl command to fix XSS vulnerability.
3 files changed · +13 −13
dist/swagger-ui.js+5 −5 modified@@ -25241,10 +25241,10 @@ SwaggerUi.Views.OperationView = Backbone.View.extend({ this.parentId = this.model.parentId; this.nickname = this.model.nickname; this.model.encodedParentId = encodeURIComponent(this.parentId); - + if (opts.swaggerOptions) { this.model.defaultRendering = opts.swaggerOptions.defaultModelRendering; - + if (opts.swaggerOptions.showRequestHeaders) { this.model.showRequestHeaders = true; } @@ -25497,15 +25497,15 @@ SwaggerUi.Views.OperationView = Backbone.View.extend({ // This is required for JsonEditor to display the root properly if(!param.schema.type){ param.schema.type = 'object'; - } + } // This is the title that will be used by JsonEditor for the root // Since we already display the parameter's name in the Parameter column // We set this to space, we can't set it to null or space otherwise JsonEditor // will replace it with the text "root" which won't look good on screen if(!param.schema.title){ param.schema.title = ' '; } - } + } var paramView = new SwaggerUi.Views.ParameterView({ model: param, @@ -25926,7 +25926,7 @@ SwaggerUi.Views.OperationView = Backbone.View.extend({ // adds curl output var curlCommand = this.model.asCurl(this.map, {responseContentType: contentType}); curlCommand = curlCommand.replace('!', '!'); - $( 'div.curl', $(this.el)).html('<pre>' + curlCommand + '</pre>'); + $( 'div.curl', $(this.el)).html('<pre>' + _.escape(curlCommand) + '</pre>'); // only highlight the response if response is less than threshold, default state is highlight response var opts = this.options.swaggerOptions;
dist/swagger-ui.min.js+3 −3 modifiedsrc/main/javascript/view/OperationView.js+5 −5 modified@@ -19,10 +19,10 @@ SwaggerUi.Views.OperationView = Backbone.View.extend({ this.parentId = this.model.parentId; this.nickname = this.model.nickname; this.model.encodedParentId = encodeURIComponent(this.parentId); - + if (opts.swaggerOptions) { this.model.defaultRendering = opts.swaggerOptions.defaultModelRendering; - + if (opts.swaggerOptions.showRequestHeaders) { this.model.showRequestHeaders = true; } @@ -275,15 +275,15 @@ SwaggerUi.Views.OperationView = Backbone.View.extend({ // This is required for JsonEditor to display the root properly if(!param.schema.type){ param.schema.type = 'object'; - } + } // This is the title that will be used by JsonEditor for the root // Since we already display the parameter's name in the Parameter column // We set this to space, we can't set it to null or space otherwise JsonEditor // will replace it with the text "root" which won't look good on screen if(!param.schema.title){ param.schema.title = ' '; } - } + } var paramView = new SwaggerUi.Views.ParameterView({ model: param, @@ -704,7 +704,7 @@ SwaggerUi.Views.OperationView = Backbone.View.extend({ // adds curl output var curlCommand = this.model.asCurl(this.map, {responseContentType: contentType}); curlCommand = curlCommand.replace('!', '!'); - $( 'div.curl', $(this.el)).html('<pre>' + curlCommand + '</pre>'); + $( 'div.curl', $(this.el)).html('<pre>' + _.escape(curlCommand) + '</pre>'); // only highlight the response if response is less than threshold, default state is highlight response var opts = this.options.swaggerOptions;
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5News mentions
0No linked articles in our index yet.