security: random per-device API token + one-shot pairing window (CRIT auth-bypass fix)
The bearer token was sha256(serial)[:32] and the serial is served unauthenticated, so anyone reaching :5000 could compute it and take the device over. Now: token is a random secrets.token_urlsafe(32) at /data/adacam/api_token (never derived from serial); /pair only returns it during a one-shot pairing window (/data/adacam/pairing_open, opened by adacam-pair or install.sh, closes after one pair); require_auth uses hmac.compare_digest. NEEDS ON-DEVICE PAIRING TEST before merge to main — see SECURITY-PAIRING.md.
This commit is contained in:
parent
6c27b75208
commit
185d490d58
5 changed files with 155 additions and 12 deletions
|
|
@ -2,7 +2,7 @@
|
|||
import subprocess
|
||||
from flask import Flask, request, jsonify
|
||||
from . import config, db, forwarder
|
||||
from .auth import get_device_serial, get_api_token, require_auth
|
||||
from .auth import get_device_serial, get_api_token, require_auth, pairing_open, close_pairing
|
||||
from .routes import landmarks, gnss, status, frames, wigle
|
||||
|
||||
|
||||
|
|
@ -25,10 +25,23 @@ def create_app():
|
|||
@app.route('/pair')
|
||||
@app.route('/api/1/pair')
|
||||
def pair():
|
||||
"""Pairing info for companion app."""
|
||||
"""One-shot pairing. Returns the device's RANDOM API token, but only
|
||||
while the pairing window is open (opened on the device via `adacam-pair`
|
||||
or install.sh on first provision). The window closes the instant a pair
|
||||
succeeds, so the token can't be harvested by an unprivileged caller the
|
||||
way the old serial-derived token could.
|
||||
"""
|
||||
if not pairing_open():
|
||||
return jsonify({
|
||||
'error': 'pairing window closed',
|
||||
'hint': 'run `adacam-pair` on the device (or re-run install.sh) to open a one-shot window'
|
||||
}), 403
|
||||
serial = get_device_serial()
|
||||
token = get_api_token()
|
||||
close_pairing() # one-shot — must be re-opened on the device for the next pair
|
||||
return jsonify({
|
||||
'serial': serial,
|
||||
'token': token,
|
||||
'version': '1.0',
|
||||
'ap_ip': '10.77.0.1',
|
||||
'api_port': 5000
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue