Skip to content

Private feed addresses quoted in RSS descriptions reach the cache and generated notes #438

Closed

Description

@chhoumann

An RSS description that quotes a subscriber's private feed address survives in parsed feed content. Creating an episode note then writes that address through {{description}}, even when the feed's own URL and resume link use the private placeholder.

The localStorage cache is device-local and does not sync with the vault. Its copy is lower severity than data.json or notes. The generated note can sync or be shared, so this is not a cache-only leak.

Reproduction and comparison

Real Obsidian 1.14.4 on Linux/Xvfb, isolated synthetic vault. No subscriber credentials are included in this report. The fixture is http://priv3.supercast.com:38227/feeds/PRIV3_PATH_SENTINEL/feed.xml, mapped to loopback. It serves a 120-second WAV and quotes its address in the channel and item descriptions.

  1. Run the attached fixture server and create its sibling quote-address file.
  2. Subscribe through Settings, select PRIV3 Episode, and create an episode note.
  3. When changing the fixture from neutral to quoted descriptions, refresh and reload the plugin, then select the episode again. The already-loaded player can retain its old metadata.
  4. Inspect the actual note, data.json, and app.loadLocalStorage("podnotes:feed-cache:v6").
Observed text Master 6ebf83543e1777629233011d961c5697d815ed41 PRIV3 34950aac1a17c1b229a1d5ccfac2632f6c18d59b
Saved feed address in data.json Raw address Placeholder; no sentinel anywhere in the captured document
Cache key Raw address Placeholder
Channel and item descriptions in cache Raw quoted address Raw quoted address
Default note's feed URL and resume link Raw address Placeholder
Default note's description Raw quoted address Raw quoted address

The default note was exercised live. Source inspection shows that custom templates using {{description}} consume the same episode description. Other template tags and every possible metadata field were not tested.

Boundary to fix

FeedRepository.fetch stores the parsed channel and items, persist serializes those documents, and projectEpisode copies their descriptions into runtime episodes. createPodcastNote passes the episode to NoteTemplateEngine, whose description conversion does not redact the feed address.

PRIV3 extends the existing address classifier. Fixing content across parsing, cached documents, runtime projections, and note templates needs a separate change. Scrubbing only data.json or cache keys does not protect the note.

A follow-up should reproduce both cold and warm-cache paths with quoted metadata, keep legitimate media addresses usable, and assert the bytes of newly generated notes. Also inspect old raw cache keys before the view opens and legacy raw-URL note links. Those two cases were source-inspected here, not proven live. Existing notes are not rewritten by PRIV3.

Evidence

Private address still appears in the generated description

Synthetic fixture and captured evidence.

Activity

  1. chhoumann commented on Oct 13, 2026

    @chhoumann
    OwnerAuthor

    Fixed by #454 (merged 48e1d50): nothing PodNotes writes into the vault contains a private feed address. Verified live on Obsidian 1.14.4 in the #454 verification (V-454), with a sentinel in every field and template tag. Remaining alias classes and entity-escaped copies in data.json are tracked separately.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions