fix(security): harden AI summary, docs listing, QuickSearch & feedback endpoints#330
Conversation
…k endpoints
- REST /docs/{id}/ai-summary/generate: replace __return_true with a
permission callback (published-only for anonymous, edit_docs bypass) and
rate-limit anonymous requests to curb AI cost abuse; wp_kses_post the
stored summary to prevent stored XSS.
- AJAX wedocs_get_docs: return draft/pending docs only to users who can
edit docs (was leaking unpublished content to anonymous callers).
- AJAX wedocs_ajax_feedback: reject non-docs post IDs before writing meta.
- REST /docs/contributors: return display_name instead of user_login
(user enumeration).
- QuickSearch results template: escape the doc title before highlighting
(stored XSS via title in nopriv AJAX HTML response).
- Add wedocs_rate_limit_ok() per-IP transient rate limiter.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (2)
WalkthroughThe changes restrict AI summary and AJAX document access, add per-IP rate limiting, validate feedback targets, sanitize generated summaries, display contributor names, and safely highlight quick-search title matches. ChangesDocumentation security hardening
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
Suggested labels: Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 PHPStan (2.2.2)PHP Fatal error: Uncaught Error: Undefined constant "ABSPATH" in /includes/functions.php:423 Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@includes/API/API.php`:
- Around line 808-813: Update the contributor loop around get_userdata to check
whether it returned a valid user before accessing display_name or calling
get_avatar_url. Skip deleted or otherwise missing contributor accounts, while
preserving the existing data mapping for valid users.
In `@includes/functions.php`:
- Around line 1201-1213: Update wedocs_rate_limit_ok to implement a fixed window
by storing the window start time alongside the request count, resetting both
only when the existing window has expired, and preserving the original expiry
rather than refreshing it on every allowed request. Also make the counter update
atomic or otherwise prevent concurrent requests from passing the same limit
check, while retaining the current key isolation and boolean return behavior.
In `@src/blocks/QuickSearch/templates/search-results.php`:
- Around line 44-55: Update the title handling around $title and
$highlighted_title to retain the raw document title for matching instead of
applying esc_html() before preg_replace(). Reconstruct the highlighted output
from raw matched and unmatched fragments, escaping each fragment before
inserting the trusted <mark> wrapper, and use context-specific escaping at
output boundaries such as the esc_attr() call. Preserve normal unhighlighted
output and support both array and scalar title values.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 834a36b1-075e-4357-85af-489913b489df
📒 Files selected for processing (4)
includes/API/API.phpincludes/Ajax.phpincludes/functions.phpsrc/blocks/QuickSearch/templates/search-results.php
- Guard get_userdata() against deleted contributor accounts (avoid fatal on ->display_name) - Make wedocs_rate_limit_ok() a true fixed window; preserve original TTL instead of sliding it - Highlight QuickSearch results against the raw title and escape each fragment (no entity-name matches, no double escaping)
Audit tracker: weDevsOfficial/wedocs-pro#349
Fixes (audit issues, tracked on the pro repo): weDevsOfficial/wedocs-pro#344, #345, #346, #347, #348
Summary
Security hardening for weDocs Free (2.3.1). One bundled PR covering the five findings from the manual audit (tracked in
weDevsOfficial/wedocs-pro#349). All fixes are backward-compatible — the public "Generate AI Summary" button and QuickSearch keep working; only anonymous access to unpublished content, cost abuse, and unescaped output are closed.Fixes
__return_true→generate_summary_permissions_check(published-only for anon,edit_docsbypass) + per-IP rate limit +wp_kses_poston saveincludes/API/API.phpwedocs_get_docsreturns unpublished statuses only toedit_docsusersincludes/Ajax.php<mark>highlightsrc/blocks/QuickSearch/templates/search-results.phpdocspost IDs beforeupdate_post_metaincludes/Ajax.phpuser_loginenumerationdisplay_nameincludes/API/API.phpAdds
wedocs_rate_limit_ok()(per-IP transient limiter) inincludes/functions.php.Compatibility
Callers traced in
src//assets/build/first: the AI-summary button and QuickSearch are public-by-design and stay public (hardened with validation + rate-limit + escaping);get_docs/feedback are unchanged for legitimate use. No frontend build change required —assets/build/**is CI-generated fromsrc/**.Testing
php -lclean on all changed PHP. Manual: anon generate on a published doc still returns a summary; anon generate on a draft → 403; QuickSearch highlights an HTML-bearing title escaped.Summary by CodeRabbit
Security & Access
Improvements