Security Findings
When WPHammer runs security scans, it produces individual findings — specific issues discovered on a site or server. The findings system aggregates these results, deduplicates them across scan runs, tracks their lifecycle, and lets you triage or suppress findings that are not actionable.
Finding structure
Each SecurityFinding records:
- Type — what category of issue was found (
FindingTypeenum: CoreIntegrity, PluginIntegrity, SuspiciousFile, FilePermission, Vulnerability, SuspiciousCron, Abandoned, AbusePattern) - Severity — how serious the finding is (
FindingSeverityenum: Critical, High, Medium, Low, Info) - Status — where the finding is in its lifecycle (
FindingStatusenum: New, Regressed, Dismissed, FalsePositive, Resolved, Suppressed) - Title and description — human-readable summary of the issue
- File path — the specific file involved, if applicable
- Signature — an xxh128 hash generated from the finding type and a unique identifier, used for deduplication across scan runs
- Occurrence tracking —
occurrence_count,first_seen_at, andlast_seen_attrack how often and when the finding has appeared
For vulnerability-type findings, additional fields track:
- CVE ID — the Common Vulnerabilities and Exposures identifier
- Plugin slug — the affected WordPress plugin
- Affected version and patched version — version range information
- Patch status — whether a fix is available (
PatchStatusenum)
Finding lifecycle
Findings move through a defined lifecycle:
New findings
When a scan discovers an issue for the first time, it creates a finding with New status. The signature ensures that if the same issue appears in a subsequent scan, it increments the occurrence_count and updates last_seen_at rather than creating a duplicate.
Triage
Team members can triage findings by calling triage() on the finding, which records:
- The new status (Dismissed, FalsePositive, or Resolved)
- The user who triaged it
- Optional triage notes explaining the decision
- A timestamp of when the triage occurred
Regression
If a previously resolved or dismissed finding reappears in a later scan, its status changes to Regressed and regressed_at is set. This surfaces issues that were thought to be fixed but have returned — a common scenario after plugin updates or restored backups.
Active findings
A finding is considered active (via isActive()) when its status is New or Regressed. These are the findings that need attention.
Scan context
Every finding belongs to a SecurityScan record that tracks the scan event itself:
- Scan type — what kind of scan was run (
ScanTypeenum: Full, Integrity, Files, Vulnerabilities, Crons, Abuse) - Status — whether the scan is pending, running, completed, or failed
- Finding counts — aggregated counts by severity (critical, high, medium, low, info, total)
- Timing —
started_at,completed_at, andduration_seconds
When a scan completes, markAsCompleted() automatically counts findings by severity and stores the totals on the scan record. The worstSeverity() method returns the highest severity found, useful for quick assessment.
Suppression rules
For findings that are known and accepted — such as intentional file permission changes or expected custom code patterns — you can create suppression rules. The SecurityRule model defines team-level rules that automatically suppress matching findings:
- Match type — which finding type to match (or
*for all types) - Match pattern — a signature or glob pattern to match against
- Match field — whether to match on
signatureorfile_path - Scope — rules can be scoped to a specific server, site, or apply team-wide
When isSuppressed() is called on a finding, it checks whether any active rule matches the finding's type, signature, and file path within the team's rules. Matched rules track how many times they have been applied (times_matched) and when (last_matched_at).
You can create a suppression rule directly from a finding using suppressForTeam(), which generates a rule matching that finding's type and signature.
Reviewing findings
The security findings view aggregates findings across all scans for a site or server. Key review patterns:
- By severity — critical and high findings should be reviewed first
- By status — filter to active findings (New and Regressed) to see what needs attention
- By type — group by finding type to batch-review similar issues
- By recurrence — findings with high
occurrence_countor recentregressed_atdates indicate persistent problems
The dashboard Security tab provides a fleet-wide view of findings across all servers and sites.
Related
- Uptime Monitoring — Site availability monitoring
- Visual Checks — Canary visual regression checks
- Server Security — How scans are configured and run
- Plugin Management — Vulnerability matching for WordPress plugins