-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathforce-https.php
222 lines (191 loc) · 8.43 KB
/
force-https.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
<?php
/*
Plugin Name: Force HTTPS
Plugin URI: https://www.littlebizzy.com/plugins/force-https
Description: HTTPS enforcement for WordPress
Version: 3.0.0
Author: LittleBizzy
Author URI: https://www.littlebizzy.com
Requires PHP: 7.0
Tested up to: 6.7
License: GPLv3
License URI: http://www.gnu.org/licenses/gpl-3.0.html
Update URI: false
GitHub Plugin URI: littlebizzy/force-https
Primary Branch: master
Text Domain: force-https
*/
// prevent direct access
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// override wordpress.org with git updater
add_filter( 'gu_override_dot_org', function( $overrides ) {
$overrides[] = 'force-https/force-https.php';
return $overrides;
}, 999 );
// enforce https at the database level only if wordpress is incorrectly detecting http
// home_url and site_url should not be in force_https_securize_url because it would run on every call unnecessarily
function force_https_filter_home( $value ) {
if ( is_ssl() ) {
return $value;
}
return set_url_scheme( $value, 'https' );
}
// no priority needed since pre_option filters override values immediately
add_filter( 'pre_option_home', 'force_https_filter_home' );
add_filter( 'pre_option_siteurl', 'force_https_filter_home' );
// enforce https by redirecting non-ssl requests on frontend, admin, and login pages
function force_https_redirect() {
// exit if already using https
if ( is_ssl() ) {
return;
}
// exit if headers are sent, running via cli, cron, ajax, or if no request uri exists
if ( headers_sent() || defined( 'WP_CLI' ) || defined( 'DOING_CRON' ) || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) || ! isset( $_SERVER['REQUEST_URI'] ) ) {
return;
}
// redirect to https version of the requested url
wp_redirect( set_url_scheme( home_url( $_SERVER['REQUEST_URI'] ), 'https' ), 301 );
exit;
}
// apply https redirect during initialization, admin, and login
add_action( 'init', 'force_https_redirect', 10 );
add_action( 'admin_init', 'force_https_redirect', 10 );
add_action( 'login_init', 'force_https_redirect', 10 );
// enforce https for valid urls only
function force_https_securize_url( $value ) {
// return unchanged if not a string or does not start with http
if ( ! is_string( $value ) || stripos( $value, 'http://' ) !== 0 ) {
return $value;
}
// convert to https
return set_url_scheme( $value, 'https' );
}
// apply https to urls used across wordpress
add_filter( 'admin_url', 'force_https_securize_url', 10 );
add_filter( 'author_feed_link', 'force_https_securize_url', 10 );
add_filter( 'category_feed_link', 'force_https_securize_url', 10 );
add_filter( 'category_link', 'force_https_securize_url', 10 );
add_filter( 'content_url', 'force_https_securize_url', 10 );
add_filter( 'embed_oembed_html', 'force_https_securize_url', 10 );
add_filter( 'get_avatar_url', 'force_https_securize_url', 10 );
add_filter( 'get_custom_logo', 'force_https_securize_url', 10 );
add_filter( 'get_the_permalink', 'force_https_securize_url', 10 );
add_filter( 'includes_url', 'force_https_securize_url', 10 );
add_filter( 'login_redirect', 'force_https_securize_url', 10 );
add_filter( 'logout_redirect', 'force_https_securize_url', 10 );
add_filter( 'nav_menu_link_attributes', 'force_https_securize_url', 10 );
add_filter( 'network_home_url', 'force_https_securize_url', 10 );
add_filter( 'network_site_url', 'force_https_securize_url', 10 );
add_filter( 'page_link', 'force_https_securize_url', 10 );
add_filter( 'plugins_url', 'force_https_securize_url', 10 );
add_filter( 'post_link', 'force_https_securize_url', 10 );
add_filter( 'rest_url', 'force_https_securize_url', 10 );
add_filter( 'tag_link', 'force_https_securize_url', 10 );
add_filter( 'term_link', 'force_https_securize_url', 10 );
add_filter( 'wp_get_attachment_url', 'force_https_securize_url', 10 );
add_filter( 'wp_logout_url', 'force_https_securize_url', 10 );
// apply https to woocommerce urls if woocommerce is active
if ( class_exists( 'WooCommerce' ) ) {
add_filter( 'wc_get_endpoint_url', 'force_https_securize_url', 10 );
add_filter( 'woocommerce_account_endpoint_url', 'force_https_securize_url', 10 );
add_filter( 'woocommerce_email_footer_text', 'force_https_filter_output', 999 );
add_filter( 'woocommerce_rest_prepare_coupon', 'force_https_filter_output', 999 );
add_filter( 'woocommerce_rest_prepare_customer', 'force_https_filter_output', 999 );
add_filter( 'woocommerce_rest_prepare_order', 'force_https_filter_output', 999 );
add_filter( 'woocommerce_rest_prepare_product', 'force_https_filter_output', 999 );
}
// enforce https on html content that may contain urls
function force_https_filter_output( $content ) {
// return unchanged if not a string
if ( ! is_string( $content ) ) {
return $content;
}
// replace http with https in text or html output
return str_replace( 'http://', 'https://', $content );
}
// apply https enforcement to html content
add_filter( 'comment_text', 'force_https_filter_output', 20 );
add_filter( 'post_thumbnail_html', 'force_https_filter_output', 10 );
add_filter( 'render_block', 'force_https_filter_output', 20 );
add_filter( 'rest_pre_echo_response', 'force_https_filter_output', 999 );
add_filter( 'walker_nav_menu_start_el', 'force_https_filter_output', 10 );
add_filter( 'widget_text', 'force_https_filter_output', 20 );
add_filter( 'widget_text_content', 'force_https_filter_output', 20 );
// enforce https on elements and inline content
add_filter( 'the_content', 'force_https_process_content', 20 );
function force_https_process_content( $content ) {
// match elements with src, href, action, content, or formaction attributes
static $element_pattern = '#(?i)(<(?:a|img|iframe|video|audio|source|form|link|embed|object|track|script|meta|input|button)\b[^>]*\s*(?:href|src|action|content|formaction)=["\'])http://([^"\']+)#';
// match script and style content
static $script_style_pattern = '#(<(?i:script|style)\b[^>]*>)(.*?)</(?i:script|style)>#s';
// replace http with https in elements
$content = preg_replace_callback(
$element_pattern,
function ( $matches ) {
return $matches[1] . 'https://' . $matches[2];
},
$content
);
// replace http and escaped http in script and style blocks
return preg_replace_callback(
$script_style_pattern,
function ( $matches ) {
preg_match('/<\s*(script|style)/i', $matches[1], $tag_match);
return $matches[1] . str_replace(
['http://', 'http:\/\/'],
['https://', 'https:\/\/'],
$matches[2]
) . '</' . $tag_match[1] . '>';
},
$content
);
}
// enforce https on wp resource hints to prevent mixed content issues
add_filter( 'wp_resource_hints', 'force_https_fix_resource_hints', 20 );
function force_https_fix_resource_hints( $urls ) {
// return unchanged if not an array
if ( ! is_array( $urls ) ) {
return $urls;
}
// loop through each url and enforce https where needed
foreach ( $urls as $key => $url ) {
if ( is_string( $url ) ) {
$urls[$key] = set_url_scheme( $url, 'https' );
} elseif ( is_array( $url ) && isset( $url['href'] ) ) {
$urls[$key]['href'] = set_url_scheme( $url['href'], 'https' );
}
}
return $urls;
}
// enforce https on image srcsets to prevent mixed content issues
add_filter( 'wp_calculate_image_srcset', 'force_https_fix_image_srcsets', 999 );
function force_https_fix_image_srcsets( $sources ) {
// return unchanged if sources is not an array
if ( ! is_array( $sources ) ) {
return $sources;
}
// loop through each source and enforce https on urls
foreach ( $sources as $key => $source ) {
// check if url is set and enforce https
if ( isset( $source['url'] ) ) {
$sources[$key]['url'] = set_url_scheme( $source['url'], 'https' );
}
}
return $sources;
}
// enforce https on urls in the upload directory to avoid insecure media links
add_filter( 'upload_dir', 'force_https_fix_upload_dir', 999 );
function force_https_fix_upload_dir( $uploads ) {
// enforce https on the main upload url
if ( isset( $uploads['url'] ) ) {
$uploads['url'] = set_url_scheme( $uploads['url'], 'https' );
}
// enforce https on the base upload url
if ( isset( $uploads['baseurl'] ) ) {
$uploads['baseurl'] = set_url_scheme( $uploads['baseurl'], 'https' );
}
return $uploads;
}
// Ref: ChatGPT