1, 'id' => '', 'scan_id' => '', 'category' => 'configuration', 'location' => '', 'observed_at' => gmdate( 'c' ), 'detector_id' => '', 'detector_version' => '1.0.0', 'severity' => 'info', 'confidence' => 'informational', 'reason' => '', 'limitations' => array(), 'recommended_action' => 'Review the evidence.', 'evidence' => array(), 'source' => array( 'provider' => 'Shieldlume Security', 'provenance' => 'Original local analysis', ), 'scope' => array(), 'rule_freshness' => array( 'version' => '1.0.0', 'published_at' => '2026-09-22', ), 'content_hash' => '', 'component_version' => 'unknown', 'policy_version' => 1, 'action_eligibility' => array( 'repair' => false, 'reason' => 'No verified replacement is available.', 'reference' => null, ), ), $data ); foreach ( array( 'category' => array( 'known_malware', 'suspicious_behavior', 'integrity_change', 'vulnerable_software', 'configuration' ), 'severity' => array( 'info', 'low', 'medium', 'high', 'critical' ), 'confidence' => array( 'confirmed', 'strong', 'suspicious', 'informational' ), ) as $key => $allowed ) { if ( ! in_array( $finding[ $key ], $allowed, true ) ) { // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped -- Exception text is internal data, not HTML output; UI consumers escape at their output context. Escaping here would corrupt JSON/plain-text evidence and chained exception arguments. throw new \InvalidArgumentException( 'Invalid finding ' . $key . '.' ); } } if ( ! $finding['location'] || ! $finding['detector_id'] ) { throw new \InvalidArgumentException( 'A finding requires a location and detector.' ); } if ( 'integrity_change' === $finding['category'] && 'confirmed' === $finding['confidence'] ) { throw new \InvalidArgumentException( 'An integrity mismatch cannot confirm malware.' ); } if ( ! $finding['id'] ) { $finding['id'] = self::identity( $finding['location'], $finding['detector_id'] ); } return $finding; } public static function identity( string $location, string $detector ): string { return 'f_' . substr( hash( 'sha256', $location . "\0" . $detector ), 0, 60 ); } public static function exceptionKey( array $finding ): string { // JSON fixes field boundaries: concatenation with an attacker controlled delimiter is unsafe. return hash( 'sha256', json_encode( array( base64_encode( (string) ( $finding['location'] ?? '' ) ), (string) ( $finding['content_hash'] ?? '' ), base64_encode( (string) ( $finding['component_version'] ?? 'unknown' ) ), (string) ( $finding['detector_id'] ?? '' ), (string) ( $finding['detector_version'] ?? '' ), (int) ( $finding['policy_version'] ?? 1 ), ), JSON_UNESCAPED_SLASHES | JSON_INVALID_UTF8_SUBSTITUTE | JSON_THROW_ON_ERROR ) ); } }