Skip to content

fix: security hardening and data-correctness bugs#31

Merged
jaywyawhare merged 2 commits into
masterfrom
fix/security-bugs-and-data-correctness
Apr 29, 2026
Merged

fix: security hardening and data-correctness bugs#31
jaywyawhare merged 2 commits into
masterfrom
fix/security-bugs-and-data-correctness

Conversation

@jaywyawhare
Copy link
Copy Markdown
Owner

Summary

  • S1 Timing-safe API key comparison — replaced strcmp with crypto_constant_time_compare
  • S4 HMAC RFC 2104 compliance — hash keys >64 bytes before XOR (both sign and verify paths)
  • S5 PKCS7 padding — validate all padding bytes, not just the last one
  • S6 Decrypt file IV-chaining bug — was reading from plaintext buffer instead of ciphertext
  • S8 JWT subject injection — JSON-escape subject string before interpolating into payload
  • S12 Filter expression injection — escape metadata keys (not just values) before building expr
  • B1 database.c — remove duplicate sparse_index = NULL assignment
  • B3 Single-vector REST add — use db_add_vector_with_rich_metadata so all metadata keys are stored (was silently dropping all but the first)
  • B8 Dashboard backup restore — close old DB handle before swapping to prevent FD leak
  • B9 Backup checksum — force null-terminate header.checksum buffer before strcmp
  • B10/B11 Backup fwrite/ftell — check return values and fail fast on disk-full or seek error

Test plan

  • Build passes with existing make / cmake pipeline
  • Run python/tests/test_api.py — existing tests pass
  • Run test_gigavector.py — backup/restore tests pass
  • Manually verify API-key auth still works after timing-safe change
  • Verify JWT issue/verify round-trip with secrets of various lengths (< 64, exactly 64, > 64 bytes)

🤖 Generated with Claude Code

- 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>
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 28, 2026

Greptile Summary

This PR addresses a solid set of security hardening and data-correctness fixes across the codebase. All fixes are well-targeted, with one regression introduced in the timing-safe auth change.

  • P1 — src/api/server.c: The !auth null-guard that was part of the original if (!auth || strcmp(...)) was dropped in the rewrite. Any request sent without an X-API-Key or Authorization header leaves auth = NULL, and the immediately-following strlen(auth) call dereferences a null pointer, crashing the server process.

Confidence Score: 4/5

Not safe to merge as-is — any unauthenticated HTTP request crashes the server due to a null-pointer dereference introduced by the timing-safe auth rewrite.

All other fixes (PKCS7, CBC IV-chaining, HMAC key hashing, filter-key escaping, backup error handling, metadata storage) are correct. One P1 regression in server.c must be resolved before merging.

src/api/server.c — missing null-guard for auth before strlen call

Important Files Changed

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

Comment thread src/api/server.c
Comment on lines +241 to +242
size_t key_len = strlen(server->config.api_key);
size_t auth_len = strlen(auth);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 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.

Suggested change
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.
@jaywyawhare jaywyawhare force-pushed the fix/security-bugs-and-data-correctness branch from f596961 to cd5dbaa Compare April 29, 2026 08:40
@jaywyawhare jaywyawhare merged commit 78fbc07 into master Apr 29, 2026
5 checks passed
@jaywyawhare jaywyawhare deleted the fix/security-bugs-and-data-correctness branch April 29, 2026 10:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant