Security Audit Notes
Date: 2026-03-13
Executive Summary
The current system is materially stronger than earlier iterations and is operating successfully on testnet. The worker, relayer, and contracts passed the current test suite and real end-to-end chain validation.
However, one protocol-level finding remains open and should be treated as the primary unresolved security issue before claiming a fully hardened production posture.
Current architecture assumptions in scope:
- Cloudflare owns public ingress, orchestration, and recovery outside the TEE
- Supabase owns durable job and operational state
- the Oracle CVM handles request/response oracle, compute, NeoDID, and paymaster authorization
- the DataFeed CVM stays isolated so continuous price publication is not starved by interactive work
Scope
- Neo N3 contracts
- Neo X contracts
- confidential Oracle runtime privacy Oracle and compute execution paths
- NeoDID bind / ticket issuance and public DID resolution surfaces
- Relayer callback fulfillment path
- Web admin/control-plane surfaces
Open Findings
High: fulfillment signatures do not bind full callback context
Status: open
Affected files:
Current behavior:
- the relayer asks the worker to sign only the callback
- both contracts verify only that signature over
- , , , and are not covered by the worker signature
Impact:
- if the updater/relayer key is compromised, an attacker can finalize pending requests with a mismatched success/error context while still presenting a valid worker signature over some result bytes
- this weakens non-repudiation of the full callback envelope
Required fix:
- change the worker, relayer, and both contracts to verify a canonical fulfillment envelope that binds:
This requires a coordinated contract upgrade on both chains.
Findings addressed
1. Neo X request and key size guards were weaker than Neo N3
Fixed in
:- length capped at
- length capped at
- size capped at
- Oracle encryption capped at
- Oracle encryption capped at
2. Callback consumer parity gaps
Fixed parity between N3 and Neo X:
- N3 callback consumer now emits admin/oracle change events
- Neo X callback consumer now exposes
3. DataFeed not-found behavior differed across chains
Fixed in
:- now returns a default record with the queried instead of an empty string pair
4. DataFeed source-set and attestation constraints were looser on N3
Fixed in
:5. Privacy Oracle and compute script execution could hang indefinitely
Fixed in worker runtime:
- Oracle programmable scripts now run in a separate worker thread
- Compute scripts now run in a separate worker thread
- timeout interrupts synchronous infinite loops
- worker termination timeout handles non-terminating async execution
- configurable with:
6. Upstream Oracle fetches could hang indefinitely
Fixed in worker runtime:
- all provider fetches support timeout/abort
- direct Oracle HTTP fetches support timeout/abort
- upstream Oracle / provider responses now have a hard maximum body size
- configurable with:
7. Compute entry-point name allowed identifier injection risk
Fixed in
:- must match a valid JS identifier
7b. Untrusted compute/oracle payloads could still attempt large input/result amplification
Fixed in worker runtime:
- compute input payloads now have a maximum serialized size
- oracle programmable input payloads now have a maximum serialized size
- script worker results now have a maximum serialized size
- wasm worker results now have a maximum serialized size
- script bodies can be fetched by , but the fetched source still passes the same script-policy checks and size limits
Configurable with:
8. Browser admin keys were persisted too broadly
Fixed in frontend admin panels:
- provider-config admin key now uses , not
- relayer-ops admin key now uses , not
- browser restart no longer silently retains privileged admin keys
9. One admin key previously covered too many backend capabilities
Fixed in web API auth routing:
- provider config routes now prefer
- relayer operation routes now prefer
- signing routes now prefer
- relay transaction routes now prefer
- and legacy remain optional fallback keys for compatibility
10. API operations were not comprehensively persisted, and encrypted request fields were not guaranteed to be stored as ciphertext
Fixed in web/API layer:
- added for API operation auditing
- added route-level and proxy-level logging for Oracle, Compute, Feed, Runtime, Attestation, Provider Config, Relayer, Signing, and Relay routes
- encrypted request fields are now extracted and stored in as ciphertext without decryption
- plaintext secret-like keys are redacted before operation-log persistence
11. Mainnet and testnet signer/env selection could drift when a root value overrode the intended network
Fixed in scripts, worker, relayer, and Phala env generation:
- network-scoped Neo N3 signer resolution now prefers when
- generated Phala env files are now split into and
- and now bind each role-split CVM to the correct generated env file
- frontend runtime defaults now resolve the selected network's Phala endpoint from
Security impact:
- prevents accidental mainnet signer leakage into testnet test runs
- reduces the risk of producing tainted validation artifacts that mix the wrong RPC, contract hash, or CVM metadata
12. Supabase data from mainnet and testnet could be mixed under shared slugs and shared operational tables
Fixed in schema and application logic:
- added scoping across active Supabase tables
- changed project uniqueness from to
- provider config lookup now resolves by
- relayer, automation, encrypted secret, backup, and operation-log writes now stamp the current network
- relayer admin queries and attestation lookup now filter by network
Security and ops impact:
- prevents testnet relayer jobs, encrypted refs, and automation state from appearing in mainnet operator views
- prevents a shared slug like from resolving to the wrong environment's provider config
- reduces the risk of cross-environment data leakage when one Supabase instance backs both networks
Phala tappd / attestation progress
The worker now includes first-stage and second-stage Phala dstack/tappd integration:
- public
- public
- authenticated
- optional response-side quote attachment when
- derived Neo N3 signing fallback when
- stable Oracle X25519 transport key using dstack-derived wrapping key + sealed keystore
- verifier API and demo flow for application-level attestation checks
Remaining architectural notes
- N3 contracts still expose an explicit admin-only , while the Neo X contracts are currently non-upgradeable plain contracts. This is a lifecycle difference, not an immediate exploitable vulnerability.
- Relayer-side transaction signing now supports dstack-derived key fallback for N3 and Neo X fulfill transactions, but explicit env keys are still supported as operational overrides.
- The public NeoDID DID resolver should remain metadata-only. It must not be extended to expose provider UIDs, Web3Auth JWT claims, master nullifiers, action nullifiers, or decrypted confidential payloads.
- The locally ignored generated files and can contain live operational secrets and private keys. They are ignored by git, but they still represent workstation secret concentration risk and should be handled as sensitive operator material.
Validation
- live Phala health and public-key endpoint verification
- live Supabase write verification for and
- standalone AA verifier / hook validation in the active test suite
- cross-system attack coverage through the current integrated regression scripts