Skip to content

hardening: migrate uninstall drop statements to prepared + align test framework with Thold - #30

Merged
TheWitness merged 17 commits into
Cacti:developfrom
TheWitness:fix/prepared-uninstall-drop-24
Sep 12, 2026
Merged

TheWitness merged 17 commits into
Cacti:developfrom
TheWitness:fix/prepared-uninstall-drop-24

Conversation

@TheWitness

@TheWitness TheWitness commented Sep 11, 2026

Copy link
Copy Markdown
Member

Summary

This carries forward #25 ("hardening: migrate uninstall drop statements to
prepared" by @somethingwithproof) and, in addition to that PR's
prepared-statement hardening, re-designs the Evidence plugin's test/CI
infrastructure identical to pull request #29:

  • Remove composer.json (no composer.lock was present) — Pest/PHPUnit
    no longer come from a vendor tree local to this plugin.
  • Add tests/.cacti-version, tests/TestCase.php, and
    tests/bootstrap-unit.php (adapted from thold). bootstrap-unit.php
    verifies the Cacti checkout in CI matches tests/.cacti-version,
    requires Cacti's own Composer vendor autoloader, and stubs the Cacti
    global functions plugin source expects.
  • Replace tests/bootstrap.php with tests/bootstrap-unit.php and update
    tests/Pest.php's comment to match.
  • Add phpunit.xml (none existed before), bootstrapping from
    tests/bootstrap-unit.php and covering tests/Security, tests/Unit,
    tests/Integration, and tests/E2E.
  • Add .github/copilot-instructions.md adapted from thold's for the
    Evidence plugin.

Supersedes #25.

Test plan

  • CI workflow (Pest Tests) builds the Cacti test image and runs Pest
    against tests/Security, tests/Unit, tests/Integration, and
    tests/E2E successfully.

somethingwithproof and others added 7 commits March 15, 2026 16:37
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>
Supersedes Cacti#25 ("hardening: migrate uninstall drop statements to
prepared" by @somethingwithproof) — this branch carries forward that
PR's prepared-statement hardening and test coverage, then updates the
test/CI plumbing to match the model used by Cacti/plugin_thold, mirroring
the same work already applied in PR Cacti#29:

- Remove composer.json (no composer.lock was present): Pest/PHPUnit no
  longer come from a vendor tree local to this plugin.
- Add tests/.cacti-version, tests/TestCase.php, and tests/bootstrap-unit.php
  (adapted from thold). bootstrap-unit.php verifies the Cacti checkout in
  CI matches tests/.cacti-version, requires Cacti's own Composer vendor
  autoloader, and stubs the Cacti global functions plugin source expects.
- Replace tests/bootstrap.php with tests/bootstrap-unit.php and update
  tests/Pest.php's comment to match.
- Add phpunit.xml (none existed before) bootstrapping from
  tests/bootstrap-unit.php and covering tests/Security, tests/Unit,
  tests/Integration, and tests/E2E.
- Add .github/copilot-instructions.md adapted from thold's for the
  Evidence plugin.
- Add .github/workflows/php-unit-tests.yml modeled on thold's workflow:
  checks out this plugin plus a pinned Cacti runtime and test toolchain,
  builds a Docker test image, lints, and runs Pest with coverage.
Adding phpunit.xml means these tests actually execute in CI for the
first time; two of them had latent bugs that were never caught before:

- AuthGuardTest.php checked tests/test_prepared_statements.php (a test
  helper script) instead of the plugin's real UI entry points
  (evidence.php, evidence_tab.php), causing a false-positive failure and
  a risky (zero-assertion) test once no matching line existed.
- SetupStructureTest.php regexed setup.php's raw source for `'name' =>`
  / `'version' =>`, but those keys live in the INFO ini file that
  setup.php parses at runtime, not in its literal source text. Assert
  against the parsed INFO file instead, matching PR Cacti#29's approach.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Several security checks are failing or vacuous, and the prepared-statement regression test is not executed by CI.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Hardens uninstall SQL and output escaping while aligning Evidence tests and CI with Cacti’s toolchain.

Changes:

  • Uses prepared uninstall statements and escapes rendered values.
  • Adds security, unit, integration, and E2E tests.
  • Adds Cacti bootstrap, PHPUnit configuration, pinned runtime, CI workflow, and project guidance.
File summaries
File Summary
tests/Unit/FilterOutputEscapingTest.php Tests output escaping.
tests/TestCase.php Adds shared test fixture.
tests/test_prepared_statements.php Prepared-statement assertions; moderate issue (3 votes): not discovered by the configured CI suite.
tests/Security/SetupStructureTest.php Setup structure checks; critical issue (3 votes): assertions do not match the current INFO contract.
tests/Security/RedirectSafetyTest.php Redirect checks; moderate issue (2 votes): scans files without redirects and is vacuous.
tests/Security/PreparedStatementConsistencyTest.php Prepared-statement consistency checks; moderate issue (2 votes): scans an incomplete file set.
tests/Security/Php74CompatibilityTest.php PHP 7.4 compatibility checks.
tests/Security/OutputEscapingTest.php Output escaping security checks.
tests/Security/AuthGuardTest.php Authentication guard checks; critical issue (3 votes): scans a helper that contains none of the expected includes.
tests/Pest.php Documents the test bootstrap.
tests/Integration/EvidenceTabEscapingTest.php Tests escaped tab output.
tests/E2E/EvidenceFilterXssRegressionTest.php Tests filter XSS regression wiring.
tests/bootstrap-unit.php Loads Cacti tooling and stubs globals.
tests/.cacti-version Pins the expected Cacti version.
setup.php Uses prepared uninstall statements.
phpunit.xml Configures test suites and coverage.
evidence_tab.php Escapes rendered values.
.github/workflows/php-unit-tests.yml Adds Cacti-based Docker CI.
.github/copilot-instructions.md Documents project conventions.
Review details
  • Files reviewed: 19/19 changed files
  • Comments generated: 5
  • 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 tests/Security/AuthGuardTest.php Outdated
Comment thread tests/Security/SetupStructureTest.php Outdated
Comment thread tests/Security/PreparedStatementConsistencyTest.php
Comment thread tests/Security/RedirectSafetyTest.php
Comment thread tests/test_prepared_statements.php Outdated
.github/copilot-instructions.md, .github/workflows/php-unit-tests.yml,
tests/.cacti-version, tests/TestCase.php, and tests/bootstrap-unit.php
were committed with CRLF line endings. Normalize them to LF to match the
rest of the repo, and add .gitattributes (`* text=auto eol=lf`) so this
doesn't regress.
- PreparedStatementConsistencyTest.php: drop the non-existent
  tests/test_prepared_statements.php target and narrow the description/
  scope to the setup.php uninstall/drop path it actually verifies,
  instead of implying (and failing to enforce) coverage of every plugin
  file's DB calls.
- RedirectSafetyTest.php: scan the real redirect entry points
  (index.php, images/index.php, data/index.php) instead of setup.php,
  which has no header(Location) call at all.
- index.php, images/index.php, data/index.php: follow the
  header("Location: ...") redirect with exit, so the test above passes
  for a real reason and the scripts can't fall through if code is later
  added after the redirect.
- Php74CompatibilityTest.php: drop the dangling reference to the removed
  tests/test_prepared_statements.php.
- Convert tests/test_prepared_statements.php (a standalone script never
  discovered by phpunit.xml or Pest's *Test.php convention, so its
  assertions never ran in CI) into
  tests/Security/UninstallPreparedStatementsTest.php, a proper Pest test
  with the same assertions.
@TheWitness
TheWitness merged commit a2c64d6 into Cacti:develop Sep 12, 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