Server-side Request Forgery in OpenID support

Bug #1808720 reported by François Marier on 2018-12-16
256
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Libravatar
High
François Marier

Bug Description

OpenID support in Libravatar (adding an OpenID to an account, as well as logging in) allows users to trigger an arbitrary HTTP GET request from the server. This includes localhost URLs for example.

https://www.acunetix.com/blog/articles/server-side-request-forgery-vulnerability/

We should implement the following mitigations:

- filter out "localhost" and its variants (127.0.0.1, ::1, etc.)
- enforce that the scheme is HTTP or HTTPS
- disable non-standard ports (look to see if anybody is using one)
- ensure internal services (postgres, pgbouncer, gearman) are either not listening on the network or have authentication

François Marier (fmarier) wrote :

Filtering out is quite tricky because it will probably miss two kinds of things:

- a hostname which resolves to a local address
- a remote URL which redirects to a local address

The best option is probably to setup an HTTP proxy without access to local resources and then force all OpenID requests through it.

François Marier (fmarier) wrote :

Postgres and pgbouncer now require a password for localhost TCP connections.

It doesn't look like it's possible to enable any kind of authentication in gearman:

https://stackoverflow.com/questions/11228888/gearman-client
https://ttmm.io/tech/managing-gearman-securely/

François Marier (fmarier) wrote :

The GET requests are triggered from python-django-auth-openid which it turns uses a urllib2-based fetcher inside of python-openid.

Our best bet is probably to find a way to set the http_proxy and https_proxy environment variables globally for Django, possibly at the WSGI layer:

https://stackoverflow.com/questions/14284824/working-with-django-proxy-setup

Related bugs:

https://github.com/openid/python-openid/issues/83
https://bugs.python.org/issue24311

François Marier (fmarier) wrote :

All requests originating in Django are now going through a Squid proxy:

https://github.com/libravatar/wiki.libravatar.org/commit/51cdee5ead711f662b4d2d7116dc8aadd756ccb8

and any requests to localhost are denied.

In addition, I verified that nobody was using an OpenID URL in the database and now enforce a standard port of 80 or 433 in the proxy.

The OpenID library itself already restricts the protocol to HTTP or HTTPS.

Changed in libravatar:
status: Confirmed → Fix Released
information type: Private Security → Public Security
To post a comment you must log in.
This report contains Public Security information  Edit
Everyone can see this security related information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.