If you discover a security vulnerability in thetadatadx, please report it responsibly:
- Do NOT open a public GitHub issue for security vulnerabilities
- Email: security@thetadatadx.dev (or open a private security advisory on GitHub)
- Include:
- Description of the vulnerability
- Steps to reproduce
- Potential impact
- Suggested fix (if any)
We will acknowledge receipt within 48 hours and aim to release a fix within 7 days for critical issues.
| Version | Supported | Notes |
|---|---|---|
| 1.2.x | ✅ | Current release |
| 1.1.x | ❌ | Contract wire format bug — upgrade to 1.2.x |
| < 1.1 | ❌ |
Important: Versions prior to 1.2.0 contain a contract wire format bug that could produce incorrect wire bytes for option contracts, causing subscription failures or wrong contract assignments. All users should upgrade to 1.2.x.
The ThetaData terminal ships with a hardcoded API key that is identical across all installations. This is not a secret — it is a protocol constant embedded in every copy of the Java terminal. thetadatadx includes this key for protocol compatibility. It provides no privileged access.
- User credentials (email/password) are used for both Nexus auth and FPSS authentication
- The
Debugtrait implementation forCredentialsredacts passwords — they never appear in debug output or log lines AuthRequest(internal HTTP body struct) does not deriveDebug— prevents accidental password exposure in error traces- Session UUIDs (bearer tokens for MDDS gRPC) are logged at
debug!level only, redacted to first 8 characters. They never appear atinfo!or higher. - Credentials are not persisted to disk by the library (the
creds.txtfile is user-managed and excluded from version control via.gitignore)
All network operations enforce timeouts to prevent indefinite hangs:
- Nexus auth HTTP: 10s request timeout, 5s connect timeout
- MDDS gRPC: connect timeout + keepalive from
DirectConfig - FPSS TCP+TLS: connect timeout wraps both TCP and TLS handshake
- FPSS read loop: read timeout matching Java's
SO_TIMEOUT=10s
All network connections use a unified TLS stack (rustls with ring backend):
- MDDS (gRPC): TLS via
tonic+rustls - FPSS (streaming): TLS via
tokio-rustls+rustls - Nexus auth (HTTP): TLS via
reqwest+rustls
Root certificates come from webpki-roots (Mozilla's CA bundle). Certificate
validation is enforced on all connections — there is no option to skip verification.
As of v1.2.0, FPSS credential length fields are read as unsigned integers (matching Java's
readUnsignedShort()). Previous versions used signed reads, which could cause a sign-extension
bug for passwords longer than 127 bytes. This did not leak credentials but could cause
authentication failures.
DirectClient enforces a semaphore (mdds_concurrent_requests) that limits the number of
in-flight gRPC requests. The default is dynamically derived from the user's subscription
tier (2^tier), matching the Java terminal's concurrency model. This prevents runaway
request storms from overwhelming the upstream MDDS server or triggering server-side rate
limiting.
As of v1.2.0, decompress_response returns an error for unrecognized compression algorithms
instead of silently treating the data as uncompressed. This prevents corrupt data from being
silently passed to callers.
FPSS streaming uses a fully synchronous I/O thread with a lock-free disruptor ring buffer
(disruptor-rs v4) for event dispatch. The bounded ring buffer prevents unbounded memory
growth from unconsumed events.
Binary frame size assertions use assert! (not debug_assert!), ensuring they
are enforced in release builds. This prevents oversized frames from causing
unbounded memory allocation.
We use cargo-deny to audit dependencies for:
- Known vulnerabilities (RustSec advisory database)
- License compliance
- Duplicate crate versions
See deny.toml for the full configuration.