packagekit: Sanitize PackageKit urls

It is very unlikely that vendor/bug/cve urls can be tempered with, it
requires messing with a Bodhi update or repodata. But we already have a
function to validate urls so do our due diligence and also filter out
invalid urls from the package update information.

Backported from: 5efa4af065
This commit is contained in:
Jelle van der Waa 2026-09-16 15:43:44 +02:00 committed by Tomáš Matuš
parent 0a9d08fa8a
commit 551bc6aef2
3 changed files with 24 additions and 6 deletions

View file

@ -251,9 +251,9 @@ function customRemarkable() {
}
function updateItem(remarkable, info, pkgNames, key) {
const bug_urls = info.bug_urls || [];
const cve_urls = info.cve_urls || [];
const vendor_urls = info.vendor_urls || [];
const bug_urls = (info.bug_urls || []).filter(isSafeUrl);
const cve_urls = (info.cve_urls || []).filter(isSafeUrl);
const vendor_urls = (info.vendor_urls || []).filter(isSafeUrl);
let bugs = null;
if (bug_urls.length > 0) {

View file

@ -412,6 +412,9 @@ post_upgrade() {{
if info.get("cves"):
assert isinstance(info["cves"], list)
changes += "\n * " + ", ".join(info["cves"])
if info.get("invalid_cves"):
assert isinstance(info["invalid_cves"], list)
changes += "\n * " + ", ".join(info["invalid_cves"])
path = f"{self.repo_dir}/changelogs/{pkg[0]}/{pkg}/{pkg}_{ver}-{rel}"
contents = f"""{pkg} ({ver}-{rel}) unstable; urgency=medium
@ -436,6 +439,10 @@ post_upgrade() {{
for e in info.get("errata", []):
refs += f' <reference href="https://access.redhat.com/errata/{e}" id="{e}" title="{e}" type="self"/>\n'
# Inject invalid urls
for i in info.get("invalid_cves", []):
refs += f' <reference href="{i}" onmouseover="alert(document.domain);" id="invalid" title="invalid" type="cve"/>\n'
xml += """ <update from="test@example.com" status="stable" type="{severity}" version="2.0">
<id>UPDATE-{pkg}-{ver}-{rel}</id>
<title>{pkg} {ver}-{rel} update</title>

View file

@ -825,6 +825,7 @@ ExecStart=/usr/local/bin/{packageName}
self.createPackage("sevcritical", "5", "1", install=True)
self.createPackage("sevcritical", "5", "2", cves=["CVE-2014-54321"], securitySeverity="critical",
errata=["RHSA-2000:0001", "RHSA-2000:0002"],
invalid_cves=["javascript:alert(document.cookie)", "https://example.com"],
changes='See [malicious link](https://example.invalid/"onmouseover="alert(document.domain)) for info')
self.enableRepo(refresh_repo=True)
@ -846,10 +847,20 @@ ExecStart=/usr/local/bin/{packageName}
self.check_nth_update(2, "secparse", "4-2", "security", 2,
desc_matches=["Fix CVE-2014-54321 and CVE-2017-9999."],
cves=["CVE-2014-54321", "CVE-2017-9999"])
# onmouseover does not survive our sanitization
sel = self.check_nth_update(3, "sevcritical", "5-2", "security", 1,
apt_based = m.image.startswith(("debian-", "ubuntu-"))
# We cannot insert example.com as an url in apts' changelog format only accepts cve ids or issues,
# so it does not appear in the UI.
sel = self.check_nth_update(3, "sevcritical", "5-2", "security", 1 if apt_based else 2,
desc_matches=["See malicious link for info"],
absent_anchor_attributes=["onmouseover"])
absent_anchor_attributes=["onmouseover"]) # onmouseover does not survive our sanitization
# Malicious cve urls don't end up being rendered
# PackageKit parses the apt changelog and constructs CVE urls from it, so we can't insert a malicious javascript: uri
if apt_based:
b.wait_in_text(sel, "javascript:alert")
b.wait_not_present(f"{sel} a[href='javascript:alert(document.cookie)']")
else:
self.assertIsNone(b.attr(f"{sel} a[href='https://example.com']", "onmouseover"))
b.wait_not_in_text(sel, "javascript:alert")
# buggy: bug refs, no security
sel = self.check_nth_update(4, "buggy", "2-2", "bug", 2, bugs=["123", "456"], desc_matches=["Fixit"])