Make WordPress Core


Ignore:
Timestamp:
02/02/2021 08:53:53 PM (3 years ago)
Author:
adamsilverstein
Message:

Security: add Content-Security-Policy script loaders.

Add new functions wp_get_script_tag, wp_print_script_tag, wp_print_inline_script_tag and wp_get_inline_script_tag that support script attributes. Enables passing attributes such as async or nonce, creating a path forward for enabling a Content-Security-Policy in core, plugins and themes.

Props tomdxw, johnbillion, jadeddragoon, jrchamp, mallorydxw, epicfaace, alinod, enricocarraro, ocean90.
Fixes #39941.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/functions.php

    r50148 r50167  
    78677867    return abs( (float) $expected - (float) $actual ) <= $precision;
    78687868}
     7869
     7870/**
     7871 * Sanitizes an attributes array into an attributes string to be placed inside a `<script>` tag.
     7872 *
     7873 * Automatically injects type attribute if needed.
     7874 * Used by {@see wp_get_script_tag()} and {@see wp_get_inline_script_tag()}.
     7875 *
     7876 * @since 5.7.0
     7877 *
     7878 * @param array $attributes Key-value pairs representing `<script>` tag attributes.
     7879 * @return string String made of sanitized `<script>` tag attributes.
     7880 */
     7881function wp_sanitize_script_attributes( $attributes ) {
     7882    $html5_script_support = ! is_admin() && ! current_theme_supports( 'html5', 'script' );
     7883    $attributes_string    = '';
     7884
     7885    // If HTML5 script tag is supported, only the attribute name is added
     7886    // to $attributes_string for entries with a boolean value, and that are true.
     7887    foreach ( $attributes as $attribute_name => $attribute_value ) {
     7888        if ( is_bool( $attribute_value ) ) {
     7889            if ( $attribute_value ) {
     7890                $attributes_string .= $html5_script_support ? sprintf( ' %1$s="%2$s"', esc_attr( $attribute_name ), esc_attr( $attribute_name ) ) : ' ' . $attribute_name;
     7891            }
     7892        } else {
     7893            $attributes_string .= sprintf( ' %1$s="%2$s"', esc_attr( $attribute_name ), esc_attr( $attribute_value ) );
     7894        }
     7895    }
     7896
     7897    return $attributes_string;
     7898}
     7899
     7900/**
     7901 * Formats `<script>` loader tags.
     7902 *
     7903 * It is possible to inject attributes in the `<script>` tag via the {@see 'wp_script_attributes'} filter.
     7904 * Automatically injects type attribute if needed.
     7905 *
     7906 * @since 5.7.0
     7907 *
     7908 * @param array $attributes Key-value pairs representing `<script>` tag attributes.
     7909 * @return string String containing `<script>` opening and closing tags.
     7910 */
     7911function wp_get_script_tag( $attributes ) {
     7912    if ( ! isset( $attributes['type'] ) && ! is_admin() && ! current_theme_supports( 'html5', 'script' ) ) {
     7913        $attributes['type'] = 'text/javascript';
     7914    }
     7915    /**
     7916     * Filters attributes to be added to a script tag.
     7917     *
     7918     * @since 5.7.0
     7919     *
     7920     * @param array $attributes Key-value pairs representing `<script>` tag attributes.
     7921     *                          Only the attribute name is added to the `<script>` tag for
     7922     *                          entries with a boolean value, and that are true.
     7923     */
     7924    $attributes = apply_filters( 'wp_script_attributes', $attributes );
     7925
     7926    return sprintf( "<script%s></script>\n", wp_sanitize_script_attributes( $attributes ) );
     7927}
     7928
     7929/**
     7930 * Prints formatted `<script>` loader tag.
     7931 *
     7932 * It is possible to inject attributes in the `<script>` tag via the  {@see 'wp_script_attributes'}  filter.
     7933 * Automatically injects type attribute if needed.
     7934 *
     7935 * @since 5.7.0
     7936 *
     7937 * @param array $attributes Key-value pairs representing `<script>` tag attributes.
     7938 */
     7939function wp_print_script_tag( $attributes ) {
     7940    echo wp_get_script_tag( $attributes );
     7941}
     7942
     7943/**
     7944 * Wraps inline JavaScript in `<script>` tag.
     7945 *
     7946 * It is possible to inject attributes in the `<script>` tag via the  {@see 'wp_script_attributes'}  filter.
     7947 * Automatically injects type attribute if needed.
     7948 *
     7949 * @since 5.7.0
     7950 *
     7951 * @param string $javascript Inline JavaScript code.
     7952 * @param array  $attributes  Optional. Key-value pairs representing `<script>` tag attributes.
     7953 * @return string String containing inline JavaScript code wrapped around `<script>` tag.
     7954 */
     7955function wp_get_inline_script_tag( $javascript, $attributes = array() ) {
     7956    if ( ! isset( $attributes['type'] ) && ! is_admin() && ! current_theme_supports( 'html5', 'script' ) ) {
     7957        $attributes['type'] = 'text/javascript';
     7958    }
     7959    /**
     7960     * Filters attributes to be added to a script tag.
     7961     *
     7962     * @since 5.7.0
     7963     *
     7964     * @param array $attributes Key-value pairs representing `<script>` tag attributes.
     7965     *                          Only the attribute name is added to the `<script>` tag for
     7966     *                          entries with a boolean value, and that are true.
     7967     */
     7968    $attributes = apply_filters( 'wp_inline_script_attributes', $attributes, $javascript );
     7969
     7970    $javascript = "\n" . trim( $javascript, "\n\r " ) . "\n";
     7971
     7972    return sprintf( "<script%s>%s</script>\n", wp_sanitize_script_attributes( $attributes ), $javascript );
     7973}
     7974
     7975/**
     7976 * Prints inline JavaScript wrapped in `<script>` tag.
     7977 *
     7978 * It is possible to inject attributes in the `<script>` tag via the  {@see 'wp_script_attributes'}  filter.
     7979 * Automatically injects type attribute if needed.
     7980 *
     7981 * @since 5.7.0
     7982 *
     7983 * @param string $javascript Inline JavaScript code.
     7984 * @param array  $attributes Optional. Key-value pairs representing `<script>` tag attributes.
     7985 */
     7986function wp_print_inline_script_tag( $javascript, $attributes = array() ) {
     7987    echo wp_get_inline_script_tag( $javascript, $attributes );
     7988}
Note: See TracChangeset for help on using the changeset viewer.