Problem/Motivation

When attempting to sort the search on a non existing field server returns HTTP code 500 (WSOD).

Drupal\search_api_solr\Plugin\search_api\backend\SearchApiSolrBackend::setSorts() will pass user submitted string directly to Solarium\QueryType\Select\Query\Query::addSort() without checking if that string is valid sort or not.

This will cause warning and TypeError because Drupal\search_api_solr\Utility\Utility::getSortableSolrField won't be able to find sortable field and will return NULL.

Warning: reset() expects parameter 1 to be array, null given in Drupal\search_api_solr\Utility\Utility::getSortableSolrField() (line 531 of web/modules/contrib/search_api_solr/src/Utility/Utility.php).

The website encountered an unexpected error. Please try again later.
TypeError: Argument 1 passed to Solarium\QueryType\Select\Query\Query::addSort() must be of the type string, null given, called in web/modules/contrib/search_api_solr/src/Plugin/search_api/backend/SearchApiSolrBackend.php on line 4143 in Solarium\QueryType\Select\Query\Query->addSort() (line 415 of vendor/solarium/solarium/src/QueryType/Select/Query/Query.php).
Stack trace:
Solarium\QueryType\Select\Query\Query->addSort(NULL, 'desc') (Line: 4143)
Drupal\search_api_solr\Plugin\search_api\backend\SearchApiSolrBackend->setSorts(Object, Object) (Line: 1453)
Drupal\search_api_solr\Plugin\search_api\backend\SearchApiSolrBackend->search(Object) (Line: 468)
Drupal\search_api\Entity\Server->search(Object) (Line: 539)
Drupal\search_api\Query\Query->execute() (Line: 575)
Drupal\search_api\Plugin\views\query\SearchApiQuery->execute(Object) (Line: 1426)
Drupal\views\ViewExecutable->execute(NULL) (Line: 52)
Drupal\webprofiler\Views\TraceableViewExecutable->render() (Line: 183)
Drupal\views\Plugin\views\display\Page->execute() (Line: 1630)
...

Note: all the line numbers above correspond to release 4.1.4.

Valid reason when invalid sort string may be submitted is after sortable field has been removed from the index but search engines not aware of this change continue attempting to access URLs containing the outdated sort.

I also encountered cases when malicious users attempt to exploit the site by providing encoded SQL queries as sort.

Steps to reproduce

Supply non-existing field name as sort parameter.

For example assume there is a search view at the path: /search.

Visit the URL /search?sort=nonexisting_field&order=desc

Order parameter is irrelevant here. It can be either 'desc' or 'asc'.

Proposed resolution

Attempt to add sort only if the string passed as sort matches known/existing field. Ignore all other strings.

When visiting URL /search?sort=nonexisting_field&order=desc I expect invalid sort to be ignored and search results returned as if sort wasn't defined at all.

Remaining tasks

None.

User interface changes

None.

API changes

None.

Data model changes

None.

Comments

vaish created an issue. See original summary.

vaish’s picture

Here is the patch implementing proposed solution.

vaish’s picture

Issue summary: View changes
mkalkbrenner’s picture

Status: Active » Needs work

You're right!

But I prefer if we check the result of getSortableField() instead before we call addSort().
And we should trigger a warning about it to inform the site admin.

vaish’s picture

Status: Needs work » Needs review
StatusFileSize
new685 bytes

Thanks for the feedback, @mkalkbrenner. Here is a new patch. This one throws exception if sort is not a valid solr field. User will see an error message on the page and search won't return any results. I think this makes more sense than pretending that nothing wrong happened.

And we should trigger a warning about it to inform the site admin.

I'm assuming by this you meant adding a warning to the dblog? On the site I'm maintaining I was getting more that 200 of those every day. I'm not sure how useful is to have a log full of such messages when I'm not really able to do anything about it. If you still think warning is necessary, I can add one.

  • mkalkbrenner committed a8680f7 on 4.x authored by vaish
    Issue #3165913 by vaish, mkalkbrenner: TypeError: Argument 1 passed to...
mkalkbrenner’s picture

Status: Needs review » Fixed

Status: Fixed » Closed (fixed)

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