PluginProbe
Vigilant – 100% Free Security Suite: Firewall, 2FA, Login, Headers, Scanner… / 3.0.4
Vigilant – 100% Free Security Suite: Firewall, 2FA, Login, Headers, Scanner… v3.0.4
3.0.5 3.0.4 3.0.3 3.0.2 3.0.1 3.0.0 2.11.12 2.11.11 2.11.10 2.11.9 2.11.7 2.11.8 2.11.6 2.11.5 2.11.4 2.11.3 2.11.1 2.11.2 2.11.0 2.10.5 2.10.4 2.10.3 2.10.2 2.10.1 2.10.0 All 93 releases
← All changes | includes/class-security-headers.php +95 -27 3.0.5 → 3.0.4 View file →
@@ -551,46 +551,114 @@
551 551 return implode( "\n", $rules );
552 552 }
553 553
554 554 /**
555 - * Warnings about the Content-Security-Policy as it is configured
555 + * Get security grade based on enabled headers
556 556 *
557 - * They are about what is saved in the tab, not about what reaches the
558 - * browser: that is measured by the checks of Security Check, which is
559 - * also what the Test Headers button shows. Until 3.0.4 that button graded
560 - * these settings and listed them as enabled headers without asking the
561 - * site for anything.
562 - *
563 - * @since 3.0.5
564 - *
565 - * @return string[]
557 + * @return array
566 558 */
567 - public function get_csp_warnings() {
559 + public function get_security_grade() {
560 + $score = 0;
561 + $enabled = array();
562 + $missing = array();
568 563 $warnings = array();
569 564
570 - if ( empty( $this->options['csp']['enabled'] ) ) {
571 - return $warnings;
565 + // X-Frame-Options (15 points)
566 + if ( ! empty( $this->options['x_frame_options'] ) ) {
567 + $score += 15;
568 + $enabled[] = 'X-Frame-Options: ' . $this->options['x_frame_options'];
569 + } else {
570 + $missing[] = 'X-Frame-Options';
572 571 }
573 572
574 - if ( ! empty( $this->options['csp']['report_only'] ) ) {
575 - $warnings[] = __( 'CSP is in report-only mode: the browser reports what the policy would block, and blocks nothing.', 'vigilante' );
576 - return $warnings;
573 + // X-Content-Type-Options (15 points)
574 + if ( ! empty( $this->options['x_content_type_options'] ) ) {
575 + $score += 15;
576 + $enabled[] = 'X-Content-Type-Options: nosniff';
577 + } else {
578 + $missing[] = 'X-Content-Type-Options';
577 579 }
578 580
579 - if ( $this->is_csp_restrictive() ) {
580 - $warnings[] = __( 'Restrictive CSP detected. Admin area is automatically excluded to prevent breaking the dashboard and block editor.', 'vigilante' );
581 + // HSTS (20 points)
582 + if ( ! empty( $this->options['hsts']['enabled'] ) ) {
583 + $hsts = $this->options['hsts'];
584 + if ( $hsts['max_age'] >= 31536000 ) {
585 + $score += 20;
586 + } else {
587 + $score += 10;
588 + $warnings[] = 'HSTS max-age should be at least 1 year (31536000 seconds)';
589 + }
590 + $enabled[] = 'Strict-Transport-Security';
591 + } else {
592 + $missing[] = 'Strict-Transport-Security (HSTS)';
581 593 }
582 594
583 - foreach ( $this->get_csp_compatibility_issues() as $issue ) {
584 - if ( 'high' === $issue['severity'] ) {
585 - $warnings[] = sprintf(
586 - /* translators: 1: CSP directive name, 2: Issue description */
587 - __( 'CSP %1$s: %2$s', 'vigilante' ),
588 - $issue['directive'],
589 - $issue['issue']
590 - );
595 + // CSP (30 points; absorbs the 10 points freed by retiring the deprecated X-XSS-Protection)
596 + if ( ! empty( $this->options['csp']['enabled'] ) ) {
597 + if ( empty( $this->options['csp']['report_only'] ) ) {
598 + $score += 30;
599 + $enabled[] = 'Content-Security-Policy';
600 +
601 + // Add warning if CSP is restrictive
602 + if ( $this->is_csp_restrictive() ) {
603 + $warnings[] = __( 'Restrictive CSP detected. Admin area is automatically excluded to prevent breaking the dashboard and block editor.', 'vigilante' );
604 + }
605 +
606 + // Check for specific compatibility issues
607 + $csp_issues = $this->get_csp_compatibility_issues();
608 + foreach ( $csp_issues as $issue ) {
609 + if ( 'high' === $issue['severity'] ) {
610 + $warnings[] = sprintf(
611 + /* translators: 1: CSP directive name, 2: Issue description */
612 + __( 'CSP %1$s: %2$s', 'vigilante' ),
613 + $issue['directive'],
614 + $issue['issue']
615 + );
616 + }
617 + }
618 + } else {
619 + $score += 15;
620 + $enabled[] = 'Content-Security-Policy-Report-Only';
621 + $warnings[] = 'CSP is in report-only mode (recommended for testing)';
591 622 }
623 + } else {
624 + $missing[] = 'Content-Security-Policy';
592 625 }
593 626
594 - return $warnings;
627 + // Referrer-Policy (10 points)
628 + if ( ! empty( $this->options['referrer_policy'] ) ) {
629 + $score += 10;
630 + $enabled[] = 'Referrer-Policy: ' . $this->options['referrer_policy'];
631 + } else {
632 + $missing[] = 'Referrer-Policy';
633 + }
634 +
635 + // Permissions-Policy (10 points)
636 + if ( ! empty( $this->options['permissions_policy']['enabled'] ) ) {
637 + $score += 10;
638 + $enabled[] = 'Permissions-Policy';
639 + } else {
640 + $missing[] = 'Permissions-Policy';
641 + }
642 +
643 + // Calculate grade
644 + if ( $score >= 90 ) {
645 + $grade = 'A';
646 + } elseif ( $score >= 80 ) {
647 + $grade = 'B';
648 + } elseif ( $score >= 70 ) {
649 + $grade = 'C';
650 + } elseif ( $score >= 60 ) {
651 + $grade = 'D';
652 + } else {
653 + $grade = 'F';
654 + }
655 +
656 + return array(
657 + 'grade' => $grade,
658 + 'score' => $score,
659 + 'headers' => $enabled,
660 + 'missing' => $missing,
661 + 'warnings' => $warnings,
662 + );
595 663 }
596 664 }