Inspiration

Existing security mechanisms (DNSSEC, CSP, X-XSS-Protection, X-Frame-Options, SRI) fall short in addressing unique challenges in dApp environments. They particularly lack of direct linkage between frontend code integrity and smart contract ownership. And so with Web3 projects, the integrity of the frontend code is just as important as the immutability of the smart contract.

What it does

  • Create an on-chain registry that maintains a verifiable relationship between smart contract, dApp frontend, and domain registration
  • Utilizing signed DNS TXT records, verify and store the domain owner’s wallet address on the smart contract
  • Leverage a browser extension to verify the integrity of dApp front-end code and relationship between the domain name and the contract in real-time

How we built it

A number of options were brainstormed to effectively provide the linkage between Web2 and Web3 resources in a way that to compromise a DApp, a malicious entity would need to compromise both the Web2 and Web3 resources of any project (barring smart contract takeover or smart contract bugs).

We landed on a design that leverages

  • A smart contract that maps domains to smart contract addresses
  • Chainlink nodes to query DNS text records to associate domain ownership to contract ownership
  • A browser extension that sniffs DApp connections to verify code and contract ownership tied to the DApp domain name

Effectively, it was built in 2 parts

REGISTRATION FLOW

What: Create an authenticated mapping on-chain between a domain owner and a wallet address via a smart contract

Why: This allows the domain owner to create a point-in-time proof of their ownership, tying that ownership to a keypair, and using that keypair to sign and (allow others to) verify code signatures

How:

  • User submits domain<>contract mapping
  • DomainRegistry.sol forwards request to custom Chainlink node to verify User’s ownership of the domain
  • Chainlink Node pulls signed DNS TXT record from Google DNS-over-HTTPS JSON API
  • Chainlink Node uses custom NodeJS External Adapter to format Google DoH response
  • Chainlink Node calls back into the contract with the signature from the DNS TXT record, which is then verified onchain

VALIDATION FLOW

What: Verify that the code signatures provided by the webserver match the registered domain owner’s Base wallet address, and verify the DNS TXT record contains a valid signature from the owner

Why: If the signatures are invalid, you know that the frontend logic has been tampered with

How:

  • User loads browser extension
  • Upon navigating to a dApp, the browser extension fetches the code signatures for that dApp, prior to page load
  • The extension fetches the domain owner’s Base wallet address located in the DomainRegistry.sol contract
  • Extension validates the DNS TXT record contains a valid signatures
  • Upon loading the dApp’s frontend application logic, each file is validated against the signature to ensure integrity

Challenges we ran into

  • Ideating on how to tie the contract to the domain ownership was the biggest challenge. We ideated using randomly generated tokens on the smart contract, to signed contract addresses and signed public keys stored in DNS text records
  • Signing and verification standards across libraries have changed over time, and finding a way to consistently sign in one place and verify in another proved to be our largest challenge
  • We had to setup a custom Chain Link Oracle Node to fetch the DNS TXT record
  • Designing a thoughtful mechanism that solved a real problem while accounting for various edge cases took many iterations

Accomplishments that we're proud of

  • Tying Web2 resource ownership to Web3 resource ownership
  • Leveraging Chainlink nodes to query DNS txt records

What we learned

Learnt how to leverage Chainlink nodes from smart contracts, learnt building smart contracts, building a browser extension and have it sniff browser traffic

What's next for dApp Code Signatures

  • Decentralizing and scaling domain ownership disputes
    • Challenge window
      • Increase flexibility, allow domain owners to challenge current entries in the registrar
      • Limit registrar admin’s participation in settling dispute
    • Upgradability and multisig ownership
  • Custom security policies
    • Allow developers to specify formal rules for proper interaction with their contracts, and we enforce them on the client-side
  • Browser modifications
    • EDR capabilities, code introspection
      • Javascript is limited in its ability to observe its execution flow
      • A metalayer that can intercept sensitive Wallet operations and examine stack traces and other characteristics about the execution to determine suspicious behavior
    • Double-fetch problem
      • Validating code signatures requires us to make an additional request to fetch the resource–this security measure can be detected and defeated by a skilled attacker.
      • Ideally, we would validate the files as they are received by the browser in real time

Built With

Share this project:

Updates