Allow GET in webhook triggers#56446
Conversation
|
I think we should maybe consider allowing for this, for 2 reasons:
|
|
If this PR is to apply to all webhooks, is it possible to add CSRF protection on these URLs? |
|
+1 from me. QR codes and RFID tag URLs could then be used to trigger automations without apps. |
|
@esev what type of CSRF protection did you have in mind? I don't think any of the use cases wanting this can set header tokens. |
This comment has been minimized.
This comment has been minimized.
I agree. And I don't see any good solution except for using long random URLs that aren't shared publicly. Just to clarify. I do see the value in this PR! It makes some integrations a lot simpler. My goal isn't to stop the PR. I just want to raise awareness of the issues. As long as users are aware of the abuse vector, they can take steps to avoid it. I just fear folks will use this without considering the consequences. <html>
<body>
<img src="http://homeassistant.local:8123/api/webhook/Unlock_Door" />
<img src="http://homeassistant.local:8123/api/webhook/Open_Garage" />
</body>
</html>Can a blueprint contain a webhook trigger? If so that might be another abuse vector to consider (blueprints with common webhook names, or attacker controlled blueprints). Especially with the easy-to-click "Add Blueprint" buttons. That said, AFAICT the CSRF issue is already present with webhooks as the CORS headers already allow this ( This might get safer in the future though. See https://wicg.github.io/private-network-access/. I believe Chrome intends to support this (https://developer.chrome.com/blog/private-network-access-update/). |
But you are aware that everything you wrote is the same for POST webhooks? This request is to get GET and not to remove webhooks. 😉 |
This comment was marked as off-topic.
This comment was marked as off-topic.
|
Why are we discussing webhooks in this PR? This is completely not related to it. Everything what you wrote is already there. Warning, off by default, created only if you create an automation, etc. https://www.home-assistant.io/docs/automation/trigger/#webhook-trigger And I saw this "only local" in the changelog from 2022.2.0 as well. At least I think so. |
|
The difference in this PR is that GET requests have no CORS preflight checks. The GET verb was intended to be a read-only action without side-effects. By adding GET, the webhooks are automatically triggerable from any static web page. That was not possible before this PR; you had to use some javascript or user interaction to trigger the webhook from a web page. Example: With this PR, if I add a webhook with the ID This can't be prevented by checking if the device is on the local subnet. Until https://wicg.github.io/private-network-access/ is implemented in browsers, all that is required is that your browser (likely on the same subnet as HA) be able to access Home Assistant locally. And that only considers browsers. It could still be triggered by malicious content in document/PDF viewers, native apps, chat messages, etc. Admittedly though, I think most browsers would block this behavior from secure sites. Browsers tend to not allow mixed content; http requests from https sites. So that would mitigate the risk a bit. But it would be great if we could also consider users who setup SSL for themselves too, and make them safe also. Personally I'd like to see:
Each of these options could be described in the docs with examples of how they could be abused if enabled. I'm not on the HA core development team, so don't take anything I've written as a requirement for this PR. I'm not suggesting the PR be blocked; I see how it is very useful. I'm only suggesting ideas to make things safe by default (from a browser security perspective) when using webhooks so users can enable them without adding security risks. IMHO I don't think users understand/consider the CSRF implications for browsers before using webhooks. I'd just like users to be aware of the danger, and need to perform an extra action, before using webhooks in an unsafe way. In it's current form, this PR increases the danger by bypassing CORS preflight checks in the browser, without providing any safe-by-default options. This increases risk for all previously defined webhooks that only expected POST/PUT/HEAD. |
|
As someone who has requested GET support for webhooks, in several places, I think the additions proposed by @esev all sound like good ideas. In particular, the last four bullets:
All sound like terrific, and hopefully not terribly complicated additional development. I'm sad that that might mean this PR requires some re-work. I have Shelly Button 1's that want GET webhooks today to make it easier for my wife to turn off the "smart" bedroom light switch without getting out of bed. (The switch is by the door; the bed is not.) But safety first! I'll personally commit to writing the doc to go with the changes, if the appropriate person wants to loop me in. (I'm a tech writer by day, and I have one commit for the webhooks doc already.) |
|
@alderete I've sent a PR for randomizing the webhook_id by default. home-assistant/frontend#11568 Could you take a look, and update the docs if you think there is anything needed for that? The copy button on the right-side copies the URL for the webhook to the clipboard ( Thanks for volunteering to update the docs! |
|
I just submitted a PR for the webhooks doc: home-assistant/home-assistant.io#21506 I attempted to add security details in the form of best practices and considerations (don't open your garage door, etc.), and other concerns discussed in this thread. And I'm happy to continue to update the docs as this and other open webhook-related PRs move forward. (That is, please don't let doc be the blocker on this PR. I will fix it if that's what's needed.) |
|
I'm putting together a PR to:
For 1, I'm making it so that Nabu Casa's webhooks still work regardless & any webhooks triggered via the websocket API still work too. For both of these, the user would have needed to explicitly enable it, so that seems safe to me. Number 2 will be easy to adapt for this PR, and add 'GET' as an option too. trigger:
- platform: webhook
webhook_id: bnWvYB5KLRBbkT9XMCl9zXoX
allow_methods:
- PUT
- POST
allow_internet: falseI'm going to wait to see if the core developers give any feedback on the two outstanding PRs, or this PR, before proceeding on this next change though. I'll need some help updating the docs and creating a note about this being a breaking change too, assuming this all looks okay. |
|
I like the idea of opt-in GET. We should make sure it applies to the hooks coming in via cloud/websocket too. |
|
@byroncoetsee @FutureTense I don't think anyone is objecting to this feature. It's just not been reviewed yet. You could help by reviewing the PRs - even a partial review helps. 😀 |
|
@davet2001 reviews added and awaiting merge... 👍🏼 |
I'd like to have this as an opt-in feature so that folks who previously setup webhooks are not impacted by this change. This PR will decrease security for all previously added webhooks. That's why I proposed the other PRs, to give users an option to enable GET if they need it. |
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
|
I've rebased the PR onto the latest |
|
I think before we add this, we should consider: #66494 |
|
@pvizeli yes, that has been discussed and is next up. |
|
This PR is good to go, but marking it as draft until #66494 is ready to go as well. |
|
Error: tests/components/webhook/test_init.py:183:11: F811 Redefinition of unused `test_webhook_get` from line 134Edit: not this PR. |



Proposed change
Accept HTTP GET method in webhook triggers. So far only POST, PUT and HEAD have been allowed, but many devices which can be configured to send HTTP commands support only GET.
Type of change
Additional information
Checklist
black --fast homeassistant tests)If user exposed functionality or configuration variables are added/changed:
If the code communicates with devices, web services, or third-party tools:
Updated and included derived files by running:
python3 -m script.hassfest.requirements_all.txt.Updated by running
python3 -m script.gen_requirements_all..coveragerc.The integration reached or maintains the following Integration Quality Scale:
To help with the load of incoming pull requests: