Harden web UI auth, input handling, and SD path validation
- Add optional Basic Auth with NVS-backed credentials and STA/AP flags; protect status, wifi, history, and download routes - Stop pre-filling WiFi/MQTT/Web UI password fields; keep stored secrets on blank and add clear-password checkboxes - Add HTML escaping + URL encoding helpers and apply to user-controlled strings; add unit test - Harden /sd/download path validation (prefix, length, dotdot, slashes) and log rejections - Enforce protocol version in LoRa receive and release GPIO14 before SD init - Update README security, SD, and GPIO sharing notes
This commit is contained in:
23
README.md
23
README.md
@@ -31,10 +31,10 @@ Variants:
|
||||
- SCL: GPIO22
|
||||
- I2C address: 0x68
|
||||
- Battery ADC: GPIO35 (via on-board divider)
|
||||
- **Role select**: GPIO14 (INPUT_PULLDOWN, sampled at boot)
|
||||
- **Role select**: GPIO14 (INPUT_PULLDOWN, sampled at boot, **shared with SD SCK**)
|
||||
- HIGH = Sender
|
||||
- LOW/floating = Receiver
|
||||
- **OLED control**: GPIO13 (INPUT_PULLDOWN, sender only)
|
||||
- **OLED control**: GPIO13 (INPUT_PULLDOWN, sender only, **shared with SD CS**)
|
||||
- HIGH = force OLED on
|
||||
- LOW = allow auto-off after timeout
|
||||
- Not used on receiver (OLED always on)
|
||||
@@ -43,6 +43,9 @@ Variants:
|
||||
### Notes on GPIOs
|
||||
- GPIO34/35/36/39 are input-only and have **no internal pullups/pulldowns**.
|
||||
- Strap pins (GPIO0/2/4/5/12/15) can affect boot; avoid for role or control jumpers.
|
||||
- GPIO14 is shared between role select and SD SCK. **Do not attach the role jumper in Receiver mode if the SD card is connected/used**, and never force GPIO14 high when using SD.
|
||||
- GPIO13 is shared between OLED control and SD CS. Avoid driving OLED control when SD is active.
|
||||
- Receiver firmware releases GPIO14 to `INPUT` (no pulldown) after boot before SD SPI init.
|
||||
|
||||
## Firmware Roles
|
||||
### Sender (battery-powered)
|
||||
@@ -262,10 +265,20 @@ inline constexpr uint16_t EXPECTED_SENDER_IDS[NUM_SENDERS] = { 0xF19C };
|
||||
- `/wifi`: WiFi/MQTT/NTP config (AP and STA)
|
||||
- `/sender/<device_id>`: per-sender details
|
||||
- Sender IDs on `/` are clickable (open sender page in a new tab).
|
||||
- In STA mode, the UI is also available via the board’s IP/hostname on your WiFi network.
|
||||
- In STA mode, the UI is also available via the board's IP/hostname on your WiFi network.
|
||||
- Main page shows SD card file listing (downloadable).
|
||||
- Sender page includes a history chart (power) with configurable range/resolution/mode.
|
||||
|
||||
## Security
|
||||
- Basic Auth is supported for the web UI. In STA mode it is enabled by default; AP mode is optional.
|
||||
- Config flags in `include/config.h`:
|
||||
- `WEB_AUTH_REQUIRE_STA` (default `true`)
|
||||
- `WEB_AUTH_REQUIRE_AP` (default `false`)
|
||||
- `WEB_AUTH_DEFAULT_USER` / `WEB_AUTH_DEFAULT_PASS`
|
||||
- Web credentials are stored in NVS. `/wifi`, `/sd/download`, `/history/*`, `/`, `/sender/*`, and `/manual` require auth when enabled.
|
||||
- Password inputs are not prefilled. Leaving a password blank keeps the stored value; use the "clear password" checkbox to erase it.
|
||||
- User-controlled strings are HTML-escaped before embedding in pages.
|
||||
|
||||
## MQTT
|
||||
- Topic: `smartmeter/<deviceId>/state`
|
||||
- QoS 0
|
||||
@@ -303,6 +316,7 @@ Key timing settings in `include/config.h`:
|
||||
- `ENABLE_SD_LOGGING` / `PIN_SD_CS`
|
||||
- `SD_HISTORY_MAX_DAYS` / `SD_HISTORY_MIN_RES_MIN`
|
||||
- `SD_HISTORY_MAX_BINS` / `SD_HISTORY_TIME_BUDGET_MS`
|
||||
- `WEB_AUTH_REQUIRE_STA` / `WEB_AUTH_REQUIRE_AP` / `WEB_AUTH_DEFAULT_USER` / `WEB_AUTH_DEFAULT_PASS`
|
||||
|
||||
## Limits & Known Constraints
|
||||
- **Compression**: MeterData uses lightweight RLE (good for JSON but not optimal).
|
||||
@@ -320,6 +334,7 @@ Optional CSV logging to microSD (FAT32) when `ENABLE_SD_LOGGING = true`.
|
||||
`ts_utc,p_w,p1_w,p2_w,p3_w,e_kwh,bat_v,bat_pct,rssi,snr,err_m,err_d,err_tx,err_last`
|
||||
- `err_last` is written as text (`meter`, `decode`, `loratx`) only on the last sample of a batch that reports an error.
|
||||
- Files are downloadable from the main UI page.
|
||||
- Downloads only allow absolute paths under `/dd3/`, reject `..`, backslashes, and repeated slashes, and enforce a max path length.
|
||||
- History chart on sender page stream-parses CSVs and bins data in the background.
|
||||
- SD uses the on-board microSD SPI pins (CS=13, MOSI=15, SCK=14, MISO=2).
|
||||
|
||||
@@ -341,7 +356,7 @@ Optional CSV logging to microSD (FAT32) when `ENABLE_SD_LOGGING = true`.
|
||||
- `src/main.cpp`: role detection and main loop
|
||||
|
||||
## Quick Start
|
||||
1. Set role jumper on GPIO13:
|
||||
1. Set role jumper on GPIO14:
|
||||
- LOW: sender
|
||||
- HIGH: receiver
|
||||
2. OLED control on GPIO13:
|
||||
|
||||
Reference in New Issue
Block a user