Skip to content

Plugin Directory: Search: Only boost whole-slug matches, to prevent slug squatting. See #8225.#682

Open
dd32 wants to merge 1 commit into
WordPress:trunkfrom
dd32:fix/8225-slug-search-squatting
Open

Plugin Directory: Search: Only boost whole-slug matches, to prevent slug squatting. See #8225.#682
dd32 wants to merge 1 commit into
WordPress:trunkfrom
dd32:fix/8225-slug-search-squatting

Conversation

@dd32
Copy link
Copy Markdown
Member

@dd32 dd32 commented Jun 6, 2026

Refiles #674 from dd32/wordpress.org due to GitHub Sync deleting branches.


Fixes the slug boost in plugin search so it rewards searching for a plugin by its slug without letting plugins squat on common keywords via their slug. See https://meta.trac.wordpress.org/ticket/8225.

Problem

slug_text was part of the high-weight (boost: 5) most_fields title clause. slug_text is word-tokenized — wp-google-mapswp, google, maps — so a generic single-word query like map matched a fragment of every *-map(s) slug and collected the full slug boost. This is a slug-squatting vector: stuffing a popular term into a slug buys ranking on that term.

Concretely, for the query map, every plugin with map as one slug word got the boost, and the only top results without it (wp-google-maps, google-maps-widget, whose slugs contain maps, not map) were the ones penalised — the opposite of intent.

Fix

Match the query against the whole-slug slug keyword field, normalised with sanitize_title() (the same function that generated the slug), via a constant_score clause. The slug boost now fires only when the query is the plugin's identifier, not when it shares one word with it. slug_text is removed from the title most_fields clause; title matching is unchanged.

Behaviour — slug-searches still match the expected plugin

Search query Normalised Result
map map no slug boost (no plugin's whole slug is map) — squatting prevented
maps maps no slug boost — squatting prevented
wp-google-maps wp-google-maps boosts wp-google-maps
WP Google Maps (spaces) wp-google-maps boosts wp-google-maps
wordpress-seo wordpress-seo boosts wordpress-seo
leaflet-map leaflet-map boosts leaflet-map
contact-form-7 contact-form-7 boosts contact-form-7
woocommerce woocommerce boosts woocommerce ✓ (single-word brand slugs still match)

Verified against the live index: single common words (map/maps) match zero whole-slugs, while every real slug search returns exactly its plugin with a flat, predictable score.

…lug squatting.

The slug boost is meant to reward searches looking for a specific plugin by
its slug (e.g. `wordpress-seo`), not topic searches that happen to share one
word with a slug. Because `slug_text` is word-tokenized and was part of the
high-weight title `most_fields` clause, a single-word query like `map` matched
a fragment of every `*-map(s)` slug and collected the full slug boost, letting
plugins squat on common terms via their slug.

Match the query against the whole-slug `slug` keyword field instead, normalised
with `sanitize_title()`, via a `constant_score` clause. Slug searches still hit
the expected plugin, while a single common word only matches a plugin whose
entire slug is that word.

See #8225.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 6, 2026 04:23
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 6, 2026

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props dd32.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the Plugin Directory’s Jetpack/ElasticSearch query boosting to prevent “slug squatting” by ensuring the high-weight slug boost only applies when the user’s query matches an entire plugin slug (after sanitize_title() normalization), rather than matching individual slug tokens.

Changes:

  • Removes slug_text from the high-boost title multi_match clause to stop partial slug-token matches from receiving the full boost.
  • Adds a constant_score + term query against the whole-slug slug keyword field (normalized via sanitize_title()), so only full-slug queries get boosted.
  • Adds in-code rationale documenting the squatting vector and the intended new behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

// still scores a decisive, constant boost, while a single common word
// only matches a plugin whose entire slug is that word.
$slug_candidate = sanitize_title( $search_phrase );
if ( $slug_candidate ) {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants