Icinga / icinga2

The core of our monitoring platform with a powerful configuration language and REST API.
https://icinga.com/docs/icinga2/latest
GNU General Public License v2.0
2.03k stars 578 forks source link

Runtime modification bypasses↪️ Object#Validate() constraints👮‍♂️ #10178

Open Al2Klimov opened 1 month ago

Al2Klimov commented 1 month ago

Describe the bug

During startup and runtime creation, T#Validate() asserts own constraints after calling ObjectImpl\#Validate(). The latter calls individual attribute validators. In contrast, runtime modification consults only the individual attribute validators in question. Hence, one can cheat on T#Validate() constraints via runtime modification.

To Reproduce

  1. Setup API
    • prefix/sbin/icinga2 api setup
    • perl -pi -e 's/password = ".*?"/password = "123456"/' prefix/etc/icinga2/conf.d/api-users.conf
  2. Start Icinga
    • prefix/sbin/icinga2 daemon -d
  3. Create a Notification w/o recipients
    • curl -kvu root:123456 -X PUT -H 'Accept: application/json' -d '{"pretty":true, "attrs":{"command":"mail-host-notification"}}' 'https://127.0.0.1:5665/v1/objects/notifications/ws-aklimov7777777.local!lolcat'
    • Will fail: Error: Validation failed for object 'ws-aklimov7777777.local!lolcat' of type 'Notification': Validation failed: No users/user_groups specified. 👍
  4. Create a Notification w/ a recipient
    • curl -kvu root:123456 -X PUT -H 'Accept: application/json' -d '{"pretty":true, "attrs":{"command":"mail-host-notification", "users":["icingaadmin"]}}' 'https://127.0.0.1:5665/v1/objects/notifications/ws-aklimov7777777.local!lolcat' 👍
  5. Delete the recipient
    • curl -kvu root:123456 -X POST -H 'Accept: application/json' -d '{"pretty":true, "attrs":{"users":[]}}' 'https://127.0.0.1:5665/v1/objects/notifications/ws-aklimov7777777.local!lolcat'
    • Will succeed 😢

Expected behavior

Object constraints involving 2+ attributes get an own method which is still called by T#Validate() and additionally during runtime modification. Not sure how the latter can work.

Or each constraint(!) involving 2+ attributes gets an own method which isn't called directly by T#Validate() "anymore", but by individual attribute validators. E.g both the users and user groups attribute check for the constraint bypassed above.

Your Environment

Additional context