Zer0Fit v1.0.1 — Code Review Hardening Release
Zer0Fit v1.0.1 — Code Review Hardening Release
This release incorporates findings from two rounds of Claude Opus 4.6 code review covering security hardening, performance improvements, and bug fixes across all source files.
🔒 Security
- IDOR prefix strengthened: WebUI file ID matching now requires 32+ character prefixes (was 8), preventing brute-force file discovery in multi-user environments
- Symlink escape prevention: Upload directory lookups now verify realpath containment (matching the existing WebUI upload path check)
- TOCTOU race hardened: WebUI upload symlink check now rejects symlinks outright with
os.path.islink()before resolving, preventing time-of-check-time-of-use attacks - Dockerfile non-root user: The server now runs as
zer0fituser instead ofroot, reducing blast radius from container escapes - Specific exception handling: File parse errors now catch specific exceptions (ParserError, EmptyDataError, etc.) instead of bare
except Exception
🐛 Bug Fixes
- Install.sh orphaned processes: Fixed subshell scoping bug that prevented
LOG_PIDfrom being captured — backgrounddocker compose logsprocesses are now properly killed and waited on - Model inference blocking event loop: TimesFM forecast and TabFM inference are now wrapped in
asyncio.to_thread()with timeouts (120s / 300s), preventing event-loop blocking and hung requests - JSON/JSONL OOM risk:
_read_tabular_filenow enforcesnrowstruncation for JSON formats (was already enforced for CSV/Excel), preventing unbounded RAM consumption on large uploads - Trailing-separator consistency:
_cleanup_uploadssymlink escape check now adds trailing separator on both sides for correct path matching _cleanup_uploadssilent error masking: BareOSErrorcatch refined to distinguishFileNotFoundError(benign race) from other errors (logged as warnings)
🛠️ Infrastructure
- Fixed JAX/numpy incompatibility preventing TabFM preload: TabFM's
classifier_and_regressor.pyimports JAX at module level (wrapped in try/except ImportError). JAX v0.10+ requires numpy 2.0+ (StringDType), but the project pins numpy <2.0.0 for TimesFM compatibility. Since the PyTorch backend doesn't need JAX at all, the Dockerfile now uninstalls jax/jaxlib after installing TabFM dependencies, allowing the try/except fallback to activate. Removed chex, optax, and orbax-checkpoint (the transitive deps pulling in JAX) from the dependency list. - HF cache path mismatch fixed: Dockerfile now sets
HF_HOME=/app/.cache/huggingfacefor a deterministic cache path regardless of container user; install.sh health check updated to match (was checking/root/.cache/which doesn't exist with thezer0fituser) .env.exampledefaults: Changed from ARM64 to x86_64 (amd64) to match docker-compose.yml defaults, with comments explaining both architectures
🧹 Cleanup
_json_saferenamed to_json_safe_scalar— now handlesnp.ndarrayvia.tolist()andnp.str_viastr()conversion- Removed unused
fastapidependency (server uses Starlette directly) - Deprecated pandas alias:
"H"→"h"frequency alias for pandas 2.2+ compatibility - Late imports moved to top:
StreamableHTTPSessionManagerandasynccontextmanagernow imported at the top ofserver.py - docker-compose.yml defaults: Architecture defaults changed from ARM64 to x86_64 (more common for GPU servers)
- install.sh version: Added
ZER0FIT_VERSIONvariable shown in banner, build summary, and success message
🩺 Performance
- Inference timeout: TimesFM forecast now has a 2-minute timeout, TabFM inference has a 5-minute timeout — prevents model hangs from blocking VRAM
Full diff: v1.0.0...v1.0.1