CWE-650 is a protection mechanism built on the belief that a GET request is harmless. The HTTP specification says GET should not have side effects, but nothing in the protocol enforces it. If your code accepts GET and changes data, a rule that only restricts POST, PUT and DELETE does not protect anything. REST-style web services are the usual place for this.
How it happens
A team locks down write methods on a resource and assumes the job is done. Elsewhere, a developer wrote a handler that deletes a record when it receives a GET, because it was convenient or because a link had to work from an email. MITRE notes it is common practice with REST web services to have GET requests modify resources on the server side.
# Vulnerable: a state change on GET, guarded only by a method rule upstream
@app.route("/items/<id>/delete")
def delete_item(id):
db.delete(id)
return "ok"
What an attacker gains
MITRE lists three consequences: escalating privileges, modifying application data (resource modification and deletion), and reading sensitive application data.
How to find it
The record does not list detection methods. Review the route table: list every handler reachable by GET, and check whether any of them writes, deletes or triggers an action. Then try each protected resource with every method, GET included, as an unprivileged user.
How to fix it
MITRE's mitigation is to configure ACLs on the server side so the right level of access control is defined for each accessible resource representation. Practically:
- Enforce authorization in the handler, regardless of method.
- Never perform state changes on GET. Use POST, PUT, PATCH or DELETE and check permissions on those.
- Deny by default, and allow methods per route explicitly.
@app.route("/items/<id>", methods=["DELETE"])
@require_permission("items:delete")
def delete_item(id):
db.delete(id)
return "", 204
Quick check
Does the HTTP spec stop a server from changing data on GET?
No. It says GET should be free of side effects, but a server can still implement a GET that creates, updates or deletes data.