max / makenotwork
1 file changed,
+8 insertions,
-8 deletions
| @@ -2,24 +2,24 @@ | |||
| 2 | 2 | ||
| 3 | 3 | Done: All pre-beta phases. Active: None. Next: Platform integration. | |
| 4 | 4 | ||
| 5 | - | v0.3.2. Audit grade A. 225 tests. | |
| 5 | + | v0.3.4. Audit grade A. 232 tests. | |
| 6 | 6 | ||
| 7 | 7 | --- | |
| 8 | 8 | ||
| 9 | 9 | ## Code Fuzz Findings (2026-04-26) | |
| 10 | 10 | ||
| 11 | 11 | ### Critical | |
| 12 | - | - [ ] Cross-community post removal via flag: `remove_flagged_post_handler` and `dismiss_flag_handler` verify mod/owner of the URL slug community but act on any `flag_id` without checking it belongs to that community. A mod of community-A can remove posts from community-B. Fix: after fetching the flag row, join through posts→threads→categories to get community_id and verify it matches. (`src/routes/flagging.rs:101,128`) | |
| 12 | + | - [x] Cross-community post removal via flag: scoped flag queries to community_id via JOIN chain. (fixed 2026-04-26) | |
| 13 | 13 | ||
| 14 | 14 | ### Serious | |
| 15 | - | - [ ] Cross-community category edit: `edit_category_handler` verifies owner of slug community, then updates any category by UUID. Fix: add `AND community_id = $2` to the UPDATE in `update_category`. (`src/routes/settings.rs:231`, `crates/mt-db/src/mutations.rs:349`) | |
| 16 | - | - [ ] Cross-community tag delete: `delete_tag_handler` verifies owner of slug community, then deletes any tag by UUID. Fix: add `AND community_id = $2` to the DELETE in `delete_tag`. (`src/routes/settings.rs:363`, `crates/mt-db/src/mutations.rs:666`) | |
| 17 | - | - [ ] Search query panics on multi-byte UTF-8: `&q[..200]` panics if byte 200 is mid-character. Fix: use `is_char_boundary` loop to find a safe truncation point. (`src/routes/search.rs:32`) | |
| 18 | - | - [ ] SSRF bypass in link preview via alternative IP encodings (octal, decimal, hex, shorthand, IPv6-mapped IPv4). String-based host check doesn't catch them. Fix: parse host with `std::net::IpAddr` to normalize all IP representations before checking private ranges. (`src/link_preview.rs:13`) | |
| 15 | + | - [x] Cross-community category edit: added `AND community_id = $2` to UPDATE. (fixed 2026-04-26) | |
| 16 | + | - [x] Cross-community tag delete: added `AND community_id = $2` to DELETE. (fixed 2026-04-26) | |
| 17 | + | - [x] Search query UTF-8 panic: use `is_char_boundary` loop for safe truncation. (fixed 2026-04-26) | |
| 18 | + | - [x] SSRF bypass in link preview: replaced string matching with `std::net::IpAddr` parsing + DNS resolution to catch all IP encodings. (fixed 2026-04-26) | |
| 19 | 19 | ||
| 20 | 20 | ### Minor | |
| 21 | - | - [ ] `parse_duration` silently defaults unknown strings to permanent ban (e.g. typo "3d" → permanent). Fix: return error on unrecognized values. (`src/routes/helpers.rs:275`) | |
| 22 | - | - [ ] `/internal/threads/{id}/stats` is unauthenticated and publicly accessible (thread UUIDs visible in URLs). Fix: add `InternalAuth` extractor or accept the info leak. (`src/routes/internal.rs:276`) | |
| 21 | + | - [x] `parse_duration` silent default to permanent: now returns error on unrecognized values. (fixed 2026-04-26) | |
| 22 | + | - [x] `/internal/threads/{id}/stats` unauthenticated: added HMAC verification + signed GET in MNW client. (fixed 2026-04-26) | |
| 23 | 23 | - [ ] `auto_hide_if_threshold_met` records the flagger's user_id as `removed_by`, not a system/mod account. Misleading audit trail. (`src/routes/flagging.rs:82`) | |
| 24 | 24 | - [ ] `/search` endpoint has no rate limiting (GET in read_routes). Full-text + trigram similarity queries are expensive. Fix: add per-IP rate limit or move to write_routes group. (`src/routes/search.rs`) | |
| 25 | 25 |