Items not yet fixed from the full audit. Organized by repo.
- N+1 in
directory_jsonfile_count — Each directory triggers a separate COUNT query in index. Fix: counter_cache or preloaded counts with subquery. (app/controllers/api/v1/directories_controller.rb) - N+1 in
UserDirectory#path_display— Recursive parent loading for path construction. O(depth × N) queries on manifest endpoint. Fix: materialized path column. (app/models/user_directory.rb:33-43) changesAPI limit logic bug —fetch_file_changesqueries both active AND deleted with same limit, so actual count can be up to 2× limit.has_morecan give false positives causing sync clients to loop. (app/controllers/api/v1/sync_controller.rb:10-23)- No Content-Type validation on upload — Only extension denylist enforced.
.html/.svgfiles could contain scripts. ConsiderContent-Disposition: attachmenton S3 objects. (app/uploaders/file_uploader.rb)
- No
resolve_sync_clientkey format validation — Any string accepted for X-Client-Key header. Not exploitable but could lead to junk data. (app/controllers/api/v1/base_controller.rb:52-57) - Missing pagination on
files#indexanddirectories#index— Returns ALL records with no limit/offset. (app/controllers/api/v1/files_controller.rb:10,directories_controller.rb:8) parse_timestampfallback — Invalid timestamps silently fall back to 1 year ago, returning huge volume of changes. Consider returning error. (app/controllers/api/v1/sync_controller.rb:85)
remoteToLocalno Unicode normalization — macOS NFD vs Linux NFC decomposition could create duplicate sync entries cross-platform. (pkg/sync2/engine.go:686-701)- PID file race — Two daemon starts can race on PID file write. No flock. (
cmd/izerop/main.go:929) filepath.WalkTOCTOU on symlink check —infofrom Walk usesos.Stat(follows symlinks), thenos.Lstatis called separately. Symlink could be swapped between calls. Low practical risk. (pkg/sync2/engine.go:299-308)- Binary update delete+create non-atomic — Updating binary files deletes remote first then re-uploads. Crash between = file lost on server. Fix: upload with temp name, delete old, rename. (
pkg/sync2/engine.go:519-521)
- Download timeout fixed at 120s — Not configurable, could be insufficient for large files on slow connections. (
pkg/api/client.go:285) SyncPulluses recursion for pagination —HasMoretriggers recursive call. Many pages could stack overflow. Use iteration. (pkg/sync2/engine.go:232-245)addWatchRecursivecan hit inotify limits — Error fromfsw.Add(path)is returned but walk continues. Some dirs silently unwatched. (pkg/sync2/watcher.go:278-290)- Config tokens stored as plaintext — File permissions are 0600 (good) but visible to same-user processes. Consider OS keychain. (
pkg/config/config.go:16) If-Matchheader quoting — Set as"hash"(quoted). Works if server strips quotes per RFC 7232, but could fail on strict implementations. (pkg/api/client.go:439)- Test cleanup via
init()fragile — Should uset.Cleanup()per-test. (pkg/sync2/engine_test.go:893-907)
- No tests for
SyncPull(cursor-based changes API path) - No tests for
SyncPush(only fullSynctested) - No tests for path traversal (
safePathvalidation) - No tests for conflict resolution (
ResolveConflict) - No tests for v1→v2 migration (
MigrateFromV1) - No tests for the watcher (fsnotify → push cycle)
- No tests for symlink handling in
buildLocalTree - No tests for concurrent sync (two engines on same profile)
- No tests for binary file upload (delete+create path)
- No tests for error recovery (API failures mid-sync)