Skip to content

HTTPS Mixed Content for swagger.json with gunicorn #188

Closed
@jslay88

Description

@jslay88

I have noticed that swagger.json fails to load behind an HTTPS proxy (say, a kubernetes ingress controller) when using gunicorn to serve, but not uWSGI. This happens regardless of passing header X-Forwarded-Proto as recommended in the gunicorn documentation. While the issue probably lies with gunicorn, I have been able to make a slight change to the library which makes it work with gunicorn and uWSGI.

Changing api.specs_url to not use _external on url_for, allows it to return just the relative path to swagger.json, instead of a complete URI (/api/v1/swagger.json vs http://host.com/api/v1/swagger.json) and subsequently allows the JS to load swagger.json. This also falls in line with the behavior of other Django REST middlewares, as well as FastAPI.

return url_for(self.endpoint("specs"), _external=True)

Repro Steps

  1. Run a basic Flask App with Flask-RESTX using gunicorn, and access it from an HTTPS reverse proxy.

Expected Behavior

Ability to load the SwaggerUI from behind an HTTPS reverse proxy using gunicorn. Having the JS load path instead of URI by rendering out api.specs_url not using _external. Ergo, a relative path to swagger.json being passed to the swagger-ui template.

Actual Behavior

RESTX renders out the entire URI using HTTP (because the connection from proxy to gunicorn is HTTP) for the JS to load swagger.json for the SwaggerUI, thus causing a broken SwaggerUI because its trying to load insecure content on a secure site.

Error Messages/Stack Trace

Mixed Content: The page at 'https://host.com/api/v1/' was loaded over HTTPS, but requested an insecure resource 'http://host.com/api/v1/swagger.json'. This request has been blocked; the content must be served over HTTPS.

Environment

  • Python version 3.8
  • Flask version 1.1.2
  • Flask-RESTX version 0.2.0
  • Other installed Flask extensions None

Additional Context

Generally, websites use relative paths for their own content.

All of the other static content loaded by the SwaggerUI (CSS, JS bundles, etc) load with relative paths and work. Only swagger.json does not. This is because the swagger_static template filter does not use _external on url_for

return url_for("restx_doc.static", filename=filename)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions