RC RANDOM CHAOS

Stored XSS in ansi2html turned SourceHut build logs into an account-takeover vector

· via Hacker News

Original source

Sourcehut account takeover via build logs (XSS in ansi2html)

Hacker News →

While setting up his own SourceHut instance, a researcher noticed bloated CSS in the CI build-log viewer and traced it to ansi2html, the long-neglected Python library that converts terminal ANSI escape codes into HTML. Poking further revealed a stored cross-site scripting flaw: the library’s handling of OSC 8 hyperlinks didn’t sanitize the target URL, so a crafted escape sequence could break out of the href attribute to inject arbitrary attributes (autofocus, onfocus) or smuggle in a javascript: URI. Any log line rendered through ansi2html could therefore run attacker-controlled JavaScript in the browser of anyone viewing it.

The delivery paths made it especially dangerous. An attacker didn’t even need an account — sending a patch to a public mailing list with CI enabled, or controlling any remote resource whose output lands in the log, was enough to plant the payload in someone else’s build job. Because the build-log page carries the CSRF token and a resubmit form, the script could resubmit builds, escalate to admin if an administrator opened the page, and reach the deploy keys stored on builds.sr.ht — which on the flagship instance include keys for sr.ht itself. The researcher notes the bug is effectively wormable, and left weaponization as an exercise.

Defense-in-depth options include tightening the Content-Security-Policy to drop unsafe-inline (complicated by the page’s own inline scripts), sanitizing ansi2html’s output, and rewriting the parser as a proper state machine. After disclosure, Drew DeVault patched builds.sr.ht to auto-sanitize ansi2html output, though the added filtering was aggressive enough to strip colors. Upstream, ansi2html sat under the pycontribs org in a suspended, unmaintained state; the researcher ended up helping maintainer Sebastian Pipping revive the project and ship several fixed releases to PyPI, and went on to pursue a CVE — while arguing that a single CVSS score across all affected products is the wrong model.

Read the full article

Continue reading at Hacker News →

This is an AI-generated summary. Read the original for the full story.