Page 3 of 3 First 123
  • Jump to page:
    #31
  1. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    311
    Rep Power
    8
    in point 5, don't I still have to require the file in order to access the "htmlescape" function?
  2. #32
  3. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,911
    Rep Power
    1045
    You need to include it in every script that uses it.
  4. #33
  5. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    311
    Rep Power
    8
    hi,

    I saw this at point 5:
    PHP Code:
    html_escape($raw_input
    Does this have the same properties as htmlentities? If yes, what is better? What should I use?
  6. #34
  7. No Profile Picture
    Lost in code
    Devshed Supreme Being (6500+ posts)

    Join Date
    Dec 2004
    Posts
    8,298
    Rep Power
    7170
    html_escape is not a built-in PHP function, look back at point 2 to see the definition of the function. As far as preventing XSS goes, it serves the same purpose as htmlentities.
    PHP FAQ

    Originally Posted by Spad
    Ah USB, the only rectangular connector where you have to make 3 attempts before you get it the right way around
  8. #35
  9. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,911
    Rep Power
    1045
    html_escape() is a wrapper for the htmlspecialchars() function including all necessary arguments.

    htmlentities() is a bad choice, because it converts all characters that happen to have a HTML entity representation. That's not what we want. We only want to convert the dangerous characters. And that's what htmlspecialchars() does.

    Both htmlspecialchars() and htmlentities() need to be "configured". You have to pass several flags and specify the character encoding (which many people forget). To avoid repeating this for every single function call, I've wrapped the function in a simplefied escaping function.
  10. #36
  11. A Change of Season
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Mar 2004
    Location
    Nobbies beach, Gold Coast. It's beautiful.
    Posts
    2,568
    Rep Power
    171
    Hi;

    This might be very naive question but I need to ask you. I always use bind with PDO but I have never gone into the details of "how it can really be harmful". For example:
    Code:
    SELECT
        entry_id
        , title
        , entry_text
    FROM
        blog_entries
    WHERE
        category = ''
    UNION
    SELECT
        user_id
        , email_address
        , password_hash
    FROM
        users
    -- '
    To start with
    1 - The UNION part works only if the attacker knows the name of the columns, right? I usually name my columns like database_column, ie: my_star_net_members_t. I wonder how easy it would be to guess the column names.
    2 - Let's say the results have been retrieved. How can the results be printed on screen? No matter what columns you try to retrieve, you can't change the php code to display those columns (well, unless you load files to the server).
    PHP Code:
    $results DB::Load()->Execute($sql,$args)->returnArray(); // Somethig like this
    foreach($results as $val=>$row)
         {
                   
    //This shows ONLY the columns that original code in the server has (attacker cannot change this code).
                   
    echo $row['id'];
                   echo 
    $row['email'];
                   
    //How does the attacker add echo $row['phone'];
         

    3 - I see in your example you retrieve hashed password! What is the point of accessign hashed password? Even if attacker can access the password, if it is hashed properly it is usless, right?



    I can think of a few situations where you can drop the database or truncate tables which I find hard to make an example of. Would you please add some truncate or drop part to this simple sql?
    PHP Code:
    $sql "SELECT id, email, name FROM members WHERE email = '".$_POST['email']."'"
    And
    PHP Code:
    $sql "SELECT id, email, name FROM members";
    //Maybe send something with GET? 
    Thank you.
    Last edited by zxcvbnm; July 13th, 2013 at 06:18 PM.
  12. #37
  13. No Profile Picture
    Lost in code
    Devshed Supreme Being (6500+ posts)

    Join Date
    Dec 2004
    Posts
    8,298
    Rep Power
    7170
    I wonder how easy it would be to guess the column names.
    They wouldn't have to guess; if they're able to inject a union into your query they can look up the column names using a query.

    Let's say the results have been retrieved. How can the results be printed on screen?
    You can alias (rename) columns in a select query. All they have to do is rename the column they want to see so that it has the same name as one you print.

    I can think of a few situations where you can drop the database or truncate tables which I find hard to make an example of. Would you please add some truncate or drop part to this simple sql?
    Injecting a drop or truncate statement virtually always involves chaining a second query to the first, so the end result looks something like:
    "SELECT x FROM y WHERE z; DROP TABLE x;"
    PHP FAQ

    Originally Posted by Spad
    Ah USB, the only rectangular connector where you have to make 3 attempts before you get it the right way around
  14. #38
  15. --
    Devshed Expert (3500 - 3999 posts)

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

    Originally Posted by zxcvbnm
    This might be very naive question but I need to ask you.
    This isn't naive at all. Understanding why SQL injections are dangerous and why you need protection against them is a good thing and much better than just following rules.



    Originally Posted by zxcvbnm
    1 - The UNION part works only if the attacker knows the name of the columns, right? I usually name my columns like database_column, ie: my_star_net_members_t. I wonder how easy it would be to guess the column names.
    It's easy. Either the attacker tries to figure it out by collecting background information, or they try to read from the system tables (which contain all column names), or they try to get an SQL errors message containing the query, or they simply find out the name by brute force (see below).

    Unusal column names might slow down an attack a little bit, but they're no serious security feature. See security through obscurity.



    Originally Posted by zxcvbnm
    2 - Let's say the results have been retrieved. How can the results be printed on screen? No matter what columns you try to retrieve, you can't change the php code to display those columns
    That's why I used a UNION in the example above: It simply appends the stolen data to the result set of the original query, keeping all column names. So the PHP code would return a long list of blog entries mixed with the stolen user credentials.

    But there are indeed cases when the attacker cannot simply see the data on the screen. Then they have to use more sophisticated methods like measuring time differences or generating errors to get indirect information.

    As a naive example: Let's say you wanna steal the email address of some user, but the PHP code doesn't output the result set. Then you might inject something like this:

    sql Code:
    ... CASE WHEN LEFT(email_address, 1) = 'a' THEN SLEEP(2) ELSE 0 END ...

    If the email_address starts with an "a", the system will wait for 2 seconds before returning the result. So by measuring the response time, you can find out all characters one by one. If it's not an "a", you try a "b" and so on.

    SQL injections can be much more sophisticated than just SELECT * from secret_data. And since there are free tools which automatically try those kinds of attacks, anybody can do them. It doesn't take any special knowledge.



    Originally Posted by zxcvbnm
    3 - I see in your example you retrieve hashed password! What is the point of accessign hashed password? Even if attacker can access the password, if it is hashed properly it is usless, right?
    No. If the password itself is weak (which is often the case), it can still be cracked easily.

    Hashing does not make the passwords immune to attacks! If your hashes get exposed, that's a disaster, regardless of how strong the algorithm is. A strong algorithm does make the attack much harder and buys you some time, but you still need to protect the hashes under all circumstances.

    It's also a matter of setting up multiple layers of protection. Strong password hashes are a key element of security, but they shouldn't be the only security. Because if it turns out that they're not quite as strong as you thought, you're screwed. On the other hand, if there are multiple security layers, a failure on one layer can still be caught on the next layer. That's why any serious application has at least three levels of protection:

    • The application itself uses prepared statements, escaping etc.
    • The database is protected by limiting the privileges of the role used by the application
    • The operating system is protected by limiting the privileges of the database system, the webserver etc.




    Originally Posted by zxcvbnm
    I can think of a few situations where you can drop the database or truncate tables which I find hard to make an example of. Would you please add some truncate or drop part to this simple sql?
    PHP Code:
    $sql "SELECT id, email, name FROM members"
    It's not possible. Dropping or truncating a table requires a separate statement, it cannot be combined with a SELECT statement.

    And an application letting users drop tables is so badly broken that the SQLi vulnerability would be kind of the least problem.
  16. #39
  17. A Change of Season
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Mar 2004
    Location
    Nobbies beach, Gold Coast. It's beautiful.
    Posts
    2,568
    Rep Power
    171
    PHP Code:
    function html_escape($raw_input) {
        return 
    htmlspecialchars($raw_inputENT_QUOTES ENT_HTML401'UTF-8');     // important! don't forget to specify ENT_QUOTES and the correct encoding

    Had to remove the ENT_HTML401 because of the notice <br /><b>Notice</b>: Use of undefined constant ENT_HTML401 - assumed 'ENT_HTML401'

    I assume its because of PHP Version 5.3.1

    Comments on this post

    • Jacques1 agrees : Thanks for pointing this out.
  18. #40
  19. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,911
    Rep Power
    1045
    Originally Posted by English Breakfast Tea
    I assume its because of PHP Version 5.3.1
    Interesting ...

    Yeah, I wasn't aware that it was only added in PHP 5.4, so I think I'll stop recommending it.
  20. #41
  21. A Change of Season
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Mar 2004
    Location
    Nobbies beach, Gold Coast. It's beautiful.
    Posts
    2,568
    Rep Power
    171
    Jaques1;

    A few things:

    1 - Do you consider this as a proper resource?


    2- What do you think about this:
    PHP Code:
    define("MAX_LENGTH"6);
     
    function 
    generateHashWithSalt($password) {
        
    $intermediateSalt md5(uniqid(rand(), true));
        
    $salt substr($intermediateSalt0MAX_LENGTH);
        return 
    hash("sha256"$password $salt);

    3- have to work it out but what about something like this:

    PHP Code:
    $hashed_password crypt('mypassword'); // let the salt be automatically generated

    /* You should pass the entire results of crypt() as the salt for comparing a
       password, to avoid problems when different hashing algorithms are used. (As
       it says above, standard DES-based password hashing uses a 2-character salt,
       but MD5-based hashing uses 12.) */
    if (crypt($user_input$hashed_password) == $hashed_password) {
       echo 
    "Password verified!";

    Last edited by English Breakfast Tea; September 4th, 2013 at 08:11 PM.
  22. #42
  23. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,911
    Rep Power
    1045
    Originally Posted by English Breakfast Tea
    Do you consider this as a proper resource?
    No, because this is a crypto amateur (which we all are) dabbling in cryptography and talking about things he doesn't understand.

    The problem of generating secure hashes in PHP has been solved already:

    • If you have PHP 5.5, you can use the new password API
    • If you don't have PHP 5.5 yet but at least 5.3.7, you can use the password_compat library, which emulates the new password API.
    • If you don't even have 5.3.7, you need to upgrade now, because a) you're running abandoned software and b) crypt() is broken before 5.3.7

    Now, we can keep trying to come up with our own implementations and outsmart the people who wrote those libraries. Maybe some day we'll actually find some genius improvement, and then we'll all be rich and famous.

    Unfortunately, it doesn't work like this in reality. Many, many hobby cryptographers have tried to write their own crypto implementation, and all of them have failed. Some got it all wrong, because they didn't even understand the concept. Some just made a tiny mistake somewhere. It doesn't matter. In the end, broken security usually means no security -- or even "less than no security", because people rely on being secure when they aren't.

    What does that tell us? We're programmers, not cryptographers. We should keep our hands off of any custom crypto implementation and leave that to the experts.

    I'm sure that Sandeep is a good programmer. The code is clean and up to date -- which is very refreshing. But he clearly isn't a cryptographer:

    • uniqid() and rand() and variations thereof are know to produce weak random numbers. Anthony Ferrara, the author of the password_compat library, specifically advises against using those functions to generate the salt.
    • The larger the hash, the better, because it's less prone to collisions? That's plain nonsense. It the algorithm itself is bad, it doesn't matter how many bits it produces. Collisions aren't even relevant for password hashing, because we want to find a string yielding a specific hash, not two arbitrary string with the same hash.
    • We mustn't iterate hashing, because this increases the risk of collisions? Wow, we better tell the cryptographers around the world that they're all wrong, because all modern password hash functions are based on iterative hashing. Our problem is speed, not collisions.
    • The tutorial suggests that bcrypt and SHA-2 are somehow similarly secure. This is very wrong. SHA-2 isn't even remotely suitable for password hashing (no matter how big the output), because it has no protection whatsoever against brute force attacks.
    • ...

    I'm not writing this critique so that you can look for some better tutorial somewhere else on the Internet. I'm trying to tell you that the whole idea of laymen playing with cryptography is bad.

    Use the new password API or the password_compat library. Nothing else.



    Originally Posted by English Breakfast Tea
    2- What do you think about this: [...]
    It's nonsense. It's some home-made scheme combining a very weak algorithm with a weak salt in an arbitrary manner.



    Originally Posted by English Breakfast Tea
    3- have to work it out but what about something like this: [...]
    Noooo ...

    When you use crypt() like that, you can't even tell which algorithm you get. Depending on the operating system, you either get some DES stuff or md5crypt, which are both much, much weaker than the libraries I suggested above.

    Again: Hands off of low-level cryptography. This is exactly why.

    You accept that certain things should be done by professionals, right? When you have a serious illness, you most probably go to an actual hospital and have it treated by actual doctors. You wouldn't rely on some self-proclaimed witch doctor on the Internet babbling about some magical cure.

    Well, cryptography is just like that. You want established libraries by actual experts, not some home-made stuff from a random guy on the Internet.
    Last edited by Jacques1; September 4th, 2013 at 08:39 PM.
  24. #43
  25. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    311
    Rep Power
    8
    Hi,

    I'm using the html_escape and when I got a value in the database like (with quotes):

    "test"

    And I display it with the function, I get:

    &quot;test&quot;

    When using single quotes I get:

    & #039;test& #039;

    (without spaces, the forum changed it to 'test') And of course this isn't nice to see. How do I get the quotes back?

    I'm using ISO-8859-1 and have this also in the function instead of UTF-8.


    EDIT: I was stupid again, I had some old code that made it escape twice... I removed it and it works again.
    Last edited by derplumo; March 6th, 2014 at 04:17 PM.
  26. #44
  27. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2014
    Posts
    44
    Rep Power
    1
    Great six pack!
    I've been learning many things the hard and wrong way. Now I am on the right track going forward...
    Thanks for sharing.
  28. #45
  29. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2014
    Location
    Debrecen, Hungary
    Posts
    1
    Rep Power
    0
    I'm so glad that I found this forum. I heard it from someone that learning bad programming techniques is the worst so I searched until I found this. Thank you!

    Comments on this post

    • Jacques1 agrees : Cool. :-)
Page 3 of 3 First 123
  • Jump to page:

IMN logo majestic logo threadwatch logo seochat tools logo