GET must never change a resource. Why does that rule matter, and what goes wrong if an IoT server opens a door on a GET request?
GET is defined as safe: clients, browsers, proxies and crawlers may send it at any time, repeat it, prefetch it or cache it, assuming nothing happens. A door that opens on GET can be opened by a link preview, a prefetch or a retry, and the command is trivial to trigger and repeat.
HTTP gives methods two properties that the rest of the web relies on:
- Safe (GET, HEAD): the request only reads. Software may send it without asking the user.
- Idempotent (GET, PUT, DELETE): sending it twice has the same effect as sending it once, so a client may retry after a timeout. POST is neither safe nor idempotent, which is why browsers warn before resending a form.
A state-changing GET breaks those assumptions. A chat app generating a link preview fetches the URL and opens the door. A browser prefetching links does the same. A proxy may answer from its cache, so a later "open" never reaches the device. The URL ends up in browser history and server logs, and anyone who sees it can reuse it.
So actions go in POST (or PUT for "set the state to X"). This does not make the action secure: a POST can be sniffed and replayed just as well. It only keeps ordinary web infrastructure from triggering it by accident. Security needs authentication and freshness on top.
Go deeper:
RFC 9110 — Safe methods — the normative definition, including why crawlers may follow GET links.
MDN — Idempotent — which methods are idempotent and why retries depend on it.