netbox-community / pynetbox

Python API client library for Netbox.
Apache License 2.0
543 stars 167 forks source link

HTTP requests being made for connected_endpoint calls (possible security issue?) #528

Closed jiphex closed 1 year ago

jiphex commented 1 year ago

I am using Netbox v6.6.2, I've not been able to test this with v7 yet, although I don't see any reference to it in the Changelog.

When I get the connected_endpoint for a device (e.g a power outlet on a device), pynetbox has to make a call to the NetboxAPI to get the details.

Despite me having the pynetbox.Api object configured with a https endpoint, it looks like for some reason, when this details request is being made, the requests to Netbox are going over plaintext http.

netbox = pynetbox.api(
    "https://netbox.example.com",
    token=os.getenv("NETBOX_TOKEN", default=None),
)

The initial requests (getting details about the devices themselves) go directly over HTTPS:

DEBUG:urllib3.connectionpool:https://netbox.example.com:443 "GET /api/dcim/devices/?role_id=12&limit=0 HTTP/1.1" 200 380174
DEBUG:urllib3.connectionpool:https://netbox.example.com:443 "GET /api/dcim/devices/?role_id=5&limit=0 HTTP/1.1" 200 472343
DEBUG:urllib3.connectionpool:https://netbox.example.com:443 "GET /api/dcim/devices/?role_id=65&limit=0 HTTP/1.1" 200 13243

However when I start to enumerate the outlets and their connected devices, the detail requests are going via HTTP (and getting redirected):

DEBUG:urllib3.connectionpool:http://netbox.example.com:80 "GET /api/dcim/power-outlets/6370/ HTTP/1.1" 302 240
DEBUG:urllib3.connectionpool:https://netbox.example.com:443 "GET /api/dcim/power-outlets/6370/ HTTP/1.1" 200 603
DEBUG:urllib3.connectionpool:http://netbox.example.com:80 "GET /api/dcim/power-outlets/6371/ HTTP/1.1" 302 240
DEBUG:urllib3.connectionpool:https://netbox.example.com:443 "GET /api/dcim/power-outlets/6371/ HTTP/1.1" 200 603

I was able to discover this by enabling the urllib3 verbose logging as described here. I only construct the pynetbox.Api object once, and it is used throughout this code, so I don't understand why this is changing back to HTTP.

I think this is a security issue, as the requests to the http endpoint include the Netbox token, so it is being leaked in plaintext.

jiphex commented 1 year ago

I suspect this is something related to this?

jiphex commented 1 year ago

Ah, unless my netbox server is misconfigured with a HTTP base URL

jeremystretch commented 1 year ago

Looks like you got this resolved, but thanks for taking the time to report anyway @jiphex!

jiphex commented 1 year ago

Yes, for anyone else that comes across this - the problem is that the Netbox server is listening on HTTP behind a reverse proxy for SSL, so it thinks it's receiving requests via HTTP in stead of HTTPS

This means that the object URLs returned from the Netbox API (say the url field or tenant.url) in the data have http: prefixes instead of https:, which pynetbox will happily follow.

It looks like I need to configure Netbox to respect the reverse proxy's X-Forwarded-Proto header, so that it will return these as HTTPS responses instead.

markkuleinio commented 1 year ago

Yes, this is what I have in NetBox' nginx configuration when using AWS ALB in front of NetBox:

proxy_set_header X-Forwarded-Proto https;