SQL Injection, Quotes and PHP

荒凉一梦 提交于 2019-12-10 06:37:06

问题


I'm quite confused now and would like to know, if you could clear things up for me.

After the lateste Anon/Lulsec attacks, i was questioning my php/mysql security.

So, i thought, how could I protect both, PHP and Mysql.

Question: Could anyone explain me, what's best practice to handle PHP and Mysql when it comes to quotes?

  • Especially in forms, I would need some kind of htmlspecialchars in order to protect the html, correct?
  • Can PHP be exploitet at all with a form? Is there any kind of protection needed?
  • Should I use real_escape_string just before a query? Would it be wrong/bad to use it already within PHP (see sanitize_post function)?

Currently i'm using the following function. The function "sanitizes" all $_POST and $_GET variables. Is this "safe"?

function sanitize_post($array) {
    global $db;
    if(is_array($array)) {
        foreach($array as $key=>$value) {
            if(is_array($array[$key])) {
                $array[$key] = sanitize_post($array[$key]);
            } elseif(is_string($array[$key])) {
                $array[$key] = $db->real_escape_string(strtr(stripslashes(trim($array[$key])), array("'" => '', '"' => '')));
            }
        }            
    } elseif(is_string($array)) {
        $array = $db->real_escape_string(strtr(stripslashes(trim($array)), array("'" => '', '"' => '')));
    }
    return $array;
}

I'm using PHP 5.3.5 with Mysql 5.1.54.

Thanks.


回答1:


There is nothing like "universal sanitization". Let's call it just quoting, because that's what its all about.

When quoting, you always quote text for some particular output, like:

  1. string value for mysql query
  2. like expression for mysql query
  3. html code
  4. json
  5. mysql regular expression
  6. php regular expression

For each case, you need different quoting, because each usage is present within different syntax context. This also implies that the quoting shouldn't be made at the input into PHP, but at the particular output! Which is the reason why features like magic_quotes_gpc are broken (always assure it is switched off!!!).

So, what methods would one use for quoting in these particular cases? (Feel free to correct me, there might be more modern methods, but these are working for me)

  1. mysql_real_escape_string($str)
  2. mysql_real_escape_string(addcslashes($str, "%_"))
  3. htmlspecialchars($str)
  4. json_encode() - only for utf8! I use my function for iso-8859-2
  5. mysql_real_escape_string(addcslashes($str, '^.[]$()|*+?{}')) - you cannot use preg_quote in this case because backslash would be escaped two times!
  6. preg_quote()



回答2:


mysql_real_escape_string deserves your attention.

However direct queries are a quagmire and no longer considered safe practice. You should read up on PDO prepared statements and binding parameters which has a side benefit of quoting, escaping, etc. built-in.




回答3:


BEST practice is always to use prepared statements. This makes SQL injection impossible. This is done with either PDO or mysqli. Forget about all the mysql_* functions. They are old and obsolete.




回答4:


Question: Could anyone explain me, what's best practice to handle PHP and Mysql when it comes to quotes?

That's easy: Use prepared statements, e. g. with PDO::prepare or mysqli_prepare.




回答5:


Don't waste the effort using mysql_real_escape_string() or anything like that. Just use prepared statements with PDO and SQL injection is impossible.




回答6:


I usually use the PHP functions stripslashes and strip_tags on the variables as they come in via $_POST (or $_GET, depending on what you use) and mysql_real_escape_string during the query. (I'm not sure if this is "right" but it's worked for me so far.) You can also use PHP's built in validate filters to check things like email addresses, url's, data types, etc. PDO is supposedly decent at preventing SQL injection but I haven't had any experience with it yet.




回答7:


The basic workflow should be

$data = $_POST['somefield which will go into the database'];

... do data validation ...

if (everything ok) {
    $escaped_data = escape_function($data);
    $sql = " ... query here with $escaped_data ... ";
    do_query($sql);
}

Basically, data that's been escaped for database insertion should ONLY be used for database insertion. There's no point in pre-processing everything and overwriting all data with db-escaped values, when only 2 or 3 of 50(say) values actually go anywhere near the db.

Ditto for htmlspecialchars. Don't send data through htmlspecialchars unless it's headed for an HTML-type display.

Don't store data in the DB formatted for one particular purpose, because if you ever need the data in a different form for some other purpose, you have to undo the escaping. Always store raw/unformatted data in the db. And note: the escaping done with mysql_real_escape_string() and company does not actually get stored in the db. It's there only to make sure the data gets into the database SAFELY. What's actually stored in the db is the raw unescaped/unquoted data. Once it's in the database, it's "safe".

e.g. consider the escaping functions as handcuffs on a prisoner being transferred. While the prisoner is inside either jail, cuffs are not needed.



来源:https://stackoverflow.com/questions/7030428/sql-injection-quotes-and-php

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!