← Back to Feed CACHED · 2026-07-19 21:27:53 · CACHE_KEY CVE-2026-58447
CVE-2026-58447 · CWE-639 · Disclosed 2026-06-30

Invidious through 2

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
Do you agree?
01 · The Real Story

A pickpocket who can only rearrange the contents of other shoppers' carts, and only if they're already in the store

Invidious is a self-hosted, privacy-preserving frontend for YouTube written in Crystal (Kemal framework, Postgres backend). The bug is a classic IDOR (CWE-639) in the remove_video action on the playlist endpoint: the code accepted an attacker-supplied global video *index* without checking that the playlist actually belonged to the caller. Combined with the fact that per-video indices are exposed by the public playlist JSON API, any logged-in user of the same instance could permanently delete videos from *other users'* playlists. Affects Invidious ≤ 2.20260626.0; fixed in commit 77ad416 on the master branch.

Vendor pegged this at CVSS 6.5 MEDIUM with C:N/I:H/A:N. The integrity call is fair — data belonging to another user is mutated without authorization — but the deployment reality drags the operational severity down further. Invidious is not typically an enterprise application; it is deployed by hobbyists, privacy-focused communities, and small self-hosters. The affected data is playlist entries, not credentials, code, or business records. In practitioner terms this is LOW: real, worth fixing, but nowhere near patch-cycle-jumping territory.

"IDOR that lets an authenticated user delete videos from someone else's Invidious playlist. Annoying, not enterprise-critical."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Register or sign in on the target Invidious instance

The attacker needs an authenticated session on the same Invidious instance whose playlists they want to tamper with. Most public instances allow open registration; private ones require an invite or SSO. No admin rights needed — a stock user account is enough.
Conditions required:
  • Instance allows account registration OR the attacker already holds any user account
  • Network reach to the instance (usually public HTTPS)
Where this breaks in practice:
  • Locked-down private instances disable registration
  • Corporate/family instances gate accounts behind SSO
Detection/coverage: Not covered by external scanners; only visible in Invidious auth logs and Postgres users table
STEP 02

Enumerate a target playlist and harvest video indices

Hit the public playlist JSON API (/api/v1/playlists/<plid>) to pull the ordered list of videos. Each entry carries an internal index value — a Postgres bigint used as the row key in the playlist_videos table. These indices are globally unique across playlists, which is the design flaw that enables the IDOR.
Conditions required:
  • Target playlist is queryable (public, unlisted with known ID, or discoverable via search)
Where this breaks in practice:
  • Purely private playlists are not enumerable without their plid
  • Rate-limited instances slow bulk enumeration
Detection/coverage: Reads look like normal API traffic; no signature-based detection
STEP 03

POST the harvested index to remove_video on any playlist you own

Call the playlist update endpoint (/playlist_ajax / remove_video action) supplying the *victim's* video index. The vulnerable code path resolved the row by index alone and issued a DELETE FROM playlist_videos WHERE index = ? without joining against the caller's plid/owner. No public weaponized tool exists — this is a two-line curl/Python job the attacker writes themselves.
Conditions required:
  • Valid session cookie / CSRF token for the attacker's own account
Where this breaks in practice:
  • Fixed instances (commit 77ad416+) reject the request
  • Reverse proxies with per-IP write throttling limit scale
Detection/coverage: Application logs show a remove_video where the caller's user_id does not match the affected playlist's owner — trivially auditable in Postgres post-facto
STEP 04

Impact: silent, permanent deletion of other users' playlist contents

Rows are gone; there is no soft-delete or trash bin in Invidious playlists. Victims lose curation state (subscriptions and history are unaffected). At scale, an attacker could iterate the index space and gut every playlist on a busy public instance. No RCE, no auth bypass, no data exfil — pure integrity damage.
Where this breaks in practice:
  • Postgres PITR / pg_dump backups restore state if the operator takes them
Detection/coverage: User complaints; diff of playlist row counts vs. backup
03 · Intelligence Metadata

The supporting signals.

In-the-wild exploitationNone observed. Not on CISA KEV; no public campaigns, no honeypot hits reported by GreyNoise or Shodan.
Public PoCNo standalone PoC repo. The fix diff at commit 77ad416 effectively documents the vulnerable code path — weaponization is trivial for anyone reading it.
EPSS0.00225 (~0.2%) — bottom-quartile probability of exploitation in the next 30 days.
KEV statusNot listed.
CVSS 3.1 vectorAV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N → network reach, low complexity, authenticated (PR:L), no user interaction, integrity-only impact. The PR:L and C:N/A:N are the ceiling-setters.
Affected versionsInvidious ≤ v2.20260626.0 (all releases prior to the fix commit).
Fixed versionMaster branch commit 77ad416; expected in the next tagged release after v2.20260626.0. No distro backports — Invidious is not packaged in Debian/RHEL stable channels.
Exposure populationThe public Invidious instance list tracks ~40–60 public instances globally. Shodan/Censys queries for Server: Kemal + Invidious title fingerprints return a few hundred hosts including private ones. Not an enterprise-scale attack surface.
Disclosed2026-06-30, fix committed same day.
CreditReported to the iv-org maintainers; CVE assigned via MITRE. Individual reporter not publicly credited in the CVE record at time of writing.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to LOW (3.1/10)

The single decisive factor is blast radius limited to per-user playlist rows on a niche self-hosted YouTube frontend — no credentials, no code execution, no cross-tenant data, and the affected component is not present on typical enterprise fleets. Authenticated prerequisite (PR:L) plus integrity-only impact on non-critical user data keeps this firmly in the backlog-hygiene bucket.

HIGH vulnerability class and technical accuracy
HIGH absence of enterprise deployment footprint
MEDIUM exact count of vulnerable public instances

Why this verdict

  • Authenticated precondition (PR:L): attacker must hold a valid account on the same instance — implies either open registration or prior social engineering / account takeover. Removes drive-by exploitation.
  • Integrity-only impact (C:N/I:H/A:N): no credential theft, no RCE, no denial of service, no data exfiltration. Damage is bounded to playlist row deletions, which are recoverable from any Postgres backup.
  • Deployment-role audit — no high-value role exists for Invidious: it is a personal / community media frontend. It is not identity, not PKI, not backup, not hypervisor, not CI/CD, not an edge appliance. The role-multiplier floor rule does not raise the verdict because no realistic deployment role turns this bug into fleet, domain, or supply-chain compromise.
  • Exposure population is tiny in enterprise terms: dozens of public instances, low hundreds of private ones. Sub-1% of the Fortune 5000 runs Invidious anywhere.
  • No in-the-wild activity, no KEV, EPSS 0.2%. No opportunistic mass exploitation signal.
  • Vendor 6.5 baseline is reasonable for an individual instance operator; downgrade to LOW reflects enterprise portfolio prioritization, not disagreement with the technical scoring.

Why not higher?

MEDIUM would imply the bug warrants scheduled remediation ahead of routine backlog. It does not — the impact is user-visible annoyance recoverable from Postgres backups, with no lateral movement or credential exposure. HIGH/CRITICAL are inapplicable: no code execution, no auth bypass, no cross-tenant escalation, no high-value-role component.

Why not lower?

IGNORE is not appropriate because the bug is real, trivially exploitable once the patch diff is public, and permanently destroys user data. Operators of public Invidious instances do need to upgrade; LOW correctly signals 'fix in the next window' rather than 'do nothing'.

05 · Compensating Control

What to do — in priority order.

  1. Disable new-user registration on public instances until patched — Cuts off the primary attacker acquisition path (PR:L becomes unreachable). Set registration_enabled: false in config.yml and restart the container. As a LOW-severity finding under the noisgate mitigation SLA there is no mandatory mitigation deadline, but for public-facing instances treat this as a same-week hygiene step.
  2. Snapshot the Postgres playlists and playlist_videos tables before patch and daily thereafter — Because the bug destroys rows with no soft-delete, backups are your only recovery. Run pg_dump -t playlists -t playlist_videos on cron; retain 30 days. Do this before you deploy 77ad416 so you have a known-good baseline.
  3. Add a reverse-proxy rule that logs every POST to /playlist_ajax with the session user ID — Gives you post-facto attribution and lets you tell affected users what was deleted. Ten lines of nginx log_format plus a Loki/ELK query on action=remove_video where source user differs from playlist owner.
  4. Pull master or wait for the next tagged release, then redeploy the container — The fix is a single commit — git pull && docker compose build && docker compose up -d. Under the noisgate remediation SLA for LOW you have up to 365 days, but there is no reason to wait: the delta is trivial and the fix does not change data schemas.
What doesn't work
  • WAF signatures — the request looks like a normal authenticated playlist edit; there is no malicious payload to match on, only a semantic ownership violation.
  • MFA — the attacker uses a legitimate MFA-completed session of *their own* account. Second factor does nothing to stop the IDOR.
  • Rate limiting alone — a patient attacker can iterate at whatever rate the limiter permits and still hit every playlist eventually.
06 · Verification

Crowdsourced verification payload.

Run this on the Invidious host itself (the container host or the VM running the Crystal binary). It inspects the deployed git revision. Invoke as ./check-invidious-cve-2026-58447.sh /opt/invidious where the argument is the Invidious source directory. Requires read access to that directory; no root needed.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# noisgate verifier — CVE-2026-58447 (Invidious IDOR in playlist remove_video)
# Output: VULNERABLE / PATCHED / UNKNOWN
set -u

INV_DIR="${1:-/opt/invidious}"
FIX_COMMIT="77ad416"
LAST_VULN_TAG="v2.20260626.0"

if [[ ! -d "$INV_DIR/.git" ]]; then
  echo "UNKNOWN: $INV_DIR is not a git checkout of iv-org/invidious"
  exit 2
fi

cd "$INV_DIR" || { echo "UNKNOWN: cannot cd to $INV_DIR"; exit 2; }

# Fetch tags/commits quietly so we can resolve the fix ref
git fetch --quiet --tags origin 2>/dev/null || true

# 1. Does the checked-out HEAD contain the fix commit in its history?
if git merge-base --is-ancestor "$FIX_COMMIT" HEAD 2>/dev/null; then
  echo "PATCHED: HEAD ($(git rev-parse --short HEAD)) contains fix commit $FIX_COMMIT"
  exit 0
fi

# 2. Fallback — check the tagged release string in the source
CURRENT_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "unknown")
if [[ "$CURRENT_TAG" == "$LAST_VULN_TAG" || "$CURRENT_TAG" < "$LAST_VULN_TAG" ]]; then
  echo "VULNERABLE: release $CURRENT_TAG is at or before $LAST_VULN_TAG and fix commit $FIX_COMMIT is not in history"
  exit 1
fi

echo "UNKNOWN: could not conclusively determine patch status (tag=$CURRENT_TAG, HEAD=$(git rev-parse --short HEAD))"
exit 2
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning: this is a LOW for any enterprise portfolio and does not deserve a slot in your next patch train unless you actually run Invidious. If you do run a public instance, disable open registration this week (per the noisgate mitigation SLA, LOW has no mandatory mitigation deadline — treat this as hygiene), snapshot your playlist_videos Postgres table today, and roll master (or the next tag past v2.20260626.0) containing commit 77ad416 at your next maintenance window — well inside the noisgate remediation SLA ceiling of 365 days. If you don't run Invidious, close the ticket with a one-line 'not in inventory' note and move on.

Sources

  1. Invidious release v2.20260626.0 (last vulnerable tag)
  2. iv-org/invidious repository
  3. Invidious official documentation — Instances
  4. Invidious project site
  5. OWASP API1:2023 Broken Object Level Authorization
  6. CWE-639: Authorization Bypass Through User-Controlled Key
  7. CISA Known Exploited Vulnerabilities Catalog
  8. FIRST EPSS model
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.