[Security] IDOR: victim telemetry endpoints trust client-supplied vId with no ownership check
Severity: HIGH
Affected file: core/user.py (multiple routes: /cIp line 182-187, /tping line 175-180, /lr line 121-128, /lc line 130-137, /bs line 139-146, /nm line 148-155, /regv line 168-173, /gGpu line 189-194, /nr line 104-119)
Description
Every victim-telemetry endpoint in core/user.py accepts the victim identifier (vId / id) directly from the POST body and uses it to write to the database with no verification that the caller actually owns that identifier:
@app.route("/cIp", methods=["POST"])
def changeLocalIp():
vrequest = request.form['id']
vIp = request.form['ip']
db.sentences_victim('update_localIp', [vrequest, vIp], 2)
return json.dumps({'status' : 'OK', 'vId' : vrequest})The same pattern repeats in /tping, /lr, /lc, /bs, /nm, /regv, /gGpu, and /nr. There is no server-issued session/token binding a connecting client to a specific vId — the id is fully attacker-controlled.
Combined with the fact that /get_data (see issue #405) returns every tracked vId, an attacker can enumerate real victim identifiers and then forge writes against them.
Proof of Concept
POST /get_data(unauthenticated) → obtain a real victim'svId.POST /lrwithvId=<victim>&lat=0&lon=0→ overwrite that victim's stored geolocation.POST /tpingwithid=<victim>repeatedly → keep the victim falsely marked "online" indefinitely, or use it to spoof liveness.POST /regvwithvId=<victim>&site=...&fid=...&name=...&value=...&sId=...→ inject fabricated captured-form records into a real victim's session, polluting the operator's collected intelligence.POST /cIpwithid=<victim>&ip=1.2.3.4→ corrupt the victim's recorded local IP.
Impact
Any network-reachable client can corrupt or spoof another victim's tracked telemetry (location, online status, network info, GPU info, captured form data) without any authentication, undermining the integrity of all data the operator collects.
Suggested Remediation
- Issue each victim client a signed, server-generated session token when
/registerfirst creates avId, and require that token (not just the barevId) on every subsequent write endpoint. - Validate that the token matches the
vIdbeing written to before performing any database update.
Source: jofpin/trape