Skip to content

minibf: the pool metadata fetcher does not restrict the target or the response size #1315

Description

@michalrus

Related:

Summary

The pool metadata fetcher in crates/minibf sends an HTTP request to a URL from on-chain pool metadata. The fetcher does not restrict the target address. The fetcher does not limit the response size.

#1295 added the governance proposal metadata routes. The PR also added a restricted fetch path for those routes. The pinned implementation rejects non-public targets and filters DNS results. It also applies the same restriction to redirect targets. The body reader limits each response to 3000000 bytes. The pool fetcher does not use this path.

Affected code

Problem 1: the fetcher does not restrict the target

The client sends the request to any URL in the pool metadata. The URL can point to a private address. The URL can point to a loopback address. The URL can point to a link-local address. The URL can point to a cloud metadata service.

The hash check does not help here. The client reaches the target and reads the body before the hash check. The redirect policy permits three redirects. The policy does not restrict the redirect target.

The client uses the default DNS resolution. A hostname can resolve to a private address. A hostname can return a different address for a second request. This behavior makes a DNS rebinding attack possible.

Problem 2: the fetcher does not limit the response size

The client calls bytes() to read the full body. The client does not set a size limit. The client does not reject a large Content-Length value. A large body uses a large amount of memory.

The pool list route starts one fetch for each pool. The route runs the fetches at the same time. Many large bodies increase the total memory use.

Impact

An attacker can publish pool metadata with a hostile URL. A request to the pool endpoints can then reach an internal service. A large response can use too much memory.

Suggested fix

Use the restricted fetch path from #1295. Reuse its target restrictions. Reuse its bounded body reader. Make the path reusable for pool metadata and governance metadata.

  1. Reject a URL that is not HTTP or HTTPS.
  2. Reject a URL whose host is a private or special IP address.
  3. Resolve each hostname through a DNS filter that removes non-public addresses.
  4. Apply the same address restriction to every redirect.
  5. Do not use a configured proxy for these requests.
  6. If the Content-Length is more than the limit, reject the response.
  7. Read the body in chunks and stop at the limit.
  8. Use a limit of 3000000 bytes, which is the cardano-db-sync limit for vote metadata.

References

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:minibfMini Blockfrost (minibf) APIbugSomething isn't working

    Type

    Fields

    Priority

    None yet

    Effort

    Medium

    Workstream

    Dolos BF Coverage

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions