Skip to content

Security Implementation ​

VIZ Ledger's security model rests on three pillars: threshold-based authority verification, deterministic signature validation, and encrypted peer transport. This page covers each subsystem and provides guidance for operators and plugin developers.


Authority Model ​

Every account has three authority levels — master, active, and regular — each represented as a weighted set of keys and/or account references with a weight threshold.

Authority {
    weight_threshold: uint32
    key_auths:     { PublicKey → weight }
    account_auths: { AccountName → weight }
}

An operation is authorized when the sum of weights of provided signatures (and recursively resolved account authorities) meets or exceeds weight_threshold.

Recursion depth is bounded to prevent infinite loops in nested account authority chains.

The same authority structure is stored in shared memory as SharedAuthority, which uses inter-process allocators compatible with Boost.Interprocess mapped files.


Signature Validation ​

Transaction signature validation uses deterministic secp256k1 ECDSA:

  1. Digest: sha256(chain_id || serialized_transaction)
  2. Recovery: secp256k1_recover(signature, digest) → public key
  3. Authority check: sign_state.check_authority(account, level) walks the authority tree and verifies the recovered key set satisfies the threshold.

The sign_state engine:

  • Maintains a set of provided signatures and their recovered keys.
  • Recursively resolves account authorities up to the maximum depth.
  • Filters unused signatures after verification.

For plugin developers: Use the auth_util plugin's check_authority_signature API to verify signatures before processing sensitive operations:

json
{
  "method": "auth_util.check_authority_signature",
  "params": ["alice", "regular", "<hex_digest>", ["<sig1>", "<sig2>"]]
}

Returns the set of verified signing keys if the authority is satisfied, or an error if it is not.


Peer Transport Encryption ​

All peer-to-peer connections use ECDH key exchange + AES stream encryption:

  1. Each side generates an ephemeral key pair on connection.
  2. ECDH produces a shared secret from the ephemeral keys.
  3. AES encoder/decoder streams are initialized with the shared secret.
  4. All subsequent messages are encrypted.

This prevents passive eavesdropping. Every connection uses a fresh ephemeral key, so compromise of one session does not affect others.

The implementation lives in stcp_socket (libraries/network/stcp_socket.cpp).


API Exposure ​

The webserver plugin serves JSON-RPC over HTTP and WebSocket. Security configuration:

ini
# Bind to loopback for internal access only
webserver-http-endpoint = 127.0.0.1:8090
webserver-ws-endpoint = 127.0.0.1:8091

# Use a reverse proxy (nginx, caddy) for public access with TLS

Thread pool sizing: The webserver runs a configurable number of threads. Set webserver-thread-pool-size to match expected concurrent request load. Undersizing causes request queuing; oversizing wastes resources.

ini
webserver-thread-pool-size = 4

Network Security Measures ​

  • Encrypted channels: All peer connections are encrypted (ECDH + AES). Passive eavesdropping is not possible.
  • Peer database: The P2P node maintains a peer database and propagation timing metadata.
  • Soft bans: Peers that behave incorrectly (send invalid blocks, fork-only data with no progress) receive temporary soft bans rather than permanent disconnection.
  • Bandwidth limits: Configurable via max-send-buffer-size and related P2P options.

Vulnerability Assessment ​

Common risks:

RiskMitigation
Authority bypass via malformed signaturesBounded recursion depth; strict weight-threshold checking
Weak randomness in ephemeral keysUses secp256k1's deterministic key generation
MitM on unencrypted RPCBind webserver to loopback; use TLS reverse proxy for public endpoints
DoS via oversized payloadsJSON-RPC payload size limits; webserver thread pool controls concurrency
Nested authority exhaustionMaximum recursion depth enforced in sign_state

Penetration testing checklist:

  • Submit malformed or incomplete signatures to verify authority bypass protection.
  • Test recursion depth limits with deeply nested account authority chains.
  • Verify transport encryption with a network capture (no plaintext should appear on the wire).
  • Stress-test the webserver endpoint for memory exhaustion and queue saturation.

Security Best Practices for Plugin Development ​

Input validation:

  • Reject malformed or oversized JSON-RPC payloads at plugin boundaries.
  • Validate all parameters against their expected types and ranges before processing.

Authentication:

  • Always use auth_util.check_authority_signature before applying state changes that require authorization.
  • Never trust account names or key references without verifying signatures.

Constant-time comparisons:

  • Use fc::crypto::secure_compare or equivalent for secret comparisons to prevent timing side-channels.

No plaintext credentials:

  • Never store private keys in plugin state or logs.
  • Derive ephemeral keys per session; never reuse.

Threat model per authority level:

  • regular authority: social/content operations — lowest privilege.
  • active authority: funds, staking, voting — medium privilege.
  • master authority: key rotation, recovery — highest privilege. Require explicit user confirmation in any UI.

Monitoring and Incident Response ​

Metrics to monitor:

  • Peer connection count and churn rate.
  • Webserver thread pool queue depth and response latency.
  • Failed signature validation rate (visible in logs at warn level).
  • Bandwidth per peer connection.

Incident response:

  1. Isolate the affected endpoint (restrict webserver-http-endpoint to loopback).
  2. Rotate signing keys via the master authority if a validator key is compromised.
  3. Re-validate account authorities after key rotation.
  4. Review logs around sign_state failures and unusual authority chains.

Key rotation:

  • Validator signing key: update_validator operation with new signing key.
  • Account keys: update_account with new master/active/regular keys.
  • All key changes take effect immediately on the next block.

See also: Plugin Development, Data Types, Validators, Webserver Plugin.