WP Manifestindependent plugin directory

Install

Download feeds.zip From the v0.3.0 release on GitHub, Dec 2, 2025

Upload it under Plugins → Add New Plugin → Upload Plugin, then activate.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/bacoords/feeds/releases/download/v0.3.0/feeds.zip
No built-in updater. New versions won't appear under Dashboard → Updates. Install new releases yourself, or let Git Updater track the repository.

Feeds - WordPress RSS Reader Plugin (beta)

A self-hosted RSS reader living natively inside the WordPress Admin Dashboard. It aggregates content from external feeds into Custom Post Types and provides a modern React-based reading interface using @wordpress/dataviews.

Download a zip of the latest release from the Releases page.

Try it out on WordPress Playground: Playground

Features

  • Feed Management: Add, delete, refresh, and manage RSS feed subscriptions with status monitoring
  • OPML Import: Import feed subscriptions from OPML files with automatic category organization
  • Smart Reading Interface: Modern React-based split-pane UI with DataViews (table & list views)
  • Auto-Sync: Automatic feed fetching with per-feed refresh intervals (powered by Action Scheduler)
  • Read/Unread Tracking: Articles automatically marked as read when closed
  • Favorites: Star important articles - favorites are preserved when closing articles
  • Thumbnail Support: Automatic extraction of article images from multiple sources (media:thumbnail, enclosures, content)
  • Feed Status Monitoring: Filter feeds by success/error status to identify problematic sources

Development

This project uses @wordpress/scripts for the build process.

Setup

composer install
npm install
npm run build

Build Commands

  • npm run build - Production build
  • npm run start - Development build with watch mode

Architecture

Custom Post Types

  • feeds_source: RSS feed subscriptions with metadata (URL, last fetched timestamp, error messages)
  • feeds_item: Individual feed articles with metadata (source ID, permalink, author, thumbnail URL, publication date)

Post Statuses

The plugin uses custom post statuses for efficient filtering without meta queries:

Feed Items:

  • publish - Unread articles (default)
  • trash - Articles marked as read get moved to trash
  • favorite - Favorited articles get saved with this status

Feed Sources:

  • publish - Successfully fetched feeds
  • pending - Feeds with fetch errors

Taxonomies

  • feeds_category: Organize feeds and items by category (supports OPML import hierarchy) Note: This is not exposed in the UI yet.

API Endpoints

The plugin exposes the following REST API endpoints:

  • POST /wp-json/feeds/v1/refresh/{id} - Manually refresh a single feed source
  • POST /wp-json/feeds/v1/import-opml - Import OPML file with feed subscriptions

Filters & Hooks

The plugin provides the following filters for customization:

  • feeds_excerpt_char_limit - Filter to change the excerpt character limit (default: 300)
  • feeds_import_max_age_days - Filter to change the maximum age of items to import when adding a feed (default: 7 days)

Examples:

// Increase excerpt length
add_filter( 'feeds_excerpt_char_limit', function() {
    return 500;
} );

// Only import items from the last 14 days
add_filter( 'feeds_import_max_age_days', function() {
    return 14;
} );

WP-CLI Development Commands

The plugin includes WP-CLI commands for development and testing:

  • wp feeds sources fetch - Fetch all feeds without deleting
  • wp feeds sources delete - Deletes all feed sources and all feed items (complete reset).
  • wp feeds items delete - Deletes all feed items and keeps sources.

License

GPL v2 or later

Support

For issues and feature requests, please open an issue on the GitHub repository.

Releases

7 releases. Each count is every asset in that release; expand a row for the breakdown.

Tag
Published
Assets
Downloads
v0.3.0 latest
Dec 2, 2025 10mo ago
feeds.zip
57
Nov 30, 2025 10mo ago
feeds.zip
14
Nov 30, 2025 10mo ago
feeds.zip
13
Nov 29, 2025 10mo ago
feeds.zip
17
Nov 26, 2025 11mo ago
feeds.zip
13
Nov 26, 2025 11mo ago
feeds.zip
0
Nov 26, 2025 11mo ago
feeds.zip
4

Active-site estimate ≈10 comes from the median of recent superseded releases. Method.

D+ grade

Security

Feeds 0.3.0 · audited by WP Registry

High-severity findings.

1 high 1 medium
Audited release
0.3.0
Findings
2
Worst severity
high
Content hash
c7109c1776adc8cd9336aaf8…

Findings

  • high Unauthenticated REST listing of private RSS items, sources, and feed URLs

    information_disclosure

    feeds_item and feeds_source are registered public=>false, publicly_queryable=>false, show_ui=>false, but show_in_rest=>true with rest_base feed_items / feeds_source and no custom rest_controller or capability map. Core WP_REST_Posts_Controller::get_items_permissions_check returns true for context=view, and check_read_permission returns true whenever post_status is publish — it never consults the private post-type flags. Default collection status is publish, which is exactly how unread articles and successfully fetched sources are stored. register_post_meta(..., show_in_rest=>true) exposes _feeds_source_url, _feeds_item_permalink, and the rest of the underscore meta on those responses because WP_REST_Meta_Fields::get_value does not run auth_callback on read. The same pattern applies to taxonomy feeds_category (show_in_rest, rest_base feed_categories). Observable: GET /wp-json/wp/v2/feed_items and GET /wp-json/wp/v2/feeds_source with no cookie return the administrator's unread RSS library and subscription URLs (including tokenized private newsletter feeds). Trash/favorite/pending statuses stay gated on edit_posts.

    includes/CPT/class-feed-item-cpt.php:57-77

    Recommendation

    Keep show_in_rest if the admin React app needs it, but map every CPT/taxonomy capability (including read and create_posts) to manage_options, or supply a rest_controller that requires current_user_can('manage_options') on get_items/get_item as well as writes. Do not register underscore meta with show_in_rest unless those fields should be public. Mirror the same gate on feeds_source and feeds_category.

  • medium Feed source/item REST writes use post caps instead of manage_options

    missing_capability

    The Feeds UI and the plugin-owned REST routes (/feeds/v1/refresh/{id}, /feeds/v1/import-opml) require manage_options, but both CPTs set capability_type=>'post' and meta auth_callback current_user_can('edit_posts'). Core create_item_permissions_check therefore admits Contributor+ (drafts) and Author+ (publish). Feeds_Scheduler::on_source_saved runs on save_post_feeds_source with no extra cap: a published source is unscheduled then as_schedule_single_action('feeds_fetch_source'), which later calls fetch_feed on attacker-supplied _feeds_source_url (wp_safe_remote_request, so private IPs are blocked, but arbitrary public http(s) URLs are fetched and items are inserted as publish — feeding the unauthenticated listing). Editor/admin delete_others_posts can DELETE any source; handle_post_deletion then force-deletes every feeds_item whose _feeds_source_id matches. Authors can also PUT javascript: URLs into _feeds_source_url / _feeds_item_permalink, which the admin manager/drawer render as <a href> / Button href without protocol checks.

    includes/CPT/class-feed-source-cpt.php:55-75

    Recommendation

    Use a custom capability (e.g. manage_options or a dedicated manage_feeds cap granted only to administrators) for both CPTs and for every register_post_meta auth_callback. Validate _feeds_source_url with esc_url_raw / wp_http_validate_url before scheduling a fetch. Do not cascade-delete items unless the actor can manage the plugin.

WP Registry hashes the installable build and reports on that exact bytes-for-bytes copy. Embargoed findings are withheld until they are disclosed, so a clean verdict means nothing public is outstanding. WP Manifest does not audit code itself.