livepeer / livepeer/explorer

security: profile page renders unsanitized ENS-supplied URL

Open
#643 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
11
Forks
26
Avg merge
11h 58m
Merged PRs (30d)
16

Description

Summary

The orchestrator profile renders an external website link directly from identity.url, which is sourced from the orchestrator's ENS url text record. ENS text records are user-controlled, so this value is fully attacker-controlled for any account whose ENS profile is configured.

See components/Profile/index.tsx:279:

{identity?.url && (
  <A
    variant="contrast"
    css={{ fontSize: "$2" }}
    href={identity.url}
    target="__blank"
    rel="noopener noreferrer"
  >
    ...
    {identity.url.replace(/(^\w+:|^)\/\//, "")}
  </A>
)}

Attack vectors

A malicious orchestrator can set their ENS url text record to:

  • javascript:alert(document.cookie) — when a viewer clicks the globe link, arbitrary JS runs in the explorer origin. React 16+ logs a warning for javascript: hrefs but does not reliably block them, especially after build-time minification.
  • data:text/html,<script>...</script> — opens a same-document data URL whose script can phish or impersonate the explorer.
  • evil.com/path (no scheme) — the browser treats this as a relative path, so the link navigates to https://explorer.livepeer.org/.../evil.com/path instead of the intended external site. Useful for bait-and-switch / phishing where the displayed text and the actual destination differ.

Scope

Only the website (identity.url) field is affected. The Twitter and GitHub blocks just below it interpolate the user value into hardcoded https://twitter.com/... / https://github.com/... URLs, so the protocol is fixed and they are not the same risk.

Fix

Validate the URL before rendering: auto-prefix https:// if no scheme is present, parse via new URL(...), and reject anything where protocol is not http: or https:. If sanitization fails, do not render the link block at all. Bind the sanitized value to both href and title so the user sees what they will actually navigate to.

Fix is in #644.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

The affected code is components/Profile/index.tsx around line 279, where identity.url is rendered. Review the validation described in the issue and compare the existing implementation with pull request #644; done means unsafe schemes are not rendered and accepted links use the sanitized destination consistently.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
frontend, security
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.