Skip to content

hardening: migrate quicktree SQL helpers to prepared variants, adopt Pest test harness - #20

Merged
TheWitness merged 12 commits into
Cacti:mainfrom
TheWitness:fix/prepared-sql-11-cacti
Sep 19, 2026
Merged

TheWitness merged 12 commits into
Cacti:mainfrom
TheWitness:fix/prepared-sql-11-cacti

Conversation

@TheWitness

Copy link
Copy Markdown
Member

Summary

Forks the changes from #12 (opened from an external fork) into a branch on the Cacti org's own fork tree, and adopts the Cacti-standard Pest test harness used by plugin_evidence.

  • migrate selected plugin_quicktree SQL helper reads to prepared variants (quicktree.php, setup.php)
  • add quicktree_security.php with quicktree_normalize_location() and use it for location handling / redirects
  • remove composer.json — Pest/PHPUnit are now provided by Cacti core's Composer-managed vendor tree, installed by the CI workflow, matching the plugin_evidence pattern
  • bring in phpunit.xml, tests/bootstrap-unit.php, tests/TestCase.php, tests/.cacti-version, and tests/Pest.php from plugin_evidence, adapted to quicktree's own source files (quicktree.php, setup.php, quicktree_security.php, ui_helpers.php)
  • convert the remaining plain-script tests (tests/test_prepared_statements.php, tests/test_form_wrapper.php) into Pest specs (tests/Security/PreparedStatementsMigrationTest.php, tests/Unit/FormWrapperTest.php) — all test cases now run under Pest
  • drop stale references to the removed plain-script files from the existing Pest specs
  • adapt .github/workflows/plugin-ci-workflow.yml from plugin_evidence to install/enable the quicktree plugin and run the full tests/ suite through Pest

Tests

  • php -l across all plugin and test PHP files
  • Pest suite under tests/ (Security, Unit, Integration, E2E) via the updated CI workflow

Closes #12

somethingwithproof and others added 8 commits September 17, 2026 21:52
Add targeted tests for prepared statement migration, output escaping,
auth guard presence, CSRF token validation, redirect safety, and
PHP 7.4 compatibility. Tests use source-scan patterns that verify
security invariants without requiring the Cacti database.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
- remove composer.json (Pest/PHPUnit now come from Cacti core's vendor tree via CI)
- import phpunit.xml, tests/bootstrap-unit.php, tests/TestCase.php, tests/.cacti-version, and tests/Pest.php from plugin_evidence, adapted for quicktree's source files
- convert tests/test_prepared_statements.php and tests/test_form_wrapper.php from plain assert scripts into Pest tests (tests/Security/PreparedStatementsMigrationTest.php, tests/Unit/FormWrapperTest.php)
- drop stale references to the removed plain-script test files from existing Pest specs
- adapt .github/workflows/plugin-ci-workflow.yml from plugin_evidence to install/test the quicktree plugin

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The redirect-safety tests fail against two redirects, and CI requests coverage without installing a coverage driver.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

This PR hardens QuickTree database access and location handling while migrating all tests to Pest with a Cacti-provided test environment.

Changes:

  • Converts selected SQL reads to prepared helpers.
  • Adds location normalization and redirect-safety checks.
  • Replaces standalone tests with Pest and updates CI integration.
File summaries
File Description
.github/workflows/plugin-ci-workflow.yml Adds Cacti-based Pest CI
phpunit.xml Configures the Pest suite
quicktree.php Uses prepared queries and normalized locations
quicktree_security.php Adds location normalization
setup.php Uses prepared version lookup
tests/bootstrap-unit.php Adds Cacti test bootstrap and stubs
tests/TestCase.php Adds shared test base
tests/Pest.php Adds Pest configuration
tests/.cacti-version Defines expected Cacti version
tests/Unit/* Adds unit coverage
tests/Security/* Adds security and compatibility checks
tests/Integration/* Adds redirect wiring checks
tests/E2E/* Adds debug-header regression check
tests/test_form_wrapper.php Replaced by Pest spec
tests/test_prepared_statements.php Replaced by Pest spec
composer.json Removed plugin-local dependency manifest
Review details

Suppressed comments (2)

quicktree.php:324

  • This redirect has the same termination problem: the switch break does not terminate the request, so RedirectSafetyTest fails and later code can run after the Location header. Add an exit immediately after the redirect.
		header('Location: quicktree.php?location=' . $location);

tests/Unit/FormWrapperTest.php:22

  • These guarded declarations redefine Cacti's global UI functions while Pest is loading an individual spec. If Cacti or another spec has already declared one, the guard skips the stub and this test either records no events or invokes production behavior; move the configurable stubs into the shared bootstrap/fixture instead.
if (!function_exists('top_header')) {
	function top_header() {
		$GLOBALS['__form_wrapper_events'][] = 'top_header';
	}
}
  • Files reviewed: 21/21 changed files
  • Comments generated: 8
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread .github/workflows/plugin-ci-workflow.yml
Comment thread quicktree.php
Comment thread tests/Security/AuthGuardTest.php Outdated
Comment thread tests/Security/Php74CompatibilityTest.php Outdated
Comment thread tests/Security/PreparedStatementConsistencyTest.php Outdated
Comment thread tests/Unit/FormWrapperTest.php Outdated
Comment thread quicktree_security.php
Comment thread setup.php
- quicktree.php: add missing exit after header(Location) redirects in the 'clear' and 'remove' actions, matching the existing pattern used elsewhere in the file (satisfies RedirectSafetyTest)
- tests/Security/SetupStructureTest.php: check the INFO file for name/version keys instead of a nonexistent inline array in setup.php, since plugin_quicktree_version() reads the version from INFO via parse_ini_file rather than returning a literal array
- explicitly install the xdebug coverage driver in CI so --coverage-clover cannot silently fail on a runner without one
- tests/Security/AuthGuardTest.php: assert the id request var is read via get_filter_request_var() directly instead of a vacuous check that never triggered
- tests/Security/Php74CompatibilityTest.php: remove the no-op 'array() vs short syntax' test (short array syntax isn't a PHP 7.4 compatibility issue, and the test never asserted anything)
- tests/Security/PreparedStatementConsistencyTest.php: tighten the interpolated-SQL heuristic to require zero matches, while excluding legitimate array(\) parameter binding from the check so it no longer flags safe prepared calls as false positives
- tests/bootstrap-unit.php: make get_nfilter_request_var() configurable via \['__test_request_vars'], and move the shared top_header/form_start/html_start_box/html_end_box/form_end stubs here so they are declared exactly once instead of being guarded per-spec
- tests/Unit/FormWrapperTest.php: use the configurable request var stub to exercise both the header-present and header-not-set branches of quicktree_action_form_begin()
- quicktree_security.php: apply the standard GPL v2 header used by setup.php/quicktree.php
- CHANGELOG.md: add a develop entry for the hardening and Pest test-harness migration
@TheWitness
TheWitness merged commit f2ec25a into Cacti:main Sep 19, 2026
3 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.

4 participants