EXTENDED DOCUMENTATION

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:

  • text
    contracts/MorpheusOracle/MorpheusOracle.cs
  • text
    contracts/neox/contracts/MorpheusOracleX.sol
  • text
    workers/morpheus-relayer/src/relayer.js

Current behavior:

  • the relayer asks the worker to sign only the callback
    text
    result
  • both contracts verify only that signature over
    text
    result
  • text
    requestId
    ,
    text
    requestType
    ,
    text
    success
    , and
    text
    error
    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:
    • text
      requestId
    • text
      requestType
    • text
      success
    • text
      result
    • text
      error

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

text
contracts/neox/contracts/MorpheusOracleX.sol
:

  • text
    requestType
    length capped at
    text
    64
  • text
    callbackMethod
    length capped at
    text
    64
  • text
    payload
    size capped at
    text
    4096
  • Oracle encryption
    text
    algorithm
    capped at
    text
    64
  • Oracle encryption
    text
    publicKey
    capped at
    text
    2048

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
    text
    getCallback(uint256)

3. DataFeed not-found behavior differed across chains

Fixed in

text
contracts/neox/contracts/MorpheusDataFeedX.sol
:

  • text
    getLatest(pair)
    now returns a default record with the queried
    text
    pair
    instead of an empty string pair

4. DataFeed source-set and attestation constraints were looser on N3

Fixed in

text
contracts/MorpheusDataFeed/MorpheusDataFeed.cs
:

  • text
    sourceSetId >= 0
  • text
    attestationHash.length <= 32

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
  • text
    vm
    timeout interrupts synchronous infinite loops
  • worker termination timeout handles non-terminating async execution
  • configurable with:
    • text
      ORACLE_SCRIPT_TIMEOUT_MS
    • text
      COMPUTE_SCRIPT_TIMEOUT_MS

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:
    • text
      ORACLE_TIMEOUT
    • text
      ORACLE_MAX_UPSTREAM_BODY_BYTES

7. Compute entry-point name allowed identifier injection risk

Fixed in

text
workers/phala-worker/src/compute/index.js
:

  • text
    entry_point
    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
    text
    script_ref
    , but the fetched source still passes the same script-policy checks and size limits

Configurable with:

  • text
    COMPUTE_MAX_INPUT_BYTES
  • text
    ORACLE_MAX_SCRIPT_INPUT_BYTES
  • text
    SCRIPT_WORKER_MAX_RESULT_BYTES
  • text
    WASM_CHILD_MAX_RESULT_BYTES
  • text
    MORPHEUS_MAX_REGISTERED_SCRIPT_BYTES

8. Browser admin keys were persisted too broadly

Fixed in frontend admin panels:

  • provider-config admin key now uses
    text
    sessionStorage
    , not
    text
    localStorage
  • relayer-ops admin key now uses
    text
    sessionStorage
    , not
    text
    localStorage
  • 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
    text
    MORPHEUS_PROVIDER_CONFIG_API_KEY
  • relayer operation routes now prefer
    text
    MORPHEUS_RELAYER_ADMIN_API_KEY
  • signing routes now prefer
    text
    MORPHEUS_SIGNING_ADMIN_API_KEY
  • relay transaction routes now prefer
    text
    MORPHEUS_RELAY_ADMIN_API_KEY
  • text
    MORPHEUS_OPERATOR_API_KEY
    and legacy
    text
    ADMIN_CONSOLE_API_KEY
    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
    text
    morpheus_operation_logs
    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
    text
    morpheus_encrypted_secrets
    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
text
.env
value overrode the intended network

Fixed in scripts, worker, relayer, and Phala env generation:

  • network-scoped Neo N3 signer resolution now prefers
    text
    NEO_TESTNET_WIF
    when
    text
    MORPHEUS_NETWORK=testnet
  • generated Phala env files are now split into
    text
    morpheus.mainnet.env
    and
    text
    morpheus.testnet.env
  • text
    phala.request-hub.toml
    and
    text
    phala.feed-hub.toml
    now bind each role-split CVM to the correct generated env file
  • frontend runtime defaults now resolve the selected network's Phala endpoint from
    text
    config/networks/*.json

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
    text
    network
    scoping across active Supabase tables
  • changed project uniqueness from
    text
    slug
    to
    text
    (network, slug)
  • provider config lookup now resolves by
    text
    project_slug + network
  • 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
    text
    demo
    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
    text
    GET /info
  • public
    text
    GET /attestation
  • authenticated
    text
    GET /keys/derived
  • optional response-side quote attachment when
    text
    PHALA_EMIT_ATTESTATION=true
  • derived Neo N3 signing fallback when
    text
    PHALA_USE_DERIVED_KEYS=true
  • stable Oracle X25519 transport key using dstack-derived wrapping key + sealed keystore
  • verifier API and
    text
    /verifier
    demo flow for application-level attestation checks

Remaining architectural notes

  • N3 contracts still expose an explicit admin-only
    text
    Update(...)
    , 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
    text
    deploy/phala/morpheus.mainnet.env
    and
    text
    deploy/phala/morpheus.testnet.env
    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

  • text
    npm --prefix workers/phala-worker run check
  • text
    npm --prefix workers/phala-worker test
  • text
    npm --prefix contracts/neox test
  • text
    dotnet test contracts/__tests__/NeoContracts.Tests.csproj
  • text
    node examples/scripts/test-neox-examples.mjs
  • text
    node examples/scripts/test-n3-examples.mjs
  • live Phala health and public-key endpoint verification
  • live Supabase write verification for
    text
    morpheus_operation_logs
    and
    text
    morpheus_encrypted_secrets
  • standalone AA verifier / hook validation in the active
    text
    neo-abstract-account
    test suite
  • cross-system attack coverage through the current integrated regression scripts
CURRENT DESIGNUPDATED FOR DUAL-CVM ARCHITECTURE
Morpheus Oracle