Problem/Motivation

Follow-up to #3625451: Search strings are output unescaped on the Zeitgeist report page, which fixed this on 5.x-1.x.

The report page at admin/reports/search/zeitgeist (_zeitgeist_page()) outputs recorded search strings unescaped: they are passed to theme('table'), which prints cell contents verbatim.

Search strings are visitor input, recorded by the submit handlers zeitgeist_form_alter() adds to the search forms, including for anonymous users with the search content permission. With the default "Upon display" validation setting, strings containing HTML are stored, and only the blocks filter them. So any visitor can inject markup that runs in the browser of a user with access site reports viewing the report page.

Drupal 6 is unsupported, so this is handled in the public queue.

While fixing it, these related defects were found and fixed in the same change:

  • The "Top searches" block ignored the "validate search strings" setting: only the "Latest searches" block applied it.
  • The latest and top blocks each rendered with the other's template.
  • zeitgeist_update_1() called db_change_column(), a PostgreSQL-only helper from update.php, with a Schema API array.
  • zeitgeist_page_single_column() appended to an undefined variable.

Steps to reproduce

  1. Enable search and Zeitgeist, and grant search content to anonymous users.
  2. As an anonymous user, submit the search form with <b>test</b>. Drupal 6 records searches on form submission only, so visiting a search URL does not record anything.
  3. As an administrator, visit admin/reports/search/zeitgeist: "test" is rendered in bold, meaning the markup was output as HTML instead of text.

Proposed resolution

  • Escape search strings with check_plain() in _zeitgeist_page(). The blocks already escape them through l().
  • Apply _zeitgeist_validate() in the "Top searches" block, fetching an unlimited range so that rejected strings do not shrink the list.
  • Map each block to the template named after it.
  • Use db_change_field() in zeitgeist_update_1().
  • Documentation: remove CVS keywords, fix the settings path, add PHP's date.timezone to the prerequisites, update URLs.

Remaining tasks

  • Review and commit to 6.x-1.x.
  • Release 6.x-1.1.
  • 7.x has the same unescaped output in the multicolumn report (ReportMulticolumn): separate follow-up.

User interface changes

None.

API changes

Themes overriding zeitgeist-block-latest.tpl.php or zeitgeist-block-top.tpl.php must swap their copies and rename the variable each uses: see INSTALL.txt, "Upgrading".

Data model changes

None.

AI disclosure

Fix developed with Claude Opus 5.5.

Comments

fgm created an issue. See original summary.

  • fgm committed 8b8a1aa2 on 6.x-1.x
    fix: #3625471 Search strings are output unescaped on the Zeitgeist...
fgm’s picture

Status: Active » Fixed

Committed in 6.x-1.1

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

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

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

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