php - how to make ajax comment system secure

324

I am using comment system like this:(i have simplified code for this question)

 <?php
        $status_ui = '<textarea id="box"></textarea>';
        $status_ui .= '<button id="status_button" onclick="postComment(\'box\')">Post</button>';
    ?>
    <html>
    <head>
        <script type="text/javascript">
        function postComment(box){
            var data = document.getElementById(box).value;
            data = data.replace(/[^a-zA-Z0-9,.?! ;:'"]+/, '');  
            var hr = new XMLHttpRequest();
            hr.open("POST", "comment_system.php", true);
            hr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            hr.onreadystatechange = function() {
                if(hr.readyState == 4 && hr.status == 200) {
                    var html_output = "";
                        current_html = document.getElementById("comment_list").innerHTML;                   
                        html_output +=  '<div class="comment">';
                        html_output +=      data;
                        html_output +=  '</div>';
                        document.getElementById("comment_list").innerHTML = html_output + current_html;
                    }
                    results_box.innerHTML = html_output;
                }
            }
            hr.send("comment="+data);
        </script>
    </head>
    <body>
        <div id="container">
            <?php echo $status_ui; ?>        
            <div id="comment_list"></div>
        </div>
    </body>
    </html>

Users can enter only a-zA-Z0-9,.?! ;:'" and everything works super cool.

In comment_system.php, I am performing all kinds of checks, regex, in order to store my data safely to DB. The question is: how to output the user comment securely to the comment_list div to be XSS proof?

I am using string.replace,and I am aware that it can be bypassed by the bad user.

897

Answer

Solution:

                    html_output +=  '<div class="comment">';
                    html_output +=      data;
                    html_output +=  '</div>';

This is HTML injection, resulting in a client-side cross-site-scripting (DOM-XSS) vulnerability.

To stop active HTML content being included in the comment div, either:

  • escape HTML-special characters in the data (eg< to&lt;)
  • (better) use DOM methods to set the text in the div element instead of trying to create markup

document.getElementById("comment_list").innerHTML = html_output + current_html;

This is a bad idea. Every time you call this you are serialising the entire contents of the comment list to a new HTML markup string, adding to the string, destroying all the elements in the comment list, and parsing new elements from the markup. This is slow and prone to reserialization errors which also can lead to DOM-XSS (IE has trouble with the backquote character - readinginnerHTML doesn't necessarily give you a string that is safe to re-assign toinnerHTML).

Again, avoid this by creating your content with DOM methods:

var comment = document.createElement('div');
comment.appendChild(document.createTextNode(data));
var list = document.getElementById('comment_list');
list.insertBefore(comment, list.firstChild);

(And similarly for the results box.) Now it doesn't matter what funny characters might have been in the user input, you will always display correctly. Consequently you can allow users to type a less-then sign without mangling their comment.

In comment_system.php, I am performing all kinds of checks, regex, in order to store my data safely to DB.

Input filtering has its place but it is not the answer to SQL injection. You should be using query parameterisation (with mysqli or PDO) to get data into the database and not creating queries with data in them. Then, again, any input is safe and you can allow the user to type an apostrophe without mangling their comment.

People are also looking for solutions to the problem: php - get text after some symbol in mysql

Source

Didn't find the answer?

Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.

Ask a Question

Write quick answer

Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.

Similar questions

Find the answer in similar questions on our website.