Push Notifications and Basic Auth

If using a proxy, HTTP basic authentication must be off for registering or unregistering for push notifications. It can be re-enabled afterwards.

From this page: HTML5 Push Notifications - Home Assistant

Can anyone explain to me why this is the case? I assume it is because something must access the server that can’t go through that authentication layer. I am just curious what that might be, because I would like to think up a way around it.

/manifest.json must be accessible. I added
location /manifest.json { proxy_pass http://HAIPADDRESS:8123/manifest.json; }
to my nginx conf before the location / block and it seem to work

Considering I wrote that on the page this is the information I need to really make that page better. I never figured that out.

Basic Auth also has to be off for /api/notify.html5 or actions will not be returned to the server (I think that is the path, I’d have to double check) so I have an nginx location for that that disables authorization for that path.

That scenario about the HTML5 actions is something I hadn’t considered yet. Since they are coming from the browser, would they acknowledge cookies that are set in the browser?

This is how I auth currently:
expires off;
auth_request /oauth2/auth;
error_page 401 = /oauth2/start?rd=$uri;
proxy_pass http://10.0.0.100:8123;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection “upgrade”;

the /oauth2 directory is another proxy_pass location that connects to an oauth2_proxy configured for using my Gmail account to authenticate. So rather than giving the basic auth password prompts, nginx just asks oauth2_proxy “is he authed?” and if I am, it allows me through.

I have already tried the manifest.json exception. That doesn’t look like there should be any risk about accessing it without auth, is there? What would be the risks of allowing /api/html.notify access with no authentication layer?

So, I thought about what could happen if /api/notify.html5 is exposed and I think the answer is that that it is safe.

With a bit of exploring and looking at the code, I did successfully “register” a device to the html5_push_registrations.conf file, however that registration is missing keys and a googleapis endpoint. All of which I believe cannot be generated without your gcn key and gcm sender ID (since all outgoing requests hit google first and they should check that everything is valid else I could send notifications to anyone). So, an attacker could not allow themselves to receive broadcast notifications.

Then, for callbacks that take care of actions, it checks authorization on its own (just do a curl post against /api/notify.html5/callback and you’ll see). I don’t know enough about it, but I have to imagine it is at least as secure as basic_auth.

Even if I’m wrong, someone would spend a lot of time gaining the ability to turn my lights on/off, as it isn’t as straight forward as doing a GET request on /api/services and then executing whatever they want.

I see the authorization header expected response, but what would be contained in that header? I have no api key set in Hass because I am using only the proxy authentication so I don’t have to sign in twice. I have the API secured by still accepting the api_password=abc123 in the request, but only checking for it in nginx and then removing it before passing to hass.

Poking around a bit more, it is expecting an OAuth2.0 Bearer Token.

It looks like the token is pulled from the html5_push_registrations.conf file and must match upon receipt. Since it is protected by SSL during sending/receiving I conclude that it is safe. As long as you protect your html5_push_registrations.conf file no one should be able to break in.

Thank you so much for these details. This information will definitely make it into my write-up of this project. Pretty excited about having a fully functional hass with oauth2 authentication!

Actually I still have one question left.

I would like to secure /api/notify.html5 a little better. I am OK with /api/notify.html5/callback being left open because it is requiring the bearer token for auth, but /api/notify.html5 may appear “safe” at first glance, but you already said you could add registrations, broken registrations, but they could still be added and spam the file, which I would still consider unlikely, but definitely not “safe”.

Any ideas?

So, some more testing, and it looks like you can enable authorization on all locations except

/manifest.json
/api/notify.html5/callback

If you do that, you can register and unregister and receive callbacks. I believe that manifest.json is needed for the 3rd party access, and /api/notifications.html5/callback is called by whoever you notify and must pass back an auth token.

I do have to say thanks for this thread and questions. I was happy enough with my loose security (which was probably good enough), but I understand the whole thing a lot better now.

1 Like

Yeah, I think we duplicated efforts there. I logged onto /dev and they were able to help me come to the same conclusion, but forgot to post it here to save you some time.