Spruce Completes Formal Security Audit by Trail of Bits

Spruce Completes Formal Security Audit by Trail of Bits

Spruce lets users control their data across the web. To accomplish our mission, we commit to maintaining the highest standards of open-source transparency, software quality, and trust with the community.

In October 2021, the Tezos Foundation generously sponsored the initial formal security audit of the entire software supply chain of DIDKit, Kepler, Credible and Tezos Profiles with Trail of Bits as the auditor. Last month in February 2022, we had the opportunity to complete a fix-up audit that addressed all of the findings.

The complete report from Trail of Bits can be found here.

A brief summary of each of these projects follows:

  • DIDKit is a cross-platform toolkit written in Rust for working with W3C Decentralized Identifiers, W3C Verifiable Credentials, and a set of emerging specifications that enable an end-to-end credentialing solution for Web3 and beyond.
  • Kepler is a self-sovereign storage solution that allows users to deploy and manage personal data vaults, enabling a shift away from users logging into platforms to platforms logging into users' personal data vaults, with users empowered to adjust who has access at any time.
  • Credible is a whitelabel-ready native mobile application for entire credential lifecycle management. It packages DIDKit, demonstrating complete workflows on Android and iOS.
  • Tezos Profiles is an end-user Web3 application in the Tezos ecosystem with over 21,000 deployed profiles, allowing creators to demonstrate their digital identity to prevent fraud across NFT minting, DAO participation, DeFi activity, and more--all without compromising privacy. Tezos Profiles uses DIDKit and Kepler under the hood for the credentialing workflows, and is compatible with the same technology standards as Credible.

Tezos has been ahead of the curve (or curves) with support for just about all the major elliptic curves we have encountered in Web3, including ed25519 (tz1, used in Solana, NEAR, and Algorand), secp256k1 (tz2, used in Bitcoin, Ethereum, and any EVM-compatible systems), and P-256 (tz3, NIST-approved, and fit for use in federal governments globally).

We created the first signature suites in Rust to construct Tezos transactions and signing operations with tz2 and tz3. Tezos has also recently added support for BLS12-381 for zero-knowledge proofs, and thus our implementation of this curve in conjunction with the BBS+ signature credential proofs has been covered as part of the audit.

Finally, as part of our cross-chain initiatives, our EIP-712 Rust implementation was reviewed and deemed fit for use with cryptographic signing operations, allowing Ethereum users to also demonstrate their identity cross-chain on Tezos as one of the many supported use cases.

Likewise, Trail of Bits has proven themselves to be the foremost security auditor at the intersection of blockchain, cryptography, and Rust. They are an undisputed leader technically and within the community, working on the highest stakes security engagements in the world:

Key Findings and Lessons Learned

For the rest of this post, we’ll navigate the Spruce stack from low-level libraries to high-level distributed applications, including the key findings and lessons learned along the way.

ssi

GitHub - spruceid/ssi: Core library for decentralized identity.
Core library for decentralized identity. Contribute to spruceid/ssi development by creating an account on GitHub.

ssi is the core library written in Rust at the heart of our decentralized identity tooling. It handles low-level W3C Decentralized Identifiers (DIDs) and W3C Verifiable Credentials (VCs) operations, supporting JWT-only and JSON-LD formats alike along with a plethora of DID methods. This audit encouraged us to improve our programming hygiene and set coding guidelines to validate results at each interface, thus securing against injection and corruption vectors, particularly when it comes to URI parsing and user-generated inputs.

The following improvements were made:

  • Proactive zeroing of in-memory key material and other sensitive values, particularly in parts of the codebase that pre-date zeroing functions being available by default in stable Rust [ssi#327, 328]
  • Improved handling of stringified/exploded arrays and single-element arrays, a common glitch in cross-language and cross-context variable handling and error-handling [ssi#302, 313]
  • Improved validation of strings, URLs, and [LDP] proof types [ssi#299, 329]
  • Simplified usage of unwrap and unwrap_or_else functions [ssi#305]
  • Avoiding unsafe-transmute in older code [ssi#334]
  • Improved handling of DigestPassThrough option in rustcrypto: [ssi#337]
  • Avoiding cloning secret keys during generation [ssi#391]

DIDKit

GitHub - spruceid/didkit: A cross-platform toolkit for decentralized identity.
A cross-platform toolkit for decentralized identity. - GitHub - spruceid/didkit: A cross-platform toolkit for decentralized identity.

DIDKit is our cross-platform toolkit for working with W3C Decentralized Identifiers (DIDs) and W3C Verifiable Credentials (VCs) that packages ssi across different operating systems, programming languages, and blockchains. The published packages of DIDKit, allow a wide range of downstream applications to utilize our audited libraries. DIDKit was audited in overall design, ergonomics, variable/memory handling, and dependency management.

The following improvements were made:

  • DID-method-specific resolution metadata, such as the way details like indexer/node endpoints, testnet/private-network settings, verbosity settings, and more get passed between layers of the stack was documented and regularized [didkit#357]
  • Better timeout and DDoS mitigations for network requests [didkit#233,229]
  • DIDKit HTTP security assumptions documented and made adjustable [didkit#317]
  • More secure handling of corner cases for RevocationList2020 [didkit#314]
  • Better build-time handling for security overrides: [ssi#316]

Credible

GitHub - spruceid/credible: A reference credential wallet built on Flutter and DIDKit.
A reference credential wallet built on Flutter and DIDKit. - GitHub - spruceid/credible: A reference credential wallet built on Flutter and DIDKit.

Credible is a native mobile credential wallet for the verification, storage, and presentation of W3C Verifiable Credentials using W3C Decentralized Identifiers. Credible is whitelabel-ready, and is already use in production by SSI vendors such as Tezos-compatible Talao, which was accepted to the EU-level data sovereignty project Gaia-X.

Because of Credible's project goals as a reference wallet, we decided to descope select UX concerns that we felt would be bettered handled by mobile developers downstream, tailored to specific use cases and contexts. Still, we incorporated several security improvements to significantly battle-harden the base application across a broad set of downstream use cases.

The following improvements were made:

  • Mnemonic-phrase recovery UX, preventing the display of mnemonics when switching focus between apps or across screen un/lock states. [credible#90]
  • Disallowing “custom keyboards”, which can be used to record keystrokes or otherwise exfiltrate passwords and seed phrases. [credible#90]
  • Taking full advantage of the modern mobile OS features like biometric sessions and encrypted key storage. [credible#90]
  • Disabling OS-wide data backup, and having the backup of Credible credentials through Spruce’s sister product Kepler roadmapped. [credible#90]
  • The seed-phrase backup was made mandatory and tested in the set-up flow [credible#90]

DID Tezos

GitHub - spruceid/did-tezos: The Decentralized Identifier method for the Tezos blockchain.
The Decentralized Identifier method for the Tezos blockchain. - GitHub - spruceid/did-tezos: The Decentralized Identifier method for the Tezos blockchain.

The DID method specification we wrote for the Tezos ecosystem was given special scrutiny, both as a specification and as a reference implementation thereof.

The following improvements were made:

  • Spec-conformant and mature handling of DID managers queried by contract address, which was a minor feature that was specified but never implemented. [ssi#363]
  • did-tz resolution metadata and testnet support, which was improved and aligned more precisely with the final specification [ssi#350]

Tezos Profiles (DIDKit & Kepler)

GitHub - spruceid/tzprofiles: Create portable verified profiles on Tezos with public accounts.
Create portable verified profiles on Tezos with public accounts. - GitHub - spruceid/tzprofiles: Create portable verified profiles on Tezos with public accounts.

Tezos Profiles, hosted at tzprofiles.com, is the first live version of our DIDKit and Kepler tooling for making identity proofs widely available and portable using W3C Verifiable Credentials and W3C Decentralized Identifiers. DIDKit creates the credentials, and they live in Kepler to allow users the right to deletion. As such, critical workflows for Kepler were also reviewed as part of the audit.

The following improvements were made:

  • Leading-digit validation of number-strings [tzprofiles#164]
  • Better validation and normalization of URL strings against injection [tzprofiles#164, tzprofiles#172, tzprofiles#173]
  • Better sanitization of network connection objects in the Tezos Profiles dapp [tzprofiles#173]
  • Tighter validation of hypothetical corner case (false-positive verification being stored on-chain), and also a crawler script of all profiles predating the fix, to confirm no such false-positives had been registered [tzprofiles#167; script]

As noted earlier, we are incredibly grateful to work with the Tezos Foundation and Trail of Bits on this security-forward project. We are committed to additional third-party audits of our code and tooling as it sees continued adoption in Web3 and beyond.


Spruce lets users control their data across the web. If you're curious about integrating Spruce's technology into your project, come chat with us in our Discord: