ERC-7817: dApp Security Policy

title: dApp Security Policy Standard
description: Defines a document standard for defining rules regarding the expected on-chain behavior of a dApp frontend.
author: Bernard Wagner (bernard-wagner)
status: Draft
type: Meta
created: 2024-10-22
PR: https://github.com/ethereum/ERCs/pull/715

Abstract

Introduce a standardized JSON document structure that wallets can interpret to determine whether transaction signing requests should be permitted or rejected. Policy documents should be publicly discoverable using a notary service so that a policy’s authenticity can be assumed even when the origin of the transaction signing request may be compromised.

As an initial implementation, DNS-in-ENS can be used as the discovery mechanism as described in ENSIP-TBC.

Motivation

Hackers often target dApp front-ends to coerce users into signing transactions that allow the hacker to transfer victims’ funds. By introducing a security policy standard, wallet providers can implement safeguards to protect users against such attacks.

Specification

The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119 and RFC 8174.

Policy Document

The document MUST be in JSON format and follow the structure defined below:

{
  "version": "1.0.0",
  "report": "<https://mywebapp.xyz/report>",
  "rules": [
    {
      "description": "Limit USDC approvals to Uniswap Router",
      "inputs": [
        {
          "name": "_spender",
          "type": "address",
          "values": ["0xE592427A0AEce92De3Edee1F18E0157C05861564"]
        },
        {
          "name": "_value",
          "type": "uint256"
        }
      ],
      "name": "approve",
      "payable": false,
      "chainIds": [1],
      "targets": ["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"]
    }
  ],
  "metadata": {
    "commit": "70edc32"
  }
}

  • version: REQUIRED. Version of the specification.
  • report: OPTIONAL. URL to notify in case transactions are blocked. MUST include the raw unsigned 0x-hex-encoded transaction as the tx URL parameter in an HTTP GET request. e.g. https://mywebapp.xyz/report?tx=0x...
  • rules: OPTIONAL. An array of rules for transaction validation. Extension of the ABI specification.
    • name: OPTIONAL. Name of the function. If omitted, it MUST be interrupted as the fallback function.
    • description: OPTIONAL. Description for front-end messages.
    • inputs: OPTIONAL. Extended function ABI that defines a list of permittable values. It MUST be ignored if no function name is specified.
      • name: OPTIONAL. User-readable name of the argument.
      • type: REQUIRED. ABI type of argument.
      • values: REQUIRED. List of valid values. It MUST be an encoded string of the correct byte length.
    • payable: OPTIONAL. Indicates whether the function is payable. MUST default to false if not specified.
    • chainIds: OPTIONAL. A List of chain IDs to which the rule applies. If not specified, it MUST default to any chain.
    • targets: OPTIONAL. Valid “to” addresses for the transaction. MUST default to any address if not specified.
  • metadata: OPTIONAL. Any valid JSON to include in the document but not interpreted by Wallets. Typically, it will include a commit hash or change control of the policy document.

Discovery

It is envisioned that the policy document may be discovered and obtained using different protocols. However, the discovery protocol MUST adhere to the following:

  • Provide a high level of confidence that only the legitimate owner of a domain can associate a policy document to their domain.
  • Be publicly accessible.
  • Validate the integrity of the policy document.

Rationale

The front ends of dApps are regularly targeted using supply-chain attacks or DNS hijacking, whether DNS cache poisoning or registrar compromise. When executed, these attacks inject malicious JavaScript that invokes transaction signing requests to drain users’ wallets. In most scenarios, this behavior is not part of the expected behavior of the dApp from which the request originates. Therefore, if dApp developers can define the intended behavior of their dApp and have wallets obtain this policy out-of-band to enforce the intended behavior or warn users, several front-end compromise risks can be mitigated.

This EIP intends to be agnostic to the discovery protocol. However, DNS-in-ENS is a good first candidate, as it allows for importing DNSSEC-enabled domains into ENS. This process requires the submission of an on-chain transaction that includes the DNSSEC attestation for the domain. From there, the ENS controller can create a text record notarizing the location of the policy document.

Wallets, such as Metamask, can query ENS when receiving a transaction signing request to obtain the location of the policy and retrieve the document. The policy can then be applied to any signing request.

From a security perspective, this mitigates several supply-chain and DNS attack paths:

Malicious JavaScript embedded into the webpage

It invokes a transaction signing request from the webpage’s context. The wallet uses its context to obtain the HTTP origin of the request and queries ENS for the domain using its own RPC endpoint. Since the policy retrieval and evaluation are performed outside the malicious JavaScript’s execution context, it cannot request any action not permitted by the policy.

DNS cache-poisoning / BGP hijacking

The domain’s IP address is changed to direct users to a malicious version of the dApp (the DNS resolver doesn’t perform DNSSEC validation). As with a supply-chain compromise, the attackers have no control over the policy’s evaluation.

If the attack extends to the location where the policy is hosted, the policy remains intact, as the discovery protocol MUST enforce an integrity check. In the case of ENSIP-TBC, the policy digest is included in the ENS text record for policy retrieval over HTTPS.

Backwards Compatibility

N/A.

Reference Implementation

A MetaMask Snap was developed to illustrate the implementation of the EIP.

5 Likes

Related ENSIP early draft:

ENSIP-XX: Security Policy Records

| Author | Bernard Wagner(@bernard-wagner) |

| — | — |

| Status | Draft |

| Submitted | TBC |

Abstract

This ENSIP extends ENSIP-5: Text Records and defines a record, dappsec, that specifies the location of a security policy as described in EIP-TBC. The text record is intended to be queried by wallets for domains imported using ENSIP-6: DNS-in-ENS, thereby notarising the security policy for a particular domain or subdomain. Wallets can then use the security policy to validate the properties of transaction signing requests based on their HTTP origin. The objective is to mitigate the impact of front-end hacks, such as DNS takeovers or supply-chain compromises of front-end components.

Motivation

Hackers often target dApp front-ends to coerce users into signing transactions that allow the hacker to transfer victims’ funds. By introducing a security policy standard, wallet providers can implement safeguards as described in EIP-XXX to protect users against such attacks.

Specification

Introduce a well-known global text record that allows wallet providers to discover the security policy for a hosted dApp using on-chain data.

Example Text Record:


dappsec: uri=https://mywebapp.xyz/.well-known/ensip-xx.json hash=0x-hex-string

  • URI: MUST specify the https or ipfs schemas.

  • Hash: When the location is specified using the https schema, it MUST contain the policy document’s keccak256 hash as a 0x-prefixed lowercase hex string. The hash property is OPTIONAL for the ipfs schema, as the policy’s integrity is implicit.

Some early things worth discussing:

  1. Extending the rules to include EIP712 and blob signing requests. Apply token approval rules to Permits.
  2. Multicall - Is there an EIP for a standardized Multicall that this EIP can leverage to introspect multicall transactions?

What potential challenges do you see in ensuring that policy documents are reliably discoverable and authenticated through decentralized protocols like DNS-in-ENS?

To support EIP-712 and blob signing requests, the dApp Security Policy could be extended to include specific rules for structured data validation, ensuring that signature requests comply with predefined criteria. For Permits (e.g., EIP-2612), the policy should apply the same token approval logic, enhancing consistency across token authorization mechanisms. Integrating Multicall would involve referencing an existing EIP for Multicall standardization, allowing the policy to introspect and enforce rules on batch transactions. This would strengthen transaction security, providing comprehensive validation against multi-operation requests.

1 Like