fix: security hardening and data-correctness bugs#31
Conversation
- Timing-safe API key comparison (strcmp → crypto_constant_time_compare) - HMAC: hash keys >64 bytes before XOR (RFC 2104 compliance) - JWT subject JSON-escaping to prevent claim injection - PKCS7: validate all padding bytes, not just the last one - Decrypt file IV-chaining bug fixed (was using plaintext instead of ciphertext) - Filter expression: escape metadata keys, not just values - Single-vector REST add now stores all metadata entries (was dropping all but first) - Backup restore: close old DB handle before replacing (FD leak) - Backup checksum: force null-terminate before strcmp - Backup fwrite: check return values, fail fast on disk-full - database.c: remove duplicate sparse_index = NULL assignment Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
| Filename | Overview |
|---|---|
| src/api/server.c | Timing-safe API key comparison introduced but the !auth null-guard was dropped, causing a null-pointer dereference (crash) on any request with no auth header. |
| src/security/auth.c | RFC 2104 key hashing (>64-byte keys) correctly applied to both auth_generate_jwt and auth_verify_jwt; subject JSON-escaping looks correct. |
| src/security/crypto.c | PKCS7 full-padding validation and file-decrypt CBC IV-chaining fix both look correct. |
| src/api/rest_handlers.c | All-metadata storage via db_add_vector_with_rich_metadata and filter-key escaping both correct; partial-malloc fallback is safe. |
| src/storage/backup.c | ftell/fwrite error checks and checksum null-termination all look correct. |
| python/src/gigavector/dashboard/backend/server.py | Old DB handle is correctly saved and closed after the swap, preventing the FD leak. |
| src/storage/database.c | Duplicate sparse_index = NULL assignment removed — trivial cleanup. |
Reviews (1): Last reviewed commit: "fix: security hardening and data-correct..." | Re-trigger Greptile
| size_t key_len = strlen(server->config.api_key); | ||
| size_t auth_len = strlen(auth); |
There was a problem hiding this comment.
Null-pointer dereference when no auth header is supplied
When neither X-API-Key nor Authorization is present, both MHD_lookup_connection_value calls return NULL and auth stays NULL. The old guard !auth || was dropped in this rewrite, so strlen(auth) on line 242 immediately dereferences a null pointer — any unauthenticated request crashes the server.
| size_t key_len = strlen(server->config.api_key); | |
| size_t auth_len = strlen(auth); | |
| if (!auth) { | |
| return 0; | |
| } | |
| size_t key_len = strlen(server->config.api_key); | |
| size_t auth_len = strlen(auth); |
Dropped in the timing-safe rewrite; unauthenticated requests crashed the server with a null-pointer dereference.
f596961 to
cd5dbaa
Compare
Summary
strcmpwithcrypto_constant_time_comparedatabase.c— remove duplicatesparse_index = NULLassignmentdb_add_vector_with_rich_metadataso all metadata keys are stored (was silently dropping all but the first)header.checksumbuffer beforestrcmpfwrite/ftell— check return values and fail fast on disk-full or seek errorTest plan
make/cmakepipelinepython/tests/test_api.py— existing tests passtest_gigavector.py— backup/restore tests pass🤖 Generated with Claude Code