| Version | Supported |
|---|---|
| >= 0.4.11 | ✅ |
Please open a GitHub issue with the type:security label, or contact the maintainers directly.
Status: Fixed in v0.4.12
Issue: SEC-002 (#71)
Problem: The Installer::install() method previously used tempnam() + .tar.gz suffix to create a temporary download file. An attacker with local filesystem access could predict the path and plant a symlink, causing the downloaded archive to be written to an attacker-controlled location (arbitrary file write). The orphaned tempnam() file was also never cleaned up.
Solution: The temporary file strategy was replaced with a cryptographically random directory (128 bits via random_bytes(8) + bin2hex), created with mkdir() at permission 0700:
$tmpDir = sys_get_temp_dir() . '/zvec_ffi_' . bin2hex(random_bytes(8));
mkdir($tmpDir, 0700, true);
$tmpFile = $tmpDir . '/download.tar.gz';
Key properties:
- Defense-in-depth:
mkdir()with 0700 permissions creates a directory only the current user can access. An attacker cannot create symlinks inside a directory they cannot traverse. - Atomic creation:
mkdir()either succeeds or fails — there is no gap between existence check and use. - Single random name: 128 bits of cryptographic randomness (
random_bytes(8)= 16 hex chars) makes path prediction infeasible. - No stale files: The
finallyblock doesrm -rfon the entire temp directory, eliminating orphaned files. - No external dependencies: Uses only PHP built-in functions.
Status: Fixed in v0.4.12
Issue: SEC-001 (#70)
Problem: The Installer::install() method downloaded the FFI shared library without verifying its integrity. A compromised release artifact or man-in-the-middle attack could serve a malicious .so/.dylib file.
Solution: SHA-256 checksums are published alongside each release in checksums.sha256. Before extracting, Installer::verifyChecksum() computes hash_file('sha256', ...) and compares it against the expected hash using hash_equals() (timing-safe comparison).
Status: In Progress (SEC-004 #73)
All C++ FFI functions accept opaque handle types. When these are null (e.g., after destroy or invalid state), null-pointer dereference causes segfaults. The fix adds null-pointer guards to all 50+ handle-accepting functions.
- Local filesystem security: The temp directory fix (SEC-002) assumes the attacker already has local user access. It prevents privilege escalation via symlink attacks.
- TLS is not explicitly pinned: The download stream context sets
verify_peerandverify_peer_nameto true, relying on the system's CA bundle. No certificate pinning is implemented. - API keys in memory: Embedding function API keys are stored in PHP string properties and are not explicitly zeroed after use. This is a known limitation (see SEC-008).