0

I'm trying to write my first WordPress plugin and despite reading the documentation about escaping and reviewing other people's questions and answers I'm still not clear on how to do it in 2 cases the plugin checker said I should I have a line like this echo "<script> alert( 'Authorization successful. Hello ' + '$me')</script>"; and like this echo "<script> window.location.replace('$url'); </script>"; how do I esc them? thank you

8
  • best practice is generally never to use alert, but that's not WP best practice that's general javascript. What are you trying to do that requires the use of alert? And is alert really relevant to the question? It sounds like you have the generic case of "how do I safely expose a value in PHP to some javascript?"
    – Tom J Nowell
    CommentedJun 20, 2024 at 13:59
  • this might also be a helpful read on the subject: docs.wpvip.com/security/javascript-security-recommendations
    – Tom J Nowell
    CommentedJun 20, 2024 at 14:06
  • I guess the alert isn't really the important line there. I just want an easy way of letting the user now that he was successful. But i could do without it or come up with another way. what i really want is the window.location.replace. I assume it'll be the same solution for both of them. although I guess I should have made the title clearer
    – Eitan
    CommentedJun 20, 2024 at 14:32
  • 1
    the answer to that depends on things you haven't shared, escaping is all about the context and the use case. The plugin checker is only doing a basic check and doesn't understand your code, it just sees you doing stuff like this: "string text" + mystery_variable and flagging it. Can you expand your code more? It's still unclear if we're talking about javascript in a javascript file, or javascript in a PHP file. Context is super important here, it's impossible to escape correctly without it, there is no such thing as a1 size fits all function that escapes a variable.
    – Tom J Nowell
    CommentedJun 20, 2024 at 14:51
  • 1
    I've written an answer, but I suspect in the name of making it simple and generic you've stripped away all the useful parts of the question and oversimplified things
    – Tom J Nowell
    CommentedJun 20, 2024 at 15:07

1 Answer 1

0

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.

    Start asking to get answers

    Find the answer to your question by asking.

    Ask question

    Explore related questions

    See similar questions with these tags.