1. Advertising
    y u no do it?

    Advertising (learn more)

    Advertise virtually anything here, with CPM banner ads, CPM email ads and CPC contextual links. You can target relevant areas of the site and show ads based on geographical location of the user if you wish.

    Starts at just $1 per CPM or $0.10 per CPC.

form protection

Discussion in 'PHP' started by roice, Oct 7, 2010.

  1. #1
    Hello
    I create PHP form where my users can post ads.
    I know that it can constitute to break-in and that is way we are using: "htmlspecialchars()" and "mysql_real_escape_string()" and "stripslashes()". The problem is that I don't know where to use ach one of them

    if the input is "name" (<input type='text' name='name' />), so how should the POST be?
    like this:
    $name = htmlspecialchars($_POST['name']);
    or like this:
    $name = mysql_real_escape_string($_POST['name']);
    or mabe like this:
    $name = Trim(stripslashes($_POST['name'])(;
    ?

    What about the print to the screen - the stage where I get the data from the SQL:
    $query = mysql_query("SELECT * FROM `sells` ");
    $index = mysql_fetch_array($query);
    $name= $index['name'];
    PHP:
    Should it be :
    $name= htmlspecialchars($index['name']);
    or like this:
    $name = mysql_real_escape_string($_POST['name']);
    or mabe like this:
    $name = stripslashes($_POST['name']);

    ?

    Thanks for advance!
     
    Last edited: Oct 7, 2010
    roice, Oct 7, 2010 IP
  2. maneetpuri

    maneetpuri Active Member

    Messages:
    152
    Likes Received:
    4
    Best Answers:
    0
    Trophy Points:
    58
    #2
    Hi,

    At the time of insert use this: -

    $name = addslashes($_POST[‘name’]);

    And at the time of echo use this

    Echo stripsalshes($name);

    Cheers,



    ~Maneet
     
    maneetpuri, Oct 7, 2010 IP
  3. JREAM

    JREAM Member

    Messages:
    160
    Likes Received:
    2
    Best Answers:
    0
    Trophy Points:
    30
    #3
    $item = $_POST['item'];
    $other = $_POST['item'];

    //escape the entire Query
    $sql = mysql_real_escape_string("INSERT INTO table ('item', 'other') VALUES($item, $other)");

    You don't need to escape strings when you are grabbing data FROM the database, only when you are inserting stuff into it.

    Or you could do:
    $_POST = array_map('mysql_real_escape_string', $_POST);

    and that'll do it automatically
     
    JREAM, Oct 7, 2010 IP
  4. roice

    roice Peon

    Messages:
    200
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #4
    Ok, so or
    $sql = mysql_real_escape_string("INSERT INTO table ('item', 'other') VALUES($item, $other)");

    or
    $_POST = array_map('mysql_real_escape_string', $_POST);

    ?

    I don't need to use stripslashes at all? something like this: $name = Trim(stripslashes($_POST['name'])); ?
     
    roice, Oct 11, 2010 IP
  5. roice

    roice Peon

    Messages:
    200
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #5

    is there any code for automatically "htmlspecialchars" ?
     
    roice, Oct 20, 2010 IP
  6. SamT

    SamT Peon

    Messages:
    43
    Likes Received:
    1
    Best Answers:
    0
    Trophy Points:
    0
    #6
    Do Not use addslashes or stripslashes for SQL, use the native mysql_real_escape_string() function.
    Do Not escape the entire query like JREAM suggested, that function is meant to escape a single value for safe use within a query, that means it will escape all quotes and other symbols used in SQL. If you escape the whole thing, you will not have a working query.

    First off, there are two main vulnerabilities you must consider: XSS and SQL Injection.
    XSS (cross site scripting) is a vulnerability where you allow someone to place JavaScript into your page. This is bad, because you can include an external javascript file and it will run on the client machine. The way to defend against this is use htmlspecialchars(), which change the special html characters for display. < becomes &lt;, > becomes &gt;, etc.

    SQL Injection (in it's simplest form) occurs where you can "break" and SQL query. The following code has an SQL injection vulnerability:

    $result = mysql_query("SELECT * FROM sometable WHERE username = '{$_REQUEST['username']}'")
    PHP:
    Why? Let's say you put in the name "John". That works just fine, nothing wrong there, but let's say you put in "John' UNION SELECT ... ". This is where you can inject your code. If you are using MSSQL, you can simply do this: "John'; UPDATE user_password = 'lolmyownpassword'". This can cause some real problems, the way to combat it is to make sure that all data before going in is safe. You need to use the mysql_real_escape_string() function to do this to be absolutely safe. Do not use addslashes and such.

    <?php
    $item1= htmlspecialchars($_POST['item1']); 
    
    // $item1 at this point can be safely outputted to the screen but is not safe for SQL yet
    
    $item = mysql_real_escape_string($item1); // Now it is safe for a MySQL query
    $sql = "UPDATE table SET junk = '$item1' WHERE something = 23";
    $result = mysql_query($sql);
    // ...
    
    
    PHP:
     
    SamT, Oct 20, 2010 IP
    mcfox likes this.
  7. roice

    roice Peon

    Messages:
    200
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #7
    Hiן SamT,
    Thank you for your full comment!

    I understand your explantion, but I didn't understand why not to escape the entire query like JREAM suggested:
    $_POST = array_map('mysql_real_escape_string', $_POST);
    PHP:
    this code will do escape for all the variable that come from forms and make them safe for the DB...

    ?
     
    roice, Oct 20, 2010 IP
  8. Thorlax402

    Thorlax402 Member

    Messages:
    194
    Likes Received:
    2
    Best Answers:
    5
    Trophy Points:
    40
    #8
    I think SamT thought that the function was being applied to the query itself. The array_map provided would work fine to apply the function to each posted element.
     
    Thorlax402, Oct 20, 2010 IP
  9. SamT

    SamT Peon

    Messages:
    43
    Likes Received:
    1
    Best Answers:
    0
    Trophy Points:
    0
    #9
    doing array_map through the entire $_POST array will make it safe for the database, but you will still have an XSS vulnerability if you do not htmlspecialchars() your input before displaying it to the browser.

    The reason why using mysql_real_escape_string() is not a good idea for escaping the whole query at once is simply because it was designed to only escape a single value. Take these examples:
    $sql = mysl_real_escape_string('SELECT * FROM sometable');
    PHP:
    In this case, it will work, though escaping a literal query is not required.

    However, look what happens when you do this:
    $username = $_POST['username'];
    $sql = mysl_real_escape_string("SELECT user_password FROM users WHERE username = '$username'");
    PHP:
    The query will be broken, if you posted "Admin" as your username to this script, and you echo'd "$sql", it will look like the following:
    "SELECT user_password FROM users WHERE username = \'Admin\'"
    Code (markup):
    Notice how the quotes surrounding Admin are now escaped. MySQL will then assume the text "Admin" is a column and try to match records where the username column is equal to the Admin column (which does not exist).

    The proper way to do this:
    $username = htmlspecialchars($_POST['username']);
    $username =  mysl_real_escape_string($username);
    $sql = "SELECT user_password FROM users WHERE username = '$username'";
    PHP:
    Which will create the query:
    "SELECT user_id FROM users WHERE username = 'Admin'"
    Code (markup):
    What I recommend:
    Escape all values with mysql_real_escape_string() right before entering the query, not as they are imputed. Someone can easily POST a bunch of arbitrary data to the page and cause high loads (DDoS). Escape only the inputs you are are using.

    For XSS protection, you should run htmlspecialchars() only on the variables you are using as they are being imputed. Instead of using $_POST, $_GET, and $_COOKIE in your code, simply do this:
    $username = htmlspecialchars($_POST['username']);
    This ensures that $username is safe for HTML output at all times and should be free of XSS.
     
    SamT, Oct 20, 2010 IP
  10. roice

    roice Peon

    Messages:
    200
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #10
    But if I input data into the DB, and using "mysql_real_escape_string", and in another page I pull those date from the DB and print it to the sreen, should I still need to use "htmlspecialchars"? after all I pull it from my DB whice all check and clean...
    ?

    I kind sure that you gonna say that hacker will try to insert JS into the DB (mysql_real_escape_string don't handle JS) and when I print it (in another page) the JS will do the problems...

    Am I right?


    One more thing, from all this explantion I didn't understand if the code that I wrote will do the job for the "DB input" side:
    $_POST = array_map('mysql_real_escape_string', $_POST);
    $_GET= array_map('mysql_real_escape_string', $_GET);
    
    PHP:
    I'm asking because I have lots of forms in my site and instead of writing
    $item1= mysql_real_escape_string($_POST['item1']); 
    PHP:
    lots of time I rather to write theabove code one time...
     
    Last edited: Oct 21, 2010
    roice, Oct 21, 2010 IP
  11. SamT

    SamT Peon

    Messages:
    43
    Likes Received:
    1
    Best Answers:
    0
    Trophy Points:
    0
    #11
    Use htmlspecialchars() only when you take user input, and it should be safe for output in HTML at that point.
    You cannot exploit a database with JS, if they get JS in your database and you display that value directly from the database, then that's an XSS attack. Just make sure that you clean it with htmlspecialchars() at the moment you take the input:
    $username = htmlspecialchars($_POST['username']);
    Any time you use $username after that, it will be safe for output in HTML.

    The code with array_walk will apply the mysql_real_escape_string() function on each value of $_POST and $_GET. I advise against this as it's a waste of resources. Only run mysql_real_escape_string() on values right before you place them in an SQL query.

    To review:
    - Input variables like this:
    $username = htmlspecialchars($_POST['username']);
    $email = htmlspecialchars($_POST['email']);
    // ...
    PHP:
    - Refer to them as the variable you set them to, DO NOT use $_POST or $_GET with anything after you cleaned them.
    - Use mysql_real_escape_string() right before they enter a query
    $username = mysql_real_escape_string($username);
    $sql = "SELECT * FROM users WHERE username = '$username'";
    // ...
    PHP:
    Following this procedure will ensure several things:
    - You will have no possibility of SQL injections
    - XSS attacks would be extremely unlikely (htmlspecialchars has been known to have bugs)
    - All values can be safely echo'd to the screen upon input
     
    SamT, Oct 21, 2010 IP
  12. roice

    roice Peon

    Messages:
    200
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #12
    OK, thank

    Sometimes I put hyper link with paraneters, such as: <a href='index.php?page=1'>text</a>
    when I do $page = $_GET['page'] do I still need to use "mysql_real_escape_string()" before I'm pulling data from the DB?
     
    roice, Oct 22, 2010 IP
  13. AnoxiA

    AnoxiA Peon

    Messages:
    27
    Likes Received:
    1
    Best Answers:
    0
    Trophy Points:
    0
    #13
    wow mate, mysql_real_escape_string is fine, but it will protect you just aginst SQL Injection, you should use also strip_tags() for XSS and such.
    BTW
    strip_tags works better then htmlspecialchars.
     
    AnoxiA, Oct 22, 2010 IP
  14. roice

    roice Peon

    Messages:
    200
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #14
    Better?
    so should I use both of them?
     
    roice, Oct 22, 2010 IP
  15. SamT

    SamT Peon

    Messages:
    43
    Likes Received:
    1
    Best Answers:
    0
    Trophy Points:
    0
    #15
    If you are expecting it to be an integer, you can simply cast it as int, and it will be safe for the database:
    $page = (int) $_GET['page']; // This is safe for DB and output to HTML
    Code (markup):
    strip_tags() is good if you are parsing the value between two tags, htmlspecialchars() effectively clean the string for display within the template and therefore will suit your needs in this situation.
     
    SamT, Oct 22, 2010 IP
  16. roice

    roice Peon

    Messages:
    200
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #16
    Do you know if the code:
    $_GET= array_map('mysql_real_escape_string', $_GET);
    will work with "htmlspecialchars"
    ?
    for example:
    $_GET= array_map('htmlspecialchars', $_GET);
    $_POST= array_map('htmlspecialchars', $_POST);
    PHP:
     
    roice, Oct 23, 2010 IP
  17. SamT

    SamT Peon

    Messages:
    43
    Likes Received:
    1
    Best Answers:
    0
    Trophy Points:
    0
    #17
    Sure, that'll work, but you're doing a lot more processing than you need to.
     
    SamT, Oct 23, 2010 IP
  18. scriptinstaller

    scriptinstaller Peon

    Messages:
    109
    Likes Received:
    1
    Best Answers:
    0
    Trophy Points:
    0
    #18
    egads, so much confusion here

    #1
    as soon as you create a variable for a database query, you can use a mysql_real_escape_string function

    if you are using stripslashes() at all, you are doing it WRONG

    #2 never assume info is safe (pulled from db so its ok) I seen a few people say you dont have to worry about it here.. Wrong, never assume..

    #3 sanitize all input immediately after receiving get/post data

    #4 any returned echo/print to web use htmlspecialchars($output); // if you know you dont want html etc, strip_tags() it too

    make sure magic quotes is disabled, most problems also originate from escaping strings twice+

    #5 just another note, if slashes are in your DATABSE, you are doing it WRONG

    .... but even better yet
    you need to start getting into mysqli, etc to avoid the hack attacks
     
    scriptinstaller, Oct 23, 2010 IP
  19. roice

    roice Peon

    Messages:
    200
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #19
    Thanks for you advaice,
    About num4 - if I don't want HTML, can I use only strip_tags() (without htmlspecialchars) ?

    About the slashes - well, I don't think users will input slashes in their texts, so I won't have slashes in my DB. should I do anything specail?
     
    roice, Oct 24, 2010 IP
  20. roice

    roice Peon

    Messages:
    200
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #20
    Do you thing that maybe this code will be better:

    foreach ($_GET as $x => $i)
    {
    $_GET[$x] = @htmlspecialchars($_GET[$x], ENT_QUOTES);
    }
    
    foreach ($_POST as $x => $i)
    {
    $_POST [$x] = @htmlspecialchars($_POST [$x], ENT_QUOTES);
    }
    
    foreach ($_COOKIE as $x => $i)
    {
    $_COOKIE[$x] = @htmlspecialchars($_COOKIE[$x], ENT_QUOTES);
    }
    
    
    foreach ($_GET as $x => $i)
    {
    $_GET[$x] = @mysql_real_escape_string($_GET[$x], ENT_QUOTES);
    }
    
    foreach ($_POST as $x => $i)
    {
    $_POST [$x] = @mysql_real_escape_string($_POST [$x], ENT_QUOTES);
    }
    
    foreach ($_COOKIE as $x => $i)
    {
    $_COOKIE[$x] = @mysql_real_escape_string($_COOKIE[$x], ENT_QUOTES);
    }
    PHP:
    Than the code I wrote above
    ?
    ?
     
    roice, Oct 24, 2010 IP