Problem/Motivation

We have a couple older sites where a Search API Database is used, and it seems attacks (potential AI based) are getting around Cloudflare/other server level bans sometimes and causing longer-running database queries which in parallel when attacked from multiple IPs, can easier overload the database. This is because if e.g. 50 words are entered, the query generated is quite long (WHERE word LIKE word1 OR word LIKE word2, etc). The maxlength does not help when allowing query string variables, and really its the number of words here that matters not the string length.

Of course optional as a modern site will often have a e.g. vector database where someone searching in sentence/question form is more likely/valid; however, I still think this would be a useful feature to have for sites still lingering on more traditional several keywords + database backend.

Steps to reproduce

  1. Use Search API Database
  2. Configure a fulltext exposed filter like 'keywords'
  3. Use a module like Views Ajax History to have query string variable based URLs
  4. Enter a long keyword string like ?keywords=one+two+three....etc+50
  5. Observe the SQL query

Proposed resolution

Allow restricting max words, aborting query before it runs when exceeded (similar to how invalid utf8 aborts)

Screenshot of full text field configuration

And:

Screenshot of front-end error message output

Remaining tasks

MR

CommentFileSizeAuthor
#3 output-example.png15.93 KBscott_euser
#3 configuration.png106.29 KBscott_euser

Issue fork search_api-3546439

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

scott_euser created an issue. See original summary.

scott_euser’s picture

Issue summary: View changes
StatusFileSize
new106.29 KB
new15.93 KB
scott_euser’s picture

Assigned: scott_euser » Unassigned
Status: Active » Needs review
scott_euser’s picture

Issue summary: View changes
scott_euser’s picture

Couldn't see a good option in Core for word splitting, opted to borrow the one used in the Search API Database backend and therefore suggesting to move it into Utility class as a result, but feel free to disagree of course

scott_euser’s picture

Probably needs update hook as well to set default empty value, but will wait for feedback as to whether this direction is acceptable first or not

drunken monkey’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests

Thanks a lot for proposing this new feature! This does sound potentially useful, and simple enough to implement, so we can definitely go ahead with this.

However, I do have a few remarks:

  • I don’t think using (and, therefore, moving) splitIntoWords() is necessary here. There is in fact already a $words defined in SearchApiFulltext::validateExposed(), a few lines further down. Just moving that up should be enough.
    The DB backend will only use splitIntoWords() if the “Tokenizer” processor is not active, which is a bad idea anyways, so a the simple preg_split() already used in the method should be fine. Just move the definition of $words up a few rows.
  • Also, I think the new check should come after the Unicode::validateUtf8() check, it’s too early in the method currently. Right before // Only continue if there is a minimum word length set. seems good.
  • I don’t think an update hook is needed, though. The defineOptions() change should be enough to keep existing views from breaking.
  • Finally, some test coverage would be nice. We don’t always add this for Views functionality, but it seems easy enough in this case to add it to ViewsTest::testSearchView() – just adapt the used view accordingly and then add a request with too many keywords.

In any case, thanks a lot again!

scott_euser’s picture

Assigned: Unassigned » scott_euser

Sure sounds like a good plan, thanks for the thorough review!

scott_euser’s picture

Assigned: scott_euser » Unassigned
Status: Needs work » Needs review

Thanks again for the review, I think that covers it; much smaller MR now + added test coverage

drunken monkey’s picture

Status: Needs review » Fixed
Issue tags: -Needs tests +Vienna2025

Great, thanks a lot!
I just made minimal changes and then merged.
Thanks again!

Now that this issue is closed, please review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, please credit people who helped resolve this issue.

scott_euser’s picture

Great thank you!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.