fix: review findings on the token key

- Load the token key in Web::startup(), before either web server starts,
  so no token can be made with the all-zero key; log a failed
  pref.begin().
- createAPIToken checks mbedtls' return codes. On a failure it leaves
  the token empty, which tokenMatches never accepts, instead of hex
  from uninitialised stack.
- API_TOKEN_SIZE in ApiToken.h replaces the five char[65] buffers; the
  HMAC's description moves to createAPIToken, with the None form.
- handleLogin builds the candidate token once and compares it once.
- e2e: the serverId test skips on `secured` like its neighbours, names
  its values, and says it assumes the device sees this PC's address.
- KNOWN_ISSUES keeps #81, which #108 removes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
cjkas 2026-10-27 20:38:29 +01:00
parent 43191ba312
commit 97d8a90da8
8 changed files with 59 additions and 50 deletions

View file

@ -23,7 +23,6 @@
#include "Utils.h"
#include "SocketEmitter.h"
#include "../entryPoints/Web.h"
#include "ApiToken.h"
#if HAS_ETHERNET
#include <ETH.h>
#endif
@ -263,7 +262,7 @@ static bool authorized(AsyncWebServerRequest *request) {
if(settings.Security.type == security_types::None) return true;
const AsyncWebParameter *key = request->getParam("apikey");
if(!key || !request->client()) return false;
char token[65];
char token[API_TOKEN_SIZE];
webServer.createAPIToken(request->client()->remoteIP(), token);
return tokenMatches(token, key->value().c_str());
}