[security] Disable ESPHome devices' ability to control the parent HA instance

Following up on the discussion in #95032 – it would be great to have an option in the ESPHome integration to treat some devices as “untrusted” and disable their ability to make arbitrary service calls into the connected HA instance via homeassistant.service.

The fact that there is currently no way to disable this functionality (devices triggering services back in HA) creates a security vulnerability where an ESPHome device in a location that is not physically secure (e.g. a sensor or switch located outside the house) can be used to effectively take over the parent HA instance, and open house locks, disable alarms, etc.

This situation is quite surprising (intuitively, communication with a sensor should be one way) and it undermines common security practices, like having strong HA passwords, and isolating untrusted devices to a vlan/subnet that is not able to initiate connections to the outside world.

+1

Note: you should vote for your feature request yourself… :smiley:

1 Like

But hold on, the device outside the house would need to be physically connected to a computer to be flashed, and someone would need your API key to connect it to your home assistant, not to mention needing access to the HA UI to connect it.

@nickrout, the attack works like this:

  1. Attacker connects to the esp over usb, and dumps the existing firmware
  2. Wifi ssid/password and API keys are easily extractable from the firmware image
  3. Attacker flashes new exploit firmware with the extracted credentials filled in
  4. Device connects back to the wifi, and HA reconnects back to it (remember it was already a registered device that HA knows about)
  5. Exploit firmware instructs HA to execute lock.unlock(lock.frontdoor)

All the steps are automatable, and can likely be executed in under a minute using any portable Linux device and no interaction beyond plugging it in.

3 Likes

If you want to go further, only use ESP32 chips, and burn the desired e-fuses after flashing to reduce the chance someone can access the device

https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/efuse.html

You could also remove the usb port if the device has one

Is the encryption key extractable? (other than that I am with you).

The encryption key is stored on the device.

It has to be or you would have to manually enter it every time the device starts up to get the api connection working.

Even if it was only stored in memory and you did have to enter it via a serial cable every time the device started, it could be extracted from memory when the device is running with the right tools.

1 Like

Sounds great! Seems a neat feature to harden the security, and it’s not oversized to care about every possible, but unlikely, edge case. :slight_smile: Thanks! :+1:

Makes sense (unlike me!)

Wow, that was fast! Many thanks, @bdraco! :pray: