how to escape alert/window.location.replace with variable

how do I esc them?

You don’t, both approaches are fundamentally wrong in multiple ways that make them irrecoverable.

First Case

echo "<script> alert( 'Authorization successful. Hello ' + '$me')</script>";

In this scenario we are trying to use alert to display a string, and append both values together. Aside from the usage of alert there are several mistakes:

  • If we want to insert the PHP variable $me into the JS string, why are we doing the concatenation in javascript?
  • We don’t know what $me is or where it’s coming from

The final product of this should be an alert function that takes a variable or a hardcoded string, no variations on that. So there will not be a + operator.

Additionally, we do not know what’s considered acceptable here, escaping is all about context and enforcing expectations but none have been provided. e.g. are HTML tags acceptable? Do we only want numbers and letters? Is it an email? The answers to these questions determine how you would escape the value.

This is the closest to an answer as you asked for it, and it’s not reliably secure:

?>
<script>alert(<?php echo wp_json_encode( 'Authorization successful. Hello ' . $me ); ?> );</script>
<?php

Because we do not know $me contains or what it’s intended to do, we have to assume you want to display a plaintext string safely with alert. So we JSON encode it. If it’s a string it’ll be passed in as a string. Notice that the string concatenation is happening in PHP, not JS. If $me is not a string then this code will fail.

Second Case

echo "<script> window.location.replace('$url'); </script>";

Here we can safely assume that $url is meant to hold a URL, therefore esc_url would be appropriate, but we can’t dump that into a JS snippet directly.

The next best thing we can try is this:

echo "<script> window.location.replace( ". wp_json_encode( esc_url( $url ) ) . " ); </script>";

Important

  • Don’t just use wp_json_encode everywhere, it isn’t the magic fix all escaping function for JS. The true fix is to never need to insert PHP variables directly into printed JS. It’s a strong code smell and a strong indicator that you’ve done something terribly wrong.
    • e.g. how would this work: alert( { object... } ); or <a href=""malicious string""
    • if you know the type of the value you can be more specific, e.g. intval would be more appropriate for a number
    • WordPress already has a mechanism for exposing data to javascript, e.g. wp_add_inline_script, see https://developer.wordpress.org/reference/functions/wp_add_inline_script/
    • In general you want to avoid printing a <script> tag with javascript inside from PHP, even if there are no variables, unless you really have to. Most of the times I’ve done it are for 3rd party integrations in a footer/header, never for the core logic of what I’m building.
  • The example involving window.location should never make it into production code. There are no situations where this wouldn’t be better served by a PHP call to wp_redirect instead
  • Escaping isn’t a magic function you apply to data to make it safe, it’s a cookie cutter that guarantees assumptions. Why trust that a variable contains a URL when you can guarantee it using esc_url? Then if it isn’t a URL it’ll be mangled into the shape of a URL and disarmed.

tech