PluginProbe
Vigilant – 100% Free Security Suite: Firewall, 2FA, Login, Headers, Scanner… / 2.9.8
Vigilant – 100% Free Security Suite: Firewall, 2FA, Login, Headers, Scanner… v2.9.8
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 2.9.9 2.9.8 2.9.6 2.9.7 2.9.5 All 88 releases
vigilante / includes / class-head-cleaner.php

class-head-cleaner.php in Vigilant – 100% Free Security Suite: Firewall, 2FA, Login, Headers, Scanner… 2.9.8, at includes/class-head-cleaner.php

165 lines 5.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Head Cleaner Class
4 *
5 * Handles removal of unnecessary head tags that expose information
6 *
7 * @package Vigilante
8 */
9
10 // Prevent direct access
11 if ( ! defined( 'ABSPATH' ) ) {
12 exit;
13 }
14
15 /**
16 * Class Vigilante_Head_Cleaner
17 *
18 * Removes unnecessary elements from wp_head for security purposes
19 */
20 class Vigilante_Head_Cleaner {
21
22 /**
23 * Settings instance
24 *
25 * @var Vigilante_Settings
26 */
27 private $settings;
28
29 /**
30 * Head cleaner options
31 *
32 * @var array
33 */
34 private $options;
35
36 /**
37 * Constructor
38 *
39 * @param Vigilante_Settings $settings Settings instance.
40 */
41 public function __construct( $settings ) {
42 $this->settings = $settings;
43 $this->options = $settings->get_section( 'wp_hardening' );
44
45 $this->init_hooks();
46 }
47
48 /**
49 * Initialize hooks
50 */
51 private function init_hooks() {
52 add_action( 'init', array( $this, 'clean_head' ) );
53 }
54
55 /**
56 * Clean up wp_head output
57 */
58 public function clean_head() {
59 // Remove WordPress generator meta tag (hides version)
60 if ( ! empty( $this->options['remove_wp_generator'] ) ) {
61 remove_action( 'wp_head', 'wp_generator' );
62 add_filter( 'the_generator', '__return_empty_string' );
63 }
64
65 // Strip the WordPress version from enqueued script/style URLs
66 // (?ver=X.Y.Z). The "Remove Generator" option above only hides
67 // the <meta name="generator"> tag, leaving the version visible in
68 // every asset URL.
69 if ( ! empty( $this->options['remove_wp_version_assets'] ) ) {
70 add_filter( 'style_loader_src', array( $this, 'strip_wp_version_from_src' ), 9999, 1 );
71 add_filter( 'script_loader_src', array( $this, 'strip_wp_version_from_src' ), 9999, 1 );
72 }
73
74 // Remove RSD link (not needed for most sites)
75 if ( ! empty( $this->options['remove_rsd_link'] ) ) {
76 remove_action( 'wp_head', 'rsd_link' );
77 }
78
79 // Remove Windows Live Writer manifest (obsolete)
80 if ( ! empty( $this->options['remove_wlw_manifest'] ) ) {
81 remove_action( 'wp_head', 'wlwmanifest_link' );
82 }
83
84 // Remove shortlink
85 if ( ! empty( $this->options['remove_shortlink'] ) ) {
86 remove_action( 'wp_head', 'wp_shortlink_wp_head', 10 );
87 remove_action( 'template_redirect', 'wp_shortlink_header', 11 );
88 }
89
90 // Remove adjacent posts links
91 if ( ! empty( $this->options['remove_adjacent_posts'] ) ) {
92 remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head', 10 );
93 remove_action( 'wp_head', 'adjacent_posts_rel_link', 10 );
94 remove_action( 'wp_head', 'start_post_rel_link', 10 );
95 remove_action( 'wp_head', 'parent_post_rel_link', 10 );
96 remove_action( 'wp_head', 'index_rel_link' );
97 }
98
99 // Remove REST API link from header
100 if ( ! empty( $this->options['remove_rest_api_link'] ) ) {
101 remove_action( 'wp_head', 'rest_output_link_wp_head', 10 );
102 remove_action( 'template_redirect', 'rest_output_link_header', 11 );
103 }
104
105 // Remove oEmbed links
106 if ( ! empty( $this->options['remove_oembed_links'] ) ) {
107 remove_action( 'wp_head', 'wp_oembed_add_discovery_links' );
108 remove_action( 'wp_head', 'wp_oembed_add_host_js' );
109 }
110 }
111
112 /**
113 * Strip the WordPress version from an enqueued asset URL.
114 *
115 * Only removes the "ver" query argument when it matches the current
116 * WordPress version, so versions injected by plugins/themes (used for
117 * legitimate cache busting) are preserved.
118 *
119 * @param string $src Asset URL.
120 * @return string Filtered URL.
121 */
122 public function strip_wp_version_from_src( $src ) {
123 if ( ! is_string( $src ) || '' === $src || false === strpos( $src, 'ver=' ) ) {
124 return $src;
125 }
126
127 $wp_version = get_bloginfo( 'version' );
128 if ( ! $wp_version ) {
129 return $src;
130 }
131
132 // Match both ?ver=X.Y.Z and &ver=X.Y.Z exactly. Use the WP helper so
133 // we cover URL-encoded variants and avoid touching unrelated arguments.
134 $parts = wp_parse_url( $src );
135 if ( empty( $parts['query'] ) ) {
136 return $src;
137 }
138
139 parse_str( $parts['query'], $query );
140 if ( ! isset( $query['ver'] ) || (string) $query['ver'] !== (string) $wp_version ) {
141 return $src;
142 }
143
144 return remove_query_arg( 'ver', $src );
145 }
146
147 /**
148 * Get list of removable items for security
149 *
150 * @return array
151 */
152 public static function get_removable_items() {
153 return array(
154 'remove_wp_generator' => __( 'WordPress version meta tag', 'vigilante' ),
155 'remove_wp_version_assets' => __( 'WordPress version in asset URLs (?ver=)', 'vigilante' ),
156 'remove_rsd_link' => __( 'RSD (Really Simple Discovery) link', 'vigilante' ),
157 'remove_wlw_manifest' => __( 'Windows Live Writer manifest link', 'vigilante' ),
158 'remove_shortlink' => __( 'Shortlink', 'vigilante' ),
159 'remove_adjacent_posts' => __( 'Adjacent posts rel links', 'vigilante' ),
160 'remove_rest_api_link' => __( 'REST API link', 'vigilante' ),
161 'remove_oembed_links' => __( 'oEmbed discovery links', 'vigilante' ),
162 );
163 }
164 }
165