37 Audits
πŸ”

Search Auditor

Security Auditor

Checks the site search page for uncapped page size and empty queries

SecurityResilience
200 credits
Per check
~30 seconds
Average runtime
Active
Status

How it works

  1. Fetch β€” loads the search page with the 37 Audits user agent (Basic auth is honoured). If the page cannot be fetched, or answers HTTP 400 or higher, the audit is ERROR (500).

  2. Detect β€” asks each visitor whether it recognises the platform. The Liferay visitor matches when the monitored stack lists Liferay, the response carries a Liferay-Portal header, or the HTML contains the Search Results portlet or Liferay.ThemeDisplay. No match is ERROR (501).

  3. Validate β€” the resultSelector preference must be set (405) and must parse as a CSS selector or XPath (502). Nothing else runs until it does.

  4. Probe (Liferay) β€” sends four requests to the search page, each bounded by timeoutSeconds:

    • ?q= β€” empty query, default page size.

    • ?q=* β€” wildcard query, default page size. Also discovers the Search Results portlet namespace and a pagination link.

    • ?q=&delta=101 β€” empty query with a page size one above maxDelta (plus the namespaced delta when known).

    • ?q=*&delta=101 β€” wildcard query with a page size one above maxDelta.

  5. Count β€” on every answered probe, the elements matching resultSelector are counted. A probe that times out is a FAIL on its own and is not counted.

  6. Redirect chain β€” links on the wildcard page and on its first pagination page are decoded looking for a redirect parameter that nests another one.

  7. Aggregate β€” ERROR wins, then FAIL, then WARNING; if every rule passes, the audit is SUCCESS (200).

What this auditor validates

Every row maps to one checkRule* method and one CheckCode. Codes 500–502, 405 and 200 apply to every platform; 300 and 400–404 belong to the Liferay visitor. A future platform visitor continues the same sequence. CheckCode suffixes use status ranges: 200 success, 300–399 warning, 400–499 fail, 500–599 error.

CheckCodeStatusWhen it firesRecommendationWhy it matters
37A-SearchAuditor-500ERRORThe search page or one of the probe requests could not be fetched, or answered with HTTP 400 or higher (for example a WAF returning 403).Make sure {probeUrl} is reachable by the auditor and returns HTML.β€”
37A-SearchAuditor-501ERRORNo visitor recognised the platform (no Liferay in the stack, no Liferay-Portal header, no Liferay markup).Point this auditor at the site search page of a supported platform ({supported}; for Liferay usually /search) or add the platform to the monitored stack.β€”
37A-SearchAuditor-405FAILThe resultSelector preference is not configured, so results cannot be counted.Set the resultSelector preference for {url} to the CSS selector or XPath that matches one search result item (for example li.list-group-item).Until results can be counted, none of the search hardening rules can run, so the search page stays unaudited and its problems go unreported.
37A-SearchAuditor-502ERRORThe resultSelector preference is set but does not parse as a CSS selector or XPath.Fix the resultSelector preference {selector} so it parses as a CSS selector or an XPath expression.β€”
37A-SearchAuditor-404FAILLiferay: a probe (?q=, ?q=*, ?q=&delta={maxDelta+1} or ?q=*&delta={maxDelta+1}) did not answer within timeoutSeconds. One check per probe that timed out.Make {probeUrl} answer within {timeoutSeconds} seconds: cap the pagination delta, disable empty searches and index only what needs to be searchable.A search that does not answer in time is one visitors give up on, and slow queries triggered by bots can tie up the server for everyone else.
37A-SearchAuditor-401FAILLiferay: ?q= (empty query) returned one or more results.Disable "Allow Empty Searches" on the Liferay Search Bar / Search Results portlet so {probeUrl} returns no results.An empty query that returns everything exposes the entire index to scraping and turns every accidental or automated empty search into an expensive query for the server.
37A-SearchAuditor-300WARNINGLiferay: ?q=* (wildcard query) returned one or more results, so the whole index can be browsed.Reject or sanitise wildcard-only queries on the Liferay Search Bar so {probeUrl} returns no results.A wildcard query lets anyone list and scrape the whole search index, including content that was never meant to be found by browsing.
37A-SearchAuditor-403FAILLiferay: ?q=&delta={maxDelta+1} (empty query, page size above the maximum) returned one or more results.Disable "Allow Empty Searches" and cap the pagination delta on the Liferay Search Results portlet so {probeUrl} returns no results.An empty query combined with a huge page size is the cheapest way for a bot to dump the whole index and the costliest query the search backend can receive.
37A-SearchAuditor-400FAILLiferay: ?q=*&delta={maxDelta+1} returned more than maxDelta results in one page.Cap the Search Results portlet pagination delta at {maxDelta} or less; {probeUrl} currently returns {count} results in one page.An unbounded page size lets a single request pull thousands of results, which can overload the search backend and lets scrapers download the whole index in a few calls.
37A-SearchAuditor-402FAILLiferay: a link on the results page or on the first pagination page carries a redirect parameter that nests another redirect parameter (depth 2 or more).Remove the redirect parameter from the Liferay Search Results / Asset Publisher pagination URLs so {pageUrl} links stop nesting the previous URL.URLs that grow on every page change eventually exceed server limits and fail, and the bloated links hurt sharing, caching and search engine crawling.
37A-SearchAuditor-200SUCCESSEvery platform rule passed. Message is Search page "{url}" passed all {platform} search rules.β€”β€”

Output Documentation

StatusDescriptionTest logic
SUCCESSThe search page passed every rule of the detected platformLiferay: every probe answered in time, q= and q=&delta={maxDelta+1} return 0 results, q=* returns 0 results, q=*&delta={maxDelta+1} returns at most maxDelta results, and no link nests a redirect inside a redirect (200).
WARNINGThe search page can be browsed with a wildcardLiferay: q=* returns results (300) and nothing else fails.
FAILThe search page is misconfigured or cannot be audited as configuredMissing resultSelector (405); probe timeout (404); results for an empty query (401); results for an empty query with a large delta (403); more than maxDelta results for delta={maxDelta+1} (400); nested redirect parameters (402). Several can fire together.
ERRORThe auditor could not run the rulesSearch page or probe request failed or returned HTTP 400+ (500); platform not recognised (501); resultSelector does not parse (502).

Risks and Considerations

Uncapped page size is a denial-of-service vector

  • Liferay reads the delta parameter to size the results page. Without a cap, ?delta=5000 makes the portal ask Elasticsearch for thousands of documents and render them all, on every request.

  • Liferay caps delta at 200 by default, but custom themes, fragments and portlet configuration can raise or bypass it. This auditor expects maxDelta (100 by default) or less, and only ever asks for one result more than that.

Empty searches list the whole index

  • With "Allow Empty Searches" enabled, ?q= returns every indexed document. That surfaces content that is only reachable by search (drafts, internal pages, documents) and makes scraping trivial.

Redirect chains break URLs

  • Liferay portlets append the current URL as a redirect parameter so "back" navigation works. When a pagination link re-encodes a URL that already carries a redirect, every page change nests one more level. After a few clicks the URL is several kilobytes long, breaks caches and proxies, and eventually hits request-line limits.

  • Links from other portlets on the search page (for example Asset Publisher) are scanned too, because the same mechanism affects them.

Timeouts are findings

  • Liferay renders every result item server side. A request that cannot answer within timeoutSeconds (default 20) is a sign that the page size or the empty search is not capped, and is reported as a FAIL rather than an auditor error.

  • Slow but correctly configured sites can raise timeoutSeconds up to 30 per URL.

What this auditor does not check

  • It does not audit search relevance, indexing coverage, or the search bar on other pages.

  • If the search index has maxDelta or fewer documents matching *, the delta rule cannot prove a violation and passes.

  • If the results page has no pagination link, the redirect chain rule only inspects the results page itself.

  • Counting depends entirely on resultSelector. A selector that matches nothing makes every count rule pass; verify it against the live page when configuring the URL.

This documentation is built and hosted on Mintlify, a developer documentation platform.

Source: docs.37audits.com

Ready to start auditing?

Add this auditor to your monitoring setup and start identifying issues on your websites today.

Β© 2026 37 Audits. All rights reserved. Audit your websites with confidence.

Supported by

Made with ❀️ in Floripa