2528 |
http://*.com/questions/60174/how-can-i-prevent-sql-injection-in-php If user input is inserted without modification into an SQL query, then the application becomes vulnerable toSQL injection, like in the following example:
That's because the user can input something like
What can be done to prevent this from happening? |
Use prepared statements and parameterized queries. These are SQL statements that are sent to and parsed by the database server separately from any parameters. This way it is impossible for an attacker to inject malicious SQL. You basically have two options to achieve this:
If you're connecting to a database other than MySQL, there is a driver-specific second option that you can refer to (e.g. Correctly setting up the connectionNote that when using
In the above example the error mode isn't strictly necessary, but it is advised to add it. This way the script will not stop with a What is mandatory however is the first Although you can set the ExplanationWhat happens is that the SQL statement you pass to The important thing here is that the parameter values are combined with the compiled statement, not an SQL string. SQL injection works by tricking the script into including malicious strings when it creates SQL to send to the database. So by sending the actual SQL separately from the parameters, you limit the risk of ending up with something you didn't intend. Any parameters you send when using a prepared statement will just be treated as strings (although the database engine may do some optimization so parameters may end up as numbers too, of course). In the example above, if the Another benefit with using prepared statements is that if you execute the same statement many times in the same session it will only be parsed and compiled once, giving you some speed gains. Oh, and since you asked about how to do it for an insert, here's an example (using PDO):
Can Prepared Statements Be Used For Dynamic Queries?While you can still use prepared statements for the query parameters, the structure of the dynamic query itself cannot be parametrized and certain query features cannot be parametrized. For these specific scenarios, the best thing to do is use a whitelist filter that restricts the possible values.
|
|||||||||||||||||||||
|
You've got two options - escaping the special characters in your We'll do the simpler string escaping one first.
See also, the details of the Warning:As of PHP 5.5.0 To use the parameterized query, you need to use MySQLi rather than the MySQL functions. To rewrite your example, we would need something like the following.
The key function you'll want to read up on there would be Also, as others have suggested, you may find it useful/easier to step up a layer of abstraction with something likePDO. Please note that the case you asked about is a fairly simple one, and that more complex cases may require more complex approaches. In particular:
|
||||
|
I'd recommend using PDO (PHP Data Objects) to run parameterized SQL queries. Not only does this protect against SQL injection, it also speeds up queries. And by using PDO rather than |
||||
|
Every answer here covers only part of the problem.
and prepared statements covers only 2 of them But sometimes we have to make our query even more dynamic, adding operators or identifiers as well. In general, such a protection approach is based on whitelisting. In this case every dynamic parameter should be hardcoded in your script and chosen from that set.
However, there is another way to secure identifiers - escaping. As long as you have an identifier quoted, you can escape backticks inside by doubling them. As a further step we can borrow a truly brilliant idea of using some placeholder (a proxy to represent the actual value in the query) from the prepared statements and invent a placeholder of another type - an identifier placeholder. So, to make long story short: it's a placeholder, not prepared statement can be considered as a silver bullet. So, a general recommendation may be phrased as Still there is an issue with SQL syntax keywords (such as UpdateAlthough there is a general agreement on the best practices regarding SQL injection protection, there arestill many bad practices as well. And some of them too deeply rooted in the minds of PHP users. For instance, on this very page there are (although invisible to most visitors)more than 80 deleted answers - all removed by the community due to bad quality or promoting bad and outdated practices. Worse yet, some of bad answers aren't deleted but rather prospering. For example, there are still(1) many(2) answers(3)suggesting(4)you(5) manual string escaping - an outdated approach that is proven to be insecure. Or there is a slightly better answer that suggests just another method of string formatting and even boasts it as ultimate panacea. While of course it is not. This method is no better than regular string formatting yet it keeps all its drawbacks: it is applicable to strings only and, as any other manual formatting, it's essentially optional, not obligatory measure, prone to human error of any sort. I think that all this because of one very old superstition, supported by such authorities likeOWASP or PHP manual, which proclaims equality between whatever "escaping" and protection from SQL injections. Despite of what PHP manual said for ages, And OWASP makes it even worse, stressing on escaping user input which is an utter nonsense: there should be no such words in the context of injection protection. Every variable is potentially dangerous - no matter of the source! Or, in other words - every variable have to be properly formatted to be put into query - no matter of the source again. It's destination that matters. The moment a developer starts to separate the sheep from the goats (thinking whether some particular variable "safe" or not) he does his first step to disaster. Not to mention that even the wording suggests bulk escaping at the entry point, resembling the very magic quotes feature - already despised, deprecated and removed. Which is leaving us no choice other than prepared statements. If you're still not convinced, here is a step-by step explanation I wrote, The Hitchhiker's Guide to SQL Injection protection, where I explained all these matters in detail, and even compiled a section entirely dedicated to bad practices and their disclosure. |
|||||||||
|
Use (
|
||||
|
As you can see, people suggest you to use prepared statements at the most. It's not wrong, but when your query is executedjust once per process, there would be a slightly performance penalty. I was facing this issue, but I think I solved it in very sophisticated way - the way hackers use to avoid using quotes. I used this in conjuction with emulated prepared statements. I use it to preventall kinds of possible SQL injection attacks. My approach:
So for example the query:
Will become:
or
Hex is the perfect escape. No way to inject. Difference between UNHEX function and 0x prefixThere was some discussion in comments, so I finally want to make it clear. These two approaches are very similar, but they are a little different in some ways: 0x prefix can only be used on data columns such as char, varchar, text, block, binary, etc. UNHEX() works on any column; you do not have to worry about the empty string. Hex methods are often used as attacksNote that this hex method is often used as an SQL injection attack where integers are just like strings and escaped just with For example, if you just do something like this:
an attack can inject you very easily. Consider the following injected code returned from your script:
and now just extract table structure:
And then just select whatever data ones want. Cool isn't it? But if the coder of injectable site would hex it, no injection would be possible because the query would look like this: |
|||||||||||||||||||||
|
Injection prevention - mysql_real_escape_string() PHP has a specially-made function to prevent these attacks. All you need to do is use the mouthful of a function,
NOTE: you must be connected to the database to use this function! // Connect to MySQL
You can find more details in MySQL - SQL Injection Prevention. |
|||||||||||||||||||||
|
You could do something basic like this:
This won't solve every problem, but it's a very good stepping stone. I left out obvious items such as checking the variable's existence, format (numbers, letters, etc.). |
|||||||||||||||||||||
|
Whatever you do end up using, make sure that you check your input hasn't already been mangled by |
|||||||||
|
Parameterized query AND input validation is the way to go. There is many scenarios under which SQL injection may occur, even though Those examples are vulnerable to SQL injection:
or
In both cases, you can't use Source:The Unexpected SQL Injection (When Escaping Is Not Enough) |
|||||||||
|
In my opinion, the best way to generally prevent SQL injection in your PHP application (or any web application, for that matter) is to think about your application's architecture. If the only way to protect against SQL injection is to remember to use a special method or function that does The Right Thing every time you talk to the database, you are doing it wrong. That way, it's just a matter of time until you forget to correctly format your query at some point in your code. Adopting the MVC pattern and a framework like CakePHP or CodeIgniter is probably the right way to go: Common tasks like creating secure database queries have been solved and centrally implemented in such frameworks. They help you to organize your web application in a sensible way and make you think more about loading and saving objects than about securely constructing single SQL queries. |
||||
|
There are many ways of preventing SQL injections and other SQL hacks. You can easily find it on the Internet (Google Search). Of coursePDO is one of the good solution. But I would like to suggest you some good links prevention from SQL Injection. What is SQL injection and how to prevent Microsoft explanation of SQL injection and prevention in PHP and some other like Preventing SQL injection with MySQL and PHP Now, why you do you need to prevent your query from SQL injection? I would like to let you know: Why do we try for preventing SQL injection with a short example below: Query for login authentication match:
Now, if someone (a hacker) puts
and password anything.... The query will be parsed in the system only upto:
The other part will be discarded. So, what will happen? A non-authorized user (hacker) will be able to login as admin without having his password. Now, he can do anything what admin/email person can do. See, it's very dangerous if SQL injection is not prevented. |
||||
|
I favor stored procedures (MySQL has had stored procedures support since 5.0) from a security point of view - the advantages are -
The disadvantages are -
|
||||
|
I think if someone wants to use PHP and MySQL or some other dataBase server:
Libraries examples: ---- PDO
--- MySQLi
P.S: PDO wins this battle with ease. With support for twelve different database drivers and named parameters, we can ignore the small performance loss, and get used to its API. From a security standpoint, both of them are safe as long as the developer uses them the way they are supposed to be used But while both PDO and MySQLi are quite fast, MySQLi performs insignificantly faster in benchmarks – ~2.5% for non-prepared statements, and ~6.5% for prepared ones. And please test every query to your database - it's a better way to prevent injection. |
||||
|
Type cast if possible your parameters. But it's only working on simple types like int, bool and float.
|
|||
|
If you want to take advantage of cache engines, like Redis or Memcached, maybe DALMP could be a choice. It uses pureMySQLi. Check this:DALMP Database Abstraction Layer for MySQL using PHP. Also you can 'prepare' your arguments before preparing your query so that you can build dynamic queries and at the end have a full prepared statements query.DALMP Database Abstraction Layer for MySQL using PHP. |
||||
|
For those unsure of how to use PDO (coming from the Basically, read it while you read the manual to see how to put the PDO functions to use in real life to make it simple to store and retrieve values in the formatyou want.
|
|||
|
Using this PHP function For example:
For more prevention you can add at the end ...
Finally you get:
|
||||
|
A few guidelines for escaping special characters in SQL statements. Don't use MySQL, this extension is deprecated, use MySQLi or PDO. MySQLi For manually escaping special characters in a string you can use the mysqli_real_escape_string function. The function will not work properly unless the correct character set is set withmysqli_set_charset. Example:
For automatic escaping of values with prepared statements, use mysqli_prepare, and mysqli_stmt_bind_param where types for the corresponding bind variables must be provided for an appropriate conversion: Example:
No matter if you use prepared statements or mysqli_real_escape_string, you always have to know the type of input data you're working with. So if you use a prepared statement, you must specify the types of the variables for mysqli_stmt_bind_param function. And use of mysqli_real_escape_string is for, as the name says, escaping special characters in a string, so it will not make integers safe. The purpose of this function is to prevent breaking the strings in SQL statements, and the damage to the database that it could cause. mysqli_real_escape_string is a useful function when used properly, especially when combined with sprintf. Example:
|
||||
|
I use three different ways to prevent my web application from being vulnerable to SQL injection.
I hope this will help you. Consider the following query:
mysql_real_escape_string() will not protect here. If you use single quotes (' ') around your variables inside your query is what protects you against this. Here is an solution below for this:
This question has some good answers about this. I suggest, using PDO is the best option. Edit:
An alternative to mysql_real_escape_string() is
Example:
|
||||
|
Regarding to many useful answers, I hope to add some values to this thread. SQL injection is type of attack that can be done through user inputs (Inputs that filled by user and then used inside queries), The SQL injection patterns are correct query syntax while we can call it: bad queries for bad reasons, we assume that there might be bad person that try to get secret information (by passing access control) that affect the three principles of security (Confidentiality, Integrity, Availability). Now, our point is to prevent security threats such as SQL injection attacks, the question asking (How to prevent SQL injection attack using PHP), be more realistic, data filtering or clearing input data is the case when using user-input data inside such query, using PHP or any other programming language is not the case, or as recommended by more people to use modern technology such as prepared statement or any other tools that currently supporting SQL injection prevention, consider that these tools not available anymore? how you secure your application? My approach against SQL injection is: clearing user-input data before sending it to database (before using it inside any query). Data filtering for (Converting unsafe data to safe data) Consider thatPDO and MySQLi not available, how can you secure your application? do you force me to use them? what about other languages other than PHP? I prefer to provide general ideas as it can be used for wider border not just for specific language.
see Principle of least privilege
Now, if you are an advanced user, start using these defense as you like, but, for beginners, if they can't quickly implement stored procedure and prepared statement, it's better to filter input data as much they can. Finally, let's consider that user sends this text below instead of entering his username:
This input can be checked early without any prepared statement and stored procedures, but to be on safe side, using them starts after user-data filtering and validation. Last point is detecting unexpected behavior which requires more effort and complexity, it's not recommended for normal web applications. Unexpected behavior in above user input is: SELECT, UNION, IF, SUBSTRING, BENCHMARK, SHA, root once these words detected, you can avoid the input. UPDATE1:A user commented that this post is useless, OK! Here is what OWASP.ORG provided:
As you may knew, claiming on any article should be supported by valid argument, at least one reference! Otherwise it's considered as attack and bad claim! Update2:From the PHP manual, PHP: Prepared Statements - Manual:
Update3:I created test cases for knowing how PDO and MySQLi sends the query to MySQL server when using prepared statement: PDO:
Query Log:
MySQLi:
Query Log:
It's clear that a prepared statement is also escaping the data, nothing else.As also mentioned in above statement Please see this question for more detail: PDO sends raw query to MySQL while Mysqli sends prepared query, both produce the same result References: |
||||
|
The simple alternative to this problem could be solved by granting appropriate permissions in the database itself. For example: if you are using mysql database. then enter into the database through terminal or the ui provided and just follow this command:
This will restrict the user to only get confined with the specified query's only. Remove the delete permission and so the data would never get deleted from the query fired from the php page. The second thing to do is to flush the privileges so that the mysql refreshes the permissions and updates.
more information about flush. To see the current privileges for the user fire the following query.
Learn more about GRANT. |
||||
|
A simple way would be to use a PHP framework like CodeIgniter or Laravel which have in-built features like filtering and active-record, so that you don't have to worry about these nuances. |
||||
|
Warning : the approach described in this answer only applies for very specific scenarios and isn't secure since SQL injection attacks do not only rely on being able to inject If the attackers are trying to hack with the form via PHP's
Because But you must be careful, that you must not rewrite a safe query from your site. The code above is giving you a tip, to rewrite or redirect(it depends on you) that hacking-specific dynamic query string into a page that will store the attacker'sIP address, or EVEN THEIR COOKIES, history, browser, or any other sensitive information, so you can deal with them later by banning their account or contacting authorities. |
||||
|
There are so many answers for PHP and MySQL, but here is code forPHP and Oracle for preventing SQL injection as well as regular use of oci8 drivers:
|
||||
|
Using PDO and MYSQLi is a good practice to prevent SQL injections, but if you really want to work with MySQL functions and queries, it would be better to use
There are more ability to prevent this: like identify - if the input is a string, number, char or array, there are so many inbuilt functions to detect this. Also it would be better to use these functions to check input data.
And it is so much better to use those functions to check input data with |
|||||||||||||||||
|
A good idea is to use an 'object-relational mapper' like Idiorm:
It not only saves you from SQL injections, but from syntax errors too! |
||||
|
I've written this little function several years ago:
This allows running statements in an one-liner C#-ish String.Format like:
It escapes considering the variable type. If you try to parameterize table, column names, it would fail as it puts every string in quotes which is invalid syntax. SECURITY UPDATE: The previous |
||||
|
protected by AVD Jun 6 '12 at 9:59
Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10reputation on this site.
Would you like to answer one of these unanswered questions instead?
Use prepared statements and parameterized queries. These are SQL statements that are sent to and parsed by the database server separately from any parameters. This way it is impossible for an attacker to inject malicious SQL. You basically have two options to achieve this:
If you're connecting to a database other than MySQL, there is a driver-specific second option that you can refer to (e.g. Correctly setting up the connectionNote that when using
In the above example the error mode isn't strictly necessary, but it is advised to add it. This way the script will not stop with a What is mandatory however is the first Although you can set the ExplanationWhat happens is that the SQL statement you pass to The important thing here is that the parameter values are combined with the compiled statement, not an SQL string. SQL injection works by tricking the script into including malicious strings when it creates SQL to send to the database. So by sending the actual SQL separately from the parameters, you limit the risk of ending up with something you didn't intend. Any parameters you send when using a prepared statement will just be treated as strings (although the database engine may do some optimization so parameters may end up as numbers too, of course). In the example above, if the Another benefit with using prepared statements is that if you execute the same statement many times in the same session it will only be parsed and compiled once, giving you some speed gains. Oh, and since you asked about how to do it for an insert, here's an example (using PDO):
Can Prepared Statements Be Used For Dynamic Queries?While you can still use prepared statements for the query parameters, the structure of the dynamic query itself cannot be parametrized and certain query features cannot be parametrized. For these specific scenarios, the best thing to do is use a whitelist filter that restricts the possible values.
|
|||||||||||||||||||||
|
You've got two options - escaping the special characters in your We'll do the simpler string escaping one first.
See also, the details of the Warning:As of PHP 5.5.0 To use the parameterized query, you need to use MySQLi rather than the MySQL functions. To rewrite your example, we would need something like the following.
The key function you'll want to read up on there would be Also, as others have suggested, you may find it useful/easier to step up a layer of abstraction with something likePDO. Please note that the case you asked about is a fairly simple one, and that more complex cases may require more complex approaches. In particular:
|
||||
|
I'd recommend using PDO (PHP Data Objects) to run parameterized SQL queries. Not only does this protect against SQL injection, it also speeds up queries. And by using PDO rather than |
||||
|
Every answer here covers only part of the problem.
and prepared statements covers only 2 of them But sometimes we have to make our query even more dynamic, adding operators or identifiers as well. In general, such a protection approach is based on whitelisting. In this case every dynamic parameter should be hardcoded in your script and chosen from that set.
However, there is another way to secure identifiers - escaping. As long as you have an identifier quoted, you can escape backticks inside by doubling them. As a further step we can borrow a truly brilliant idea of using some placeholder (a proxy to represent the actual value in the query) from the prepared statements and invent a placeholder of another type - an identifier placeholder. So, to make long story short: it's a placeholder, not prepared statement can be considered as a silver bullet. So, a general recommendation may be phrased as Still there is an issue with SQL syntax keywords (such as UpdateAlthough there is a general agreement on the best practices regarding SQL injection protection, there arestill many bad practices as well. And some of them too deeply rooted in the minds of PHP users. For instance, on this very page there are (although invisible to most visitors)more than 80 deleted answers - all removed by the community due to bad quality or promoting bad and outdated practices. Worse yet, some of bad answers aren't deleted but rather prospering. For example, there are still(1) many(2) answers(3)suggesting(4)you(5) manual string escaping - an outdated approach that is proven to be insecure. Or there is a slightly better answer that suggests just another method of string formatting and even boasts it as ultimate panacea. While of course it is not. This method is no better than regular string formatting yet it keeps all its drawbacks: it is applicable to strings only and, as any other manual formatting, it's essentially optional, not obligatory measure, prone to human error of any sort. I think that all this because of one very old superstition, supported by such authorities likeOWASP or PHP manual, which proclaims equality between whatever "escaping" and protection from SQL injections. Despite of what PHP manual said for ages, And OWASP makes it even worse, stressing on escaping user input which is an utter nonsense: there should be no such words in the context of injection protection. Every variable is potentially dangerous - no matter of the source! Or, in other words - every variable have to be properly formatted to be put into query - no matter of the source again. It's destination that matters. The moment a developer starts to separate the sheep from the goats (thinking whether some particular variable "safe" or not) he does his first step to disaster. Not to mention that even the wording suggests bulk escaping at the entry point, resembling the very magic quotes feature - already despised, deprecated and removed. Which is leaving us no choice other than prepared statements. If you're still not convinced, here is a step-by step explanation I wrote, The Hitchhiker's Guide to SQL Injection protection, where I explained all these matters in detail, and even compiled a section entirely dedicated to bad practices and their disclosure. |
|||||||||
|
Use (
|
||||
|
As you can see, people suggest you to use prepared statements at the most. It's not wrong, but when your query is executedjust once per process, there would be a slightly performance penalty. I was facing this issue, but I think I solved it in very sophisticated way - the way hackers use to avoid using quotes. I used this in conjuction with emulated prepared statements. I use it to preventall kinds of possible SQL injection attacks. My approach:
So for example the query:
Will become:
or
Hex is the perfect escape. No way to inject. Difference between UNHEX function and 0x prefixThere was some discussion in comments, so I finally want to make it clear. These two approaches are very similar, but they are a little different in some ways: 0x prefix can only be used on data columns such as char, varchar, text, block, binary, etc. UNHEX() works on any column; you do not have to worry about the empty string. Hex methods are often used as attacksNote that this hex method is often used as an SQL injection attack where integers are just like strings and escaped just with For example, if you just do something like this:
an attack can inject you very easily. Consider the following injected code returned from your script:
and now just extract table structure:
And then just select whatever data ones want. Cool isn't it? But if the coder of injectable site would hex it, no injection would be possible because the query would look like this: |
|||||||||||||||||||||
|
Injection prevention - mysql_real_escape_string() PHP has a specially-made function to prevent these attacks. All you need to do is use the mouthful of a function,
NOTE: you must be connected to the database to use this function! // Connect to MySQL
You can find more details in MySQL - SQL Injection Prevention. |
|||||||||||||||||||||
|
You could do something basic like this:
This won't solve every problem, but it's a very good stepping stone. I left out obvious items such as checking the variable's existence, format (numbers, letters, etc.). |
|||||||||||||||||||||
|
Whatever you do end up using, make sure that you check your input hasn't already been mangled by |
|||||||||
|
Parameterized query AND input validation is the way to go. There is many scenarios under which SQL injection may occur, even though Those examples are vulnerable to SQL injection:
or
In both cases, you can't use Source:The Unexpected SQL Injection (When Escaping Is Not Enough) |
|||||||||
|
In my opinion, the best way to generally prevent SQL injection in your PHP application (or any web application, for that matter) is to think about your application's architecture. If the only way to protect against SQL injection is to remember to use a special method or function that does The Right Thing every time you talk to the database, you are doing it wrong. That way, it's just a matter of time until you forget to correctly format your query at some point in your code. Adopting the MVC pattern and a framework like CakePHP or CodeIgniter is probably the right way to go: Common tasks like creating secure database queries have been solved and centrally implemented in such frameworks. They help you to organize your web application in a sensible way and make you think more about loading and saving objects than about securely constructing single SQL queries. |
||||
|
There are many ways of preventing SQL injections and other SQL hacks. You can easily find it on the Internet (Google Search). Of coursePDO is one of the good solution. But I would like to suggest you some good links prevention from SQL Injection. What is SQL injection and how to prevent Microsoft explanation of SQL injection and prevention in PHP and some other like Preventing SQL injection with MySQL and PHP Now, why you do you need to prevent your query from SQL injection? I would like to let you know: Why do we try for preventing SQL injection with a short example below: Query for login authentication match:
Now, if someone (a hacker) puts
and password anything.... The query will be parsed in the system only upto:
The other part will be discarded. So, what will happen? A non-authorized user (hacker) will be able to login as admin without having his password. Now, he can do anything what admin/email person can do. See, it's very dangerous if SQL injection is not prevented. |
||||
|
I favor stored procedures (MySQL has had stored procedures support since 5.0) from a security point of view - the advantages are -
The disadvantages are -
|
||||
|
I think if someone wants to use PHP and MySQL or some other dataBase server:
Libraries examples: ---- PDO
--- MySQLi
P.S: PDO wins this battle with ease. With support for twelve different database drivers and named parameters, we can ignore the small performance loss, and get used to its API. From a security standpoint, both of them are safe as long as the developer uses them the way they are supposed to be used But while both PDO and MySQLi are quite fast, MySQLi performs insignificantly faster in benchmarks – ~2.5% for non-prepared statements, and ~6.5% for prepared ones. And please test every query to your database - it's a better way to prevent injection. |
||||
|
Type cast if possible your parameters. But it's only working on simple types like int, bool and float.
|
|||
|
If you want to take advantage of cache engines, like Redis or Memcached, maybe DALMP could be a choice. It uses pureMySQLi. Check this:DALMP Database Abstraction Layer for MySQL using PHP. Also you can 'prepare' your arguments before preparing your query so that you can build dynamic queries and at the end have a full prepared statements query.DALMP Database Abstraction Layer for MySQL using PHP. |
||||
|
For those unsure of how to use PDO (coming from the Basically, read it while you read the manual to see how to put the PDO functions to use in real life to make it simple to store and retrieve values in the formatyou want.
|
|||
|
Using this PHP function For example:
For more prevention you can add at the end ...
Finally you get:
|
||||
|
A few guidelines for escaping special characters in SQL statements. Don't use MySQL, this extension is deprecated, use MySQLi or PDO. MySQLi For manually escaping special characters in a string you can use the mysqli_real_escape_string function. The function will not work properly unless the correct character set is set withmysqli_set_charset. Example:
For automatic escaping of values with prepared statements, use mysqli_prepare, and mysqli_stmt_bind_param where types for the corresponding bind variables must be provided for an appropriate conversion: Example:
No matter if you use prepared statements or mysqli_real_escape_string, you always have to know the type of input data you're working with. So if you use a prepared statement, you must specify the types of the variables for mysqli_stmt_bind_param function. And use of mysqli_real_escape_string is for, as the name says, escaping special characters in a string, so it will not make integers safe. The purpose of this function is to prevent breaking the strings in SQL statements, and the damage to the database that it could cause. mysqli_real_escape_string is a useful function when used properly, especially when combined with sprintf. Example:
|
||||
|
I use three different ways to prevent my web application from being vulnerable to SQL injection.
I hope this will help you. Consider the following query:
mysql_real_escape_string() will not protect here. If you use single quotes (' ') around your variables inside your query is what protects you against this. Here is an solution below for this:
This question has some good answers about this. I suggest, using PDO is the best option. Edit:
An alternative to mysql_real_escape_string() is
Example:
|
||||
|
Regarding to many useful answers, I hope to add some values to this thread. SQL injection is type of attack that can be done through user inputs (Inputs that filled by user and then used inside queries), The SQL injection patterns are correct query syntax while we can call it: bad queries for bad reasons, we assume that there might be bad person that try to get secret information (by passing access control) that affect the three principles of security (Confidentiality, Integrity, Availability). Now, our point is to prevent security threats such as SQL injection attacks, the question asking (How to prevent SQL injection attack using PHP), be more realistic, data filtering or clearing input data is the case when using user-input data inside such query, using PHP or any other programming language is not the case, or as recommended by more people to use modern technology such as prepared statement or any other tools that currently supporting SQL injection prevention, consider that these tools not available anymore? how you secure your application? My approach against SQL injection is: clearing user-input data before sending it to database (before using it inside any query). Data filtering for (Converting unsafe data to safe data) Consider thatPDO and MySQLi not available, how can you secure your application? do you force me to use them? what about other languages other than PHP? I prefer to provide general ideas as it can be used for wider border not just for specific language.
see Principle of least privilege
Now, if you are an advanced user, start using these defense as you like, but, for beginners, if they can't quickly implement stored procedure and prepared statement, it's better to filter input data as much they can. Finally, let's consider that user sends this text below instead of entering his username:
This input can be checked early without any prepared statement and stored procedures, but to be on safe side, using them starts after user-data filtering and validation. Last point is detecting unexpected behavior which requires more effort and complexity, it's not recommended for normal web applications. Unexpected behavior in above user input is: SELECT, UNION, IF, SUBSTRING, BENCHMARK, SHA, root once these words detected, you can avoid the input. UPDATE1:A user commented that this post is useless, OK! Here is what OWASP.ORG provided:
As you may knew, claiming on any article should be supported by valid argument, at least one reference! Otherwise it's considered as attack and bad claim! Update2:From the PHP manual, PHP: Prepared Statements - Manual:
Update3:I created test cases for knowing how PDO and MySQLi sends the query to MySQL server when using prepared statement: PDO:
Query Log:
MySQLi:
Query Log:
It's clear that a prepared statement is also escaping the data, nothing else.As also mentioned in above statement Please see this question for more detail: PDO sends raw query to MySQL while Mysqli sends prepared query, both produce the same result References: |
||||
|
The simple alternative to this problem could be solved by granting appropriate permissions in the database itself. For example: if you are using mysql database. then enter into the database through terminal or the ui provided and just follow this command:
This will restrict the user to only get confined with the specified query's only. Remove the delete permission and so the data would never get deleted from the query fired from the php page. The second thing to do is to flush the privileges so that the mysql refreshes the permissions and updates.
more information about flush. To see the current privileges for the user fire the following query.
Learn more about GRANT. |
||||
|
A simple way would be to use a PHP framework like CodeIgniter or Laravel which have in-built features like filtering and active-record, so that you don't have to worry about these nuances. |
||||
|
Warning : the approach described in this answer only applies for very specific scenarios and isn't secure since SQL injection attacks do not only rely on being able to inject If the attackers are trying to hack with the form via PHP's
Because But you must be careful, that you must not rewrite a safe query from your site. The code above is giving you a tip, to rewrite or redirect(it depends on you) that hacking-specific dynamic query string into a page that will store the attacker'sIP address, or EVEN THEIR COOKIES, history, browser, or any other sensitive information, so you can deal with them later by banning their account or contacting authorities. |
||||
|
There are so many answers for PHP and MySQL, but here is code forPHP and Oracle for preventing SQL injection as well as regular use of oci8 drivers:
|
||||
|
Using PDO and MYSQLi is a good practice to prevent SQL injections, but if you really want to work with MySQL functions and queries, it would be better to use
There are more ability to prevent this: like identify - if the input is a string, number, char or array, there are so many inbuilt functions to detect this. Also it would be better to use these functions to check input data.
And it is so much better to use those functions to check input data with |
|||||||||||||||||
|
A good idea is to use an 'object-relational mapper' like Idiorm:
It not only saves you from SQL injections, but from syntax errors too! |
||||
|
I've written this little function several years ago:
This allows running statements in an one-liner C#-ish String.Format like:
It escapes considering the variable type. If you try to parameterize table, column names, it would fail as it puts every string in quotes which is invalid syntax. SECURITY UPDATE: The previous
protected by AVD Jun 6 '12 at 9:59Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10reputation on this site. preg_replace_callback version doesn't cause problems if the replacement contains these tokens.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|