fix: security hardening — replace fake HMAC, add path traversal protection, OTA auth (ADR-050)

Sprint 1 security fixes from quality engineering analysis (issue #170):

- Replace XOR-fold fake HMAC with real HMAC-SHA256 (hmac + sha2 crates) in secure_tdm.rs
- Add path traversal sanitization on DELETE /api/v1/models/:id and /api/v1/recording/:id
- Default bind address changed from 0.0.0.0 to 127.0.0.1 (configurable via --bind-addr / SENSING_BIND_ADDR)
- Add PSK authentication to ESP32 OTA firmware upload endpoint (ota_update.c)
- Flip WASM signature verification to default-on (CONFIG_WASM_SKIP_SIGNATURE opt-out vs opt-in)
- Add 6 new security tests: HMAC key/message sensitivity, determinism, wrong-key rejection, bit-flip detection, enforcing mode
- Add clap env feature for environment variable configuration

All 106 hardware crate tests pass. Sensing server compiles clean.

Closes #170

Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
ruv
2026-03-06 13:11:04 -05:00
parent c45690ed4e
commit 47223a98be
8 changed files with 313 additions and 20 deletions
+6 -5
View File
@@ -107,8 +107,9 @@ static esp_err_t wasm_upload_handler(httpd_req_t *req)
return ESP_FAIL;
}
/* Verify signature if wasm_verify is enabled. */
#ifdef CONFIG_WASM_VERIFY_SIGNATURE
/* ADR-050: Verify signature (default-on; skip only if
* CONFIG_WASM_SKIP_SIGNATURE is explicitly set for dev/lab). */
#ifndef CONFIG_WASM_SKIP_SIGNATURE
{
/* Load pubkey from NVS config (set via provision.py --wasm-pubkey). */
extern nvs_config_t g_nvs_config;
@@ -173,11 +174,11 @@ static esp_err_t wasm_upload_handler(httpd_req_t *req)
} else if (rvf_is_raw_wasm(buf, (uint32_t)total)) {
/* ── Raw WASM path (dev/lab only) ── */
#ifdef CONFIG_WASM_VERIFY_SIGNATURE
#ifndef CONFIG_WASM_SKIP_SIGNATURE
free(buf);
httpd_resp_send_err(req, HTTPD_403_FORBIDDEN,
"Raw WASM upload rejected (wasm_verify enabled). "
"Use RVF container with signature.");
"Raw WASM upload rejected (signature verification enabled). "
"Use RVF container with signature, or set CONFIG_WASM_SKIP_SIGNATURE for dev.");
return ESP_FAIL;
#else
format = "raw";