[wp-trac] [WordPress Trac] #63851: Audit wp_json_encode usage with script tags
WordPress Trac
noreply at wordpress.org
Wed Aug 20 16:50:21 UTC 2025
#63851: Audit wp_json_encode usage with script tags
----------------------------+-------------------------
Reporter: jonsurrell | Owner: (none)
Type: task (blessed) | Status: new
Priority: normal | Milestone: 6.9
Component: General | Version:
Severity: normal | Resolution:
Keywords: good-first-bug | Focuses: javascript
----------------------------+-------------------------
Description changed by jonsurrell:
Old description:
> `wp_json_encode` is used to print data in script tags in many places
> without the appropriate JSON flags.
>
> #62797 is an example of the general problem where `wp_json_encode( $data
> )` is insufficient to safely print data in a script tag.
>
> [https://sirre.al/2025/08/06/safe-json-in-script-tags-how-not-to-
> break-a-site/ A detailed analysis of the problem can be found here] where
> I recommend `wp_json_encode( $data, JSON_HEX_TAG | JSON_UNESCAPED_SLASHES
> )` to encode data safely for use in script tags.
>
> Note that ''safe'' in this context means that the content will not alter
> the expected HTML document structure. The `SCRIPT` element will not close
> prematurely, nor will the element be prevented from closing at its
> apparent `</script>` close tag. ''Safe'' in this context has nothing to
> do with the behavior of the JavaScript when evaluated by the browser. The
> JavaScript behavior in unaffected by these changes.
>
> A good example of the ongoing issue is `wp_localize_script`. The
> following snippet breaks the containing script tag and prevents the
> script element from closing:
>
> {{{#!php
> <?php
> wp_enqueue_script( '_example', '/ex.js', array(), '0.0', false );
> wp_localize_script( '_example', '_', array( '<!--' => '<script>' ) );
> }}}
>
> This produces HTML like
>
> {{{
> <script id="_example-js-extra">
> var _ = {"<!--":"<script>"};
> </script>
> <script src="http://localhost:8888/ex.js?ver=0.0" id="_example-
> js"></script>
> …the rest of the HTML page
> }}}
>
> Resulting in a tree like
>
> {{{
> └─SCRIPT id="_example-js-extra"
> └─#text var _ = {"<!--":"<script>"}; </script> <script
> src="http://localhost:8888/ex.js?ver=0.0" id="_example-js"></script> …the
> rest of the HTML page
> }}}
>
> The SCRIPT element does not close as expected and the rest of the HTML
> page is part of the script contents.
>
> [60648] fixed the issue in #62797 and is a good example of the necessary
> changes.
New description:
`wp_json_encode()` is used to print data in script tags in many places
without the appropriate JSON flags.
#62797 is an example of the general problem where `wp_json_encode( $data
)` is insufficient to safely print data in a script tag.
[https://sirre.al/2025/08/06/safe-json-in-script-tags-how-not-to-
break-a-site/ A detailed analysis of the problem can be found here] where
I recommend `wp_json_encode( $data, JSON_HEX_TAG | JSON_UNESCAPED_SLASHES
)` to encode data safely for use in script tags.
Note that ''safe'' in this context means that the content will not alter
the expected HTML document structure. The `SCRIPT` element will not close
prematurely, nor will the element be prevented from closing at its
apparent `</script>` close tag. ''Safe'' in this context has nothing to do
with the behavior of the JavaScript when evaluated by the browser. The
JavaScript behavior in unaffected by these changes.
A good example of the ongoing issue is `wp_localize_script`. The following
snippet breaks the containing script tag and prevents the script element
from closing:
{{{#!php
<?php
wp_enqueue_script( '_example', '/ex.js', array(), '0.0', false );
wp_localize_script( '_example', '_', array( '<!--' => '<script>' ) );
}}}
This produces HTML like
{{{
<script id="_example-js-extra">
var _ = {"<!--":"<script>"};
</script>
<script src="http://localhost:8888/ex.js?ver=0.0" id="_example-
js"></script>
…the rest of the HTML page
}}}
Resulting in a tree like
{{{
└─SCRIPT id="_example-js-extra"
└─#text var _ = {"<!--":"<script>"}; </script> <script
src="http://localhost:8888/ex.js?ver=0.0" id="_example-js"></script> …the
rest of the HTML page
}}}
The SCRIPT element does not close as expected and the rest of the HTML
page is part of the script contents.
[60648] fixed the issue in #62797 and is a good example of the necessary
changes.
--
--
Ticket URL: <https://core.trac.wordpress.org/ticket/63851#comment:3>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list