diff --git a/drb-c2-core/app/routers/upload.py b/drb-c2-core/app/routers/upload.py index 063f044..b62707c 100644 --- a/drb-c2-core/app/routers/upload.py +++ b/drb-c2-core/app/routers/upload.py @@ -1,3 +1,4 @@ +import secrets from typing import Optional from datetime import datetime, timezone from fastapi import APIRouter, BackgroundTasks, UploadFile, File, Form, HTTPException, Security @@ -36,7 +37,11 @@ async def upload_call_audio( if not key_doc: logger.warning(f"Upload 401: no key_doc in Firestore for node_id={node_id!r}") raise HTTPException(401, "Invalid node API key") - if key_doc.get("api_key") != credentials.credentials: + # compare_digest, not !=, so the comparison cost does not depend on how many + # leading characters matched. enrollment.py and dynsec.py were explicit about + # this for the same class of credential; this route was the odd one out. + stored_key = key_doc.get("api_key") or "" + if not secrets.compare_digest(stored_key, credentials.credentials): logger.warning( f"Upload 401: key mismatch for node_id={node_id!r} " f"(received prefix: {credentials.credentials[:8]}...)"