pai icon indicating copy to clipboard operation
pai copied to clipboard

Use user code from panel to validate partition control messages

Open kebab9009 opened this issue 4 years ago • 19 comments

With current implementation any of the client can send a partition control message to pai and easily disarm the system. From the overall system perspective it can lead to a vulnerability.

Disarming should be only possible if a user code is sent back as part of the payload. The sent user code should be validated against the user code(s) in the alarm panel. If the user code is found in the alarm panel the system should make the state change on behalf of the found user. In every other cases the request should be rejected.

kebab9009 avatar Mar 05 '20 09:03 kebab9009

Doing actions on behalf of the user on the panel would be complicated but I can make PAI validate sent code and then perform an action. You won't get any info who armed the partition in notifications. It will be same special arming as it is today.

yozik04 avatar Mar 05 '20 10:03 yozik04

It can not lead to a vulnerability if you use an MQTT password. Via HASS: Your phone is still protected with a pin code. In hass it is possible to set a password for the alarm_control_panel component.

What to do with arming/disarming from GSM or Pushbullet? Just consider these are safe senders? It will be stupid to send codes there as they will be visible later.

yozik04 avatar Mar 05 '20 10:03 yozik04

It can not lead to a vulnerability if you use an MQTT password.

I think mqtt password is not enough, the cleint need to be capable to connect to brokers with tls enabled. If not the password still can be captured as it send as cleartext over the network.

Via HASS: Your phone is still protected with a pin code. In hass it is possible to set a password for the alarm_control_panel component.

Yes you are right about HASS but its hard to synchronize the hass config with the alarm panel config for every user if you change your user code frequently.

What to do with arming/disarming from GSM or Pushbullet? Just consider these are safe senders? It will be stupid to send codes there as they will be visible later.

I don't know what to do with other channels like GSM and pushbullet, but maybe this can be an option if you want to use mqtt.

kebab9009 avatar Mar 05 '20 11:03 kebab9009

You should secure the MQTT broker with a password, ACLs and TLS. If you don't do this, it will be possible to capture the commands used. Alternatives would require implementing a CHAP method, which is not there, but may make sense.

Other methods (Signal, GSM, Pushbullet) will accept commands from known (authorized) contacts. Also, there is no challenge. Here a solution would be to deploy a OTP allowing commands from any phone if a correct OTP was provided. However, you would need to store the OTPs somewhere (wallet, laptop?), which may create a huge problem.

jpbarraca avatar Mar 05 '20 14:03 jpbarraca

I only use MQTT so i dont't know much about the other methdos. We currently use the MQTT borker with password and ACLs but as i know pai not support TLS.

kebab9009 avatar Mar 05 '20 17:03 kebab9009

Added an experimental feature in this direction.

If you set MQTT_CHALLENGE_SECRET to a string:

  • paradox/states/challenge will contain a random hex challenge
  • MQTT commands must be accompanied by a challenge response: "command response"
  • the response can be calculated by obtaining the hex digest of hashing the challenge and secret MQTT_CHALLENGE_ROUNDS times (default is 1000) using SHA1.
  • when a command is sent, the challenge changes
  • If the response fails, the command is blocked
  • otherwise, it is passed to the alarm

jpbarraca avatar Mar 06 '20 01:03 jpbarraca

😆 Isn't that over complicated? I imagine configuring homeassistant to calculate that. Sounds crazy. https://www.home-assistant.io/integrations/alarm_control_panel.mqtt/

yozik04 avatar Mar 06 '20 06:03 yozik04

I think mqtt password is not enough, the client need to be capable to connect to brokers with TLS enabled. If not the password still can be captured as it send as cleartext over the network.

stunnel is the fastest way to configure it even if link never supported tls.

I also see that paho_mqtt supports TLS. Then it should be easy to enable: https://stackoverflow.com/questions/51942821/how-to-use-ssl-tls-in-paho-mqtt-using-python-i-got-certificate-verify-failed

yozik04 avatar Mar 06 '20 06:03 yozik04

It's a standard challenge based auth and solves the issue of a passive attacker.

I will use it as I have a device that doesnt use tls but can calculate digests. For homeassistant, alternative ideas are welcome :)

jpbarraca avatar Mar 06 '20 07:03 jpbarraca

Also, even with TLS, any client connected to the broker can disarm the panel. If someone as a requirement for authenticating the requests, this helps.

Related to this, i would like to know who sent the command. Probably by allowing json messages with this info.

jpbarraca avatar Mar 06 '20 08:03 jpbarraca

For homeassistant, alternative ideas are welcome :)

Evil 🤣

Also, even with TLS, any client connected to the broker can disarm the panel. If someone as a requirement for authenticating the requests, this helps.

In mosquito you can set restrictions what authenticated user can read and write.

yozik04 avatar Mar 06 '20 08:03 yozik04

Added an experimental feature in this direction.

If you set MQTT_CHALLENGE_SECRET to a string:

  • paradox/states/challenge will contain a random hex challenge
  • MQTT commands must be accompanied by a challenge response: "command response"
  • the response can be calculated by obtaining the hex digest of hashing the challenge and secret MQTT_CHALLENGE_ROUNDS times (default is 1000) using SHA1.
  • when a command is sent, the challenge changes
  • If the response fails, the command is blocked
  • otherwise, it is passed to the alarm

It works good, only error at me is that if i try to set the secret in the pai.config, it got the error. Exception: Error parsing configuration: Invalid value type <class 'str'> for config argument MQTT_CHALLENGE_SECRET. Allowed are: [<class 'NoneType'>]

The user code can be added too to the hashing string and then can be validated at the backend.

kebab9009 avatar Mar 06 '20 12:03 kebab9009

MQTT_CHALLENGE_SECRET value type fixed.

yozik04 avatar Mar 06 '20 13:03 yozik04

Can you guys create validaiton which checks every user code in the panel? The formula can be something like this: {challenge}{secret}{user_code}

kebab9009 avatar Mar 08 '20 20:03 kebab9009

Sure we can. Need to find time for it.

yozik04 avatar Mar 09 '20 14:03 yozik04

Loading 999 users from EEPROM takes a lot of time even on EVO.

yozik04 avatar Mar 14 '20 22:03 yozik04

Hmmm. I think there is not too many people who have that many user, but if you make it optional then it can be a solution.

kebab9009 avatar Mar 15 '20 21:03 kebab9009

for EVO user definitions with codes are loaded in PAI.

yozik04 avatar Mar 17 '20 17:03 yozik04

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar May 16 '20 18:05 stale[bot]