| @@ -309,8 +309,28 @@ | ||
| 309 | 309 | return str_replace( array( '"', "\r", "\n" ), '', (string) $value ); |
| 310 | 310 | } |
| 311 | 311 | |
| 312 | 312 | /** |
| 313 | + * Whether the site address is an https:// one | |
| 314 | + * | |
| 315 | + * Read from the stored address and from nothing else. is_ssl() is false | |
| 316 | + * behind a proxy that terminates TLS and says nothing in a cron run or from | |
| 317 | + * WP-CLI, and home_url() takes its scheme from is_ssl() when the request is | |
| 318 | + * secure (wp-includes/link-template.php:3471-3477 in 7.1.2), so the same site | |
| 319 | + * would write different rules from an https request and from a scheduled | |
| 320 | + * task. Vigilante_Htaccess_Recovery and File | |
| 321 | + * Integrity compare the file with what this class would write now, so the | |
| 322 | + * answer has to be the same wherever it is asked. | |
| 323 | + * | |
| 324 | + * @since 3.0.2 | |
| 325 | + * | |
| 326 | + * @return bool | |
| 327 | + */ | |
| 328 | + private function site_address_is_https() { | |
| 329 | + return 0 === strpos( (string) get_option( 'home' ), 'https://' ); | |
| 330 | + } | |
| 331 | + | |
| 332 | + /** | |
| 313 | 333 | * Generate rules content (without markers) |
| 314 | 334 | * |
| 315 | 335 | * Public since 2.10.0: it is also "what this configuration would write right |
| 316 | 336 | * now", which is what Vigilante_Htaccess_Recovery compares the file against. |
| @@ -414,9 +434,25 @@ | ||
| 414 | 434 | } |
| 415 | 435 | } |
| 416 | 436 | |
| 417 | 437 | if ( ! empty( $csp['directives'] ) && is_array( $csp['directives'] ) ) { |
| 438 | + $site_is_https = $this->site_address_is_https(); | |
| 439 | + | |
| 418 | 440 | foreach ( $csp['directives'] as $directive => $value ) { |
| 441 | + /* | |
| 442 | + * upgrade-insecure-requests tells the browser to ask for every | |
| 443 | + * http:// resource of the page over https. On a site whose | |
| 444 | + * address is http:// nothing answers there, so every | |
| 445 | + * stylesheet, script and image stops loading, and the factory | |
| 446 | + * policy carries it. It is written only when the site address | |
| 447 | + * is https://. The setting itself is left as it is, so the | |
| 448 | + * next rewrite of the block after the address changes writes | |
| 449 | + * it. | |
| 450 | + */ | |
| 451 | + if ( 'upgrade-insecure-requests' === strtolower( (string) $directive ) && ! $site_is_https ) { | |
| 452 | + continue; | |
| 453 | + } | |
| 454 | + | |
| 419 | 455 | // Override frame-ancestors with synchronized value if X-Frame-Options is set |
| 420 | 456 | if ( 'frame-ancestors' === $directive && ! empty( $frame_ancestors_value ) ) { |
| 421 | 457 | $directives[] = $directive . ' ' . $frame_ancestors_value; |
| 422 | 458 | } elseif ( true === $value ) { |