- Return 400 for empty or whitespace-only file_name to prevent the
idedata fallback from matching everything via empty-string suffix.
- Use image.path.as_posix().endswith() since FlashImage.path is a Path
object which does not have a string endswith method.
- Add parametrized test for empty/whitespace file name values.
- Change result accumulator from volatile uint8_t to volatile size_t
to prevent truncation bypass (e.g. digest_len + 256 XOR).
- Iterate over max(digest_len, provided_len) so trailing bytes in
either string are also compared.
- Refactor auth_settings fixture to extend dashboard_settings instead
of duplicating setup.
- Explicitly clear DISABLE_HA_AUTHENTICATION in HA add-on test to
prevent order-dependent flakiness.
- Add None check for storage_json.firmware_bin_path before computing
base_dir (covers configs from StorageJSON.from_wizard()).
- Mock async_run_system_command in path traversal tests so paths that
pass validation but don't exist return 404 deterministically.
- Add test for firmware_bin_path=None case.
On Windows, ....//secrets.yaml escapes the base directory (403),
while on Unix it stays inside (404). Use sys.platform to set the
expected status code per platform.
binascii.Error is already a subclass of ValueError, but listing it
explicitly makes the intent clear. Added test for incorrect base64
padding (e.g. "Basic abc").
Use the out length from esp_crypto_base64_encode instead of strlen.
Fold length mismatch into the accumulator to make comparison fully
constant-time without early return.
Initialize password_hash as b"" (bytes) to match password_hash()
return type, preventing TypeError in hmac.compare_digest when
HA add-on auth is enabled without a password.
Use nonce_size // 2 as token_hex argument so MD5 auth produces
a 32-char cnonce and SHA256 auth produces a 64-char cnonce,
matching the original protocol behavior.
Rename mock_random fixture to mock_token_hex and use separate
mock cnonce constants per hash algorithm.
Replace string-based path sanitization (.replace/.lstrip) with
Path.resolve() and relative_to() validation, matching the
pattern used by other dashboard endpoints (e.g. settings.rel_path).
The previous approach was not exploitable but was inconsistent
with the rest of the codebase.
Wrap base64 decode and split in try/except so malformed
Authorization headers return a clean 401 instead of an
unhandled exception producing a 500 response with stack
trace in logs.
Catches ValueError (covers binascii.Error from b64decode)
and UnicodeDecodeError (from .decode()).
Use hmac.compare_digest() for the username comparison to match
the existing constant-time password comparison. This prevents
username enumeration via timing analysis.
Replace random.choice() with secrets.choice() for generating
the fallback hotspot password. The random module uses Mersenne
Twister which is not cryptographically secure. The secrets
module is the correct choice for credential generation.
The file already imports secrets for other credential generation.
Replace random.random() with secrets.token_hex() for generating
the client nonce in OTA challenge-response authentication.
The random module uses Mersenne Twister which is not
cryptographically secure. The secrets module is the correct
choice for security-sensitive token generation.
- Flush UART RX buffer when response exceeds max size
- Guard handle_note_ against zero-length data
- Guard handle_reply_ against length < 2
- Validate VERIFY response has full name payload before access
- Guard GET_VERSION against length underflow
- Cast %.*s precision to int, use %zu for size_t
- Improve MAX_RESPONSE_SIZE comment with payload layout
Replace std::vector<uint8_t> in recv_command_() with a member
std::array<uint8_t, 36> buffer to eliminate heap allocation on
every polling cycle. Also use pointer+length instead of vector
references in handle_note_/handle_reply_, and use TextSensor's
publish_state(const char*, size_t) overload to avoid temporary
std::string construction for version and face name publishing.