Skip to content

Security review fixes (component): settings validation, escaping, permissions, token hashes - #18

Merged
codeling merged 4 commits into
mainfrom
security-review-fixes
Oct 8, 2026
Merged

codeling merged 4 commits into
mainfrom
security-review-fixes

Conversation

@codeling

@codeling codeling commented Oct 7, 2026

Copy link
Copy Markdown
Owner

Summary

Component side of the security review fixes; the plugin side is in codeling/bfstop (branch security-review-fixes, which also holds all tests - they cover both extensions).

  • Unblock page looks tokens up by their hash (the plugin stores only hashes now - merge together with the plugin PR).
  • Settings validation: every list/integer setting has validate="options" (Joomla does not check submitted values against the options otherwise); notification addresses are checked (emaillist rule); the maxBlocksBefore option "6" had the value 5.
  • Escaping: messages built from form input (IpValidateHelper) are escaped - Joomla renders messages as HTML.
  • Permissions: the settings and log views need core.admin (was core.manage).
  • Small bugs: allow list removal casts ids itself and reports the outcome; UnblockHelper::unblockDB no longer reads an undefined variable after an exception; unblock page works while the plugin is disabled; failed login list fallback ordering column.

Existing saved values that do not fit a setting's options (e.g. a delay not a multiple of 5) must be re-selected when the settings are next saved.

Testing

Run from the bfstop repository with both branches checked out: 322 tests passing on Joomla 5.4.8 / PostgreSQL 16; the new component tests fail against the unfixed code. check-language.php has no errors (pre-existing missing-translation warnings only). Not run: MySQL/MariaDB, Joomla 6.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LhhhdjhErC9ZiaS4HyRjsh


Generated by Claude Code

claude added 4 commits October 7, 2026 20:55
The plugin stores only a hash of each unblock token now
(DatabaseHelper::hashToken()); the unblock page hashes the token of the
link the same way.

Needs the matching bfstop change (branch security-review-fixes).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LhhhdjhErC9ZiaS4HyRjsh
…s and log

- Every list/integer setting is validated against its options (Joomla only
  does that with validate="options"), the notification addresses against
  the email format; the 'maxBlocksBefore' option 6 had the value 5.
- Messages built from what was typed into a form are escaped: Joomla shows
  them as HTML.
- The settings and log views need core.admin, not just core.manage.
- The allow list removal casts the ids itself and reports what happened; the
  unblock helper no longer reads an undefined result after an exception; the
  unblock page works while the plugin is disabled; the failed login list falls
  back to its own sort column.

Tests are in the bfstop repository (tests/Integration/ComponentTest.php).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LhhhdjhErC9ZiaS4HyRjsh
Models use their own database (getDatabase()) instead of Factory::getDbo()
and the deprecated $_db property, so they also work with the database a
caller injects; the controller and helpers get the DatabaseInterface from the
container; SettingsModel creates the extension table directly instead of via
Table::getInstance(). All three are deprecated and gone in Joomla 7.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LhhhdjhErC9ZiaS4HyRjsh
- $app->input -> getInput(); CMSApplication::getCfg() -> get()
- Views ask their model (->getModel()->getItems() ...) instead of the
  deprecated View::get() (deprecated in Joomla 5.3)
- Stylesheets of the edit views are registered with the WebAssetManager
  instead of Document::addStyleSheet(); the path is relative to the site root
  (a leading slash would give a protocol-relative URL)
- Factory::getLanguage()/getSession() -> the application's getLanguage()/
  getSession()

The test for the deprecated calls is in the bfstop repository
(tests/Unit/DeprecatedApiTest.php).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LhhhdjhErC9ZiaS4HyRjsh
@codeling
codeling merged commit 8d72b7b into main Oct 8, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants