Skip to content
Advertisement

How to prevent PHP echo from ending a JS string?

I have this code:

<!DOCTYPE html>
<html>
    <head>
        <title>Sign up page</title>
        <meta charset="UTF-8"/>
    </head>
    <body>
        <h1>Sign up page</h1>
        <form action="test.php" method="post">
            <input placeholder="Enter your username" name="username"/><br/>
            <input type="password" placeholder="Enter your password" style="margin-bottom:5px" name="password"/><br/>
            <button type="submit" name="submit">Sign up</button>
        </form>
        <?php
        if(isset($_POST["username"],$_POST["password"],$_POST["submit"])){
            if(mb_strlen($_POST["username"])<8){
            ?>
            <script>
                alert("Your username must be at least 8 characters long.");
                var i=document.getElementsByTagName("input")[0];
                i.value="<?php echo $_POST['username']; ?>";
                i.focus();
            </script>
            <?php
            }else if(mb_strlen($_POST["password"])<8){
            ?>
            <script>
                alert("Your password must be at least 8 characters long.");
                var i=document.getElementsByTagName("input")[1];
                i.value="<?php echo $_POST['password']; ?>";
                i.focus();
            </script>
            <?php
            }else{
                echo "Successfully signed up!";
            }
        }
        ?>
    </body>
</html>

It works fine most of the time, but if you try entering ";f(); into the username field, you get an error in the console and no alert.

As is clearly visible, that is happening because when PHP receives the input, it echoes it in the JS string. "; ends the string and the statement, while f(); causes an error which prevents the input from focusing. This occurred under 8 characters, therefore causing it to fall under mb_strlen($_POST["username"])<8.

Usually I would just use htmlspecialchars, but if you try adding that, then if you put ";<!--, it comes out with &lt; instead of <. Some users may want < (or other &*; characters) in their username, and (if they weren’t developers) would be surprised what &lt; means.

So how do I prevent the JavaScript Injection from occurring while still keeping User Friendliness?

Advertisement

Answer

You should be using json_encode to output your values (and note you no longer need the enclosing "s):

i.value=<?php echo json_encode($_POST['username']); ?>;

This will ensure that quotes within the string are escaped and the entire value is treated by JavaScript as a string. For your example data, this will produce

"";f();"
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement