GHSA-9pmc-p236-855h: Ruby CSS Parser: SSRF and Local File Disclosure in `CssParser::Parser#read_remote_file`
Summary
CssParser::Parser#read_remote_file (and therefore load_uri!, and the @import-following branch of add_block!) issues HTTP/HTTPS requests against any host, port and URI it is handed, with no scheme allowlist, no host / IP filtering, and no protection against link-local, loopback or RFC‑1918 addresses. Location: redirects are followed recursively back into the same function, which also services file:// URIs, so a single attacker-controlled HTTP redirect upgrades the bug from SSRF to arbitrary local file disclosure.
In practice, any consumer of css_parser that hands it attacker‑influenced CSS together with a base_uri: option — Premailer being the canonical example — is exposed. The attacker only needs the ability to land one @import url(...) in the CSS that the host application parses.
Vulnerable code
lib/css_parser/parser.rb#L613-L687:
def read_remote_file(uri) # :nodoc:
...
begin
uri = Addressable::URI.parse(uri.to_s)
if uri.scheme == 'file'
local file
path = uri.path
path.gsub!(%r{^/}, '') if Gem.win_platform?
src = File.read(path, mode: 'rb') # <-- arbitrary local read
else
remote file
if uri.scheme == 'https'
uri.port = 443 unless uri.port
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
else
http = Net::HTTP.new(uri.host, uri.port) # <-- arbitrary host:port
end
res = http.get(uri.request_uri, ...)
...
elsif res.code.to_i >= 300 and res.code.to_i < 400
unless res['Location'].nil?
return read_remote_file Addressable::URI.parse(...) # <-- cross-scheme redirect
end
end
...
There is no validation of uri.host, uri.scheme, or the resolved IP address — neither before the HTTP request, nor before the recursive call on the Location header.
The user-facing entry points that reach this sink are:
- Parser#load_uri! — directly calls read_remote_file (line 513).
- Parser#add_block! — when invoked with base_uri: and the default import: true, scans the CSS for @import url(...) rules and resolves each one through load_uri! (line 150).
Threat model
Details
Original advisory: https://github.com/advisories/GHSA-9pmc-p236-855h
Referenced CVEs
| CVE | CSIRTS overview | External |
|---|---|---|
| CVE-2026-53727 | coverage & exploitation status | NVD · CVE.org |
More from GitHub Security Advisories
- criticalGHSA-g936-7jqj-mwv8: TSDProxy: Internal proxy auth token forwarded to backend services enables management API …2026-07-10
- highGHSA-fpg8-7664-jc5q: melange: Incomplete package integrity verification allows data section substitution2026-07-10
- mediumGHSA-48rx-c7pg-q66r: Excon does not redact additional sensitive/risky headers when following redirects2026-07-10
- highGHSA-h4g2-xfmw-q2c9: Clauster: Non-loopback deployments can serve the dashboard unauthenticated when auth.enab…2026-07-10
- mediumGHSA-rqq5-2gf9-4w4q: Secure Headers: CSP directive injection via sandbox, plugin_types, and report_to when giv…2026-07-10