#1
  1. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Sep 2006
    Posts
    1,799
    Rep Power
    529

    Secure practices for saving, editing, and displaying data


    I am editing, displaying, and saving data using an Ajax application, and I want to make sure I am practicing safe practices. This is a PHP/JavaScript/MySQL/HTML question, but hopefully you agree it is more PHP. Let me explain.

    Initially, there are no <div>s on the page. The user clicks "Add New", and a dialog with a <textarea> and save/close buttons appears. The user enters some text and clicks save.

    The text within the <TEXTAREA> and any other supporting data is POSTed to the server via Ajax. The server does some business rule checks and stores the data in the database using PDO (thus I am not manually escaping). The server then echo's back JSON containing the PK of the new record, and maybe an array of errors (for other applications, I will typically just echo 1 or 0).

    The client receives the feedback. If there was an error, it is displayed as appropriate. If all is good, it escapes the text in the textarea clientside using something like escapeHtml (below), puts a DIV on the page with the escaped text inside it, and adds an edit and delete button next to it. An attribute data-id which is set equal to the received PK is also added to the DIV (off topic, but some might say I should use a hidden input, but I seem to lean the other way. Any opinions?)

    The user clicks the edit button, and data is retrieved from the server using GET along with the PK which was stored as the attr (and not from the client DIV since it might have been changed by someone else), and the dialog with the textarea is displayed.

    If the page is reloaded, the server queries the DB and extracts any existing records. The records are escaped using htmlspecialchars(), and the same HTML as described above is created directly by PHP.

    If I embed any strings (uch as arguments) to external commands, and call them with exec, I will use escapeshellcmd and escapeshellarg.

    Is it typically better to use htmlspecialchars() before entering the data into the database (and then use htmlspecialchars_decode() when displaying data in the TEXTAREA or INPUT), or using htmlspecialchars() everytime user data which is stored in the DB is written to the page?

    Do you recommend using something like http://htmlpurifier.org/?

    What else should I be doing?

    Thanks

    Code:
    function escapeHtml(unsafe) {
      return unsafe
          .replace(/&/g, "&amp;")
          .replace(/</g, "&lt;")
          .replace(/>/g, "&gt;")
          .replace(/"/g, "&quot;")
          .replace(/'/g, "'");
    }
    Last edited by NotionCommotion; November 30th, 2012 at 01:24 PM.
  2. #2
  3. JavaScript is not spelt java
    Devshed Novice (500 - 999 posts)

    Join Date
    Feb 2011
    Location
    Landan, England
    Posts
    743
    Rep Power
    165
    I'm not an expert.. but I trim the posted data and use htmlentities with the quotes option:

    PHP Code:
    $trimmed_post array_map('trim'$_POST);

    $html_title htmlentities($trimmed_post['bgTitle'], ENT_QUOTES); 
    The quotes otherwise cause me a problem (as I have an older version of PHP) and appear as \' when I re-insert content into HTML. If I recall correctly, stripcslashes is another way around this.

    But, of course, before inserting the data into a database it should be real-escaped (mysqli_real_escape_string) or use prepared statements - which you do already.

    Less effort is required when re-inserting the database content, as it is safe. But sometimes nl2br is required, depending on what HTML element it is inserted into:

    PHP Code:
    $rowh['blog'] = htmlentities($row['blog'], ENT_QUOTES);
    // I'm just wondering if I need the above line.. 
    // I haven't looked into this in a while
    $html_blog nl2br($rowh['blog']); 
    But, as I say, I'm not an expert and someone may correct me.

    Added: I would assume that decoding of htmlentities is not necesssary, as the browser will perform the decoding.
    Last edited by AndrewSW; November 30th, 2012 at 07:36 PM.
  4. #3
  5. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,911
    Rep Power
    1045
    Hi,

    do not escape strings with htmlentities() before you insert them in the string. This has several problems:
    • You lose the original data; if something goes wrong will the escaping, you'll have nothing but a big mess
    • Different escaping methods and options can easily make the data inconsistent
    • You bind the data to a specific purpose (HTML); if you need to use it in a different context, you have to revert the HTML escaping first
    • In your HTML, you completely rely on the data being escaped already, even though there's absolutely no guarantee for this (what if somebody has edited an entry or manually added it?)


    Put the original data into the database, and when you use it, escape it for this specific purpose.

    Comments on this post

    • E-Oreo agrees
    • NotionCommotion agrees : Very well said!
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Sep 2006
    Posts
    1,799
    Rep Power
    529
    Thanks Jacques1. After posting this, I came to the same conclusion of 3 out of 4 of yours, however, my wife forced me off the computer, and I was unable to edit my original post, so I am glad she did this as I would not have thought of manually changing data. Thank you Rochelle (my wife who is probably watching me as I type) and thank you Jacques1!

IMN logo majestic logo threadwatch logo seochat tools logo