I have seen a few people on here state that concatenating queries using mysql_real_escape_string will not protect you (entirely) from SQL injection attacks.
However, I am yet to see an example of input that illustrates an attack that mysql_real_escape_string would not protect you from. The majority of examples forget that mysql_query is limited to one query and use mysql_real_escape_string incorrectly.
The only example I can think of is the following:
mysql_query('DELETE FROM users WHERE user_id = '.mysql_real_escape_string($input));
This would not protect you from the following input:
5 OR 1=1
I would see this as incorrect usage of mysql_real_escape_string rather than a shortcoming, it is designed for strings not numeric values. You should either cast to a numeric type or if you are going to treat the input as a string when sanitising you should do the same in your query and wrap quotation marks around it.
Can anyone provide an example of input that can get around mysql_real_escape_string that does not rely on incorrect handling of numeric values or forget that mysql_query can only execute one query?
Edit: I am interested in the limitations of mysql_real_escape_string and not comparing it to alternatives, I realise there are better options for new projects and am not disputing that.
The main shortcoming of mysql_real_escape_string, or of the mysql_ extension in general, is that it is harder to apply correctly than other, more modern APIs, especially prepared statements. mysql_real_escape_string is supposed to be used in exactly one case: escaping text content that is used as a value in an SQL statement between quotes. E.g.:
$value = mysql_real_escape_string($value, $link);
$sql = "... `foo` = '$value' ...";
^^^^^^
mysql_real_escape_string makes sure that the $value in the above context does not mess up the SQL syntax. It does not work as you may think here:
$sql = "... `foo` = $value ...";
or here:
$sql = "... `$value` ...";
or here:
$sql = mysql_real_escape_string("... `foo` = '$value' ...");
If applied to values which are used in any context other than a quoted string in an SQL statement, it is misapplied and may or may not mess up the resulting syntax and/or allow somebody to submit values which may enable SQL injection attacks. The use case of mysql_real_escape_string is very narrow, but is seldom correctly understood.
Another way to get yourself into hot water using mysql_real_escape_string is when you set the database connection encoding using the wrong method. You should do this:
mysql_set_charset('utf8', $link);
You can also do this though:
mysql_query("SET NAMES 'utf8'", $link);
The problem is that the latter bypasses the mysql_ API, which still thinks you're talking to the database using latin1 (or something else). When using mysql_real_escape_string now, it will assume the wrong character encoding and escape strings differently than the database will interpret them later. By running the SET NAMES query, you have created a rift between how the mysql_ client API is treating strings and how the database will interpret these strings. This can be used for injection attacks in certain multibyte string situations.
There are no fundamental injection vulnerabilities in mysql_real_escape_string that I am aware of if it is applied correctly. Again though, the main problem is that it is terrifyingly easy to apply it incorrectly, which opens up vulnerabilities.
Ok, so apart from mysql_* being deprecated, I understand your wanting to know about any possible workaround that might exist. perhaps this blog post and the slides might reveal some of them.But as this older question here shows, casting and quoting isn't full proof. There's just So many things that can wrong, and Murphy's law, twined with that ever valid mantra "Never trust the network", will go horribly wrong.
Perhaps this article, but most importantly, the follow-up to that article can reveal even more security issues. To be honest, I know mysql_real_escape_string isn't fullproof, even in combination with type casting and string formats:
printf('WHERE id = \'%d\'',(int)mysql_real_escape_string($_REQUEST['id']));
doesn't cover every possible attack. I'm no expert on this matter, but what I can tell you is sanitizing every input, will, if anything, give you a FALSE sense of security. Most of the time, you'll know (initially) what and why and how you protect against the attacks, but your colleagues might not. They might forget something, and your entire system is compromized.
In summary: Yes, you might be able to prevent any form of malicious input from getting to your DB, but every additional action it requires is an added risk. In that scenario, the greatest liability (as always) is the developer that hasn't had is fourth cup of coffee on a monday morning. No code, no matter how defensive and well thought out, can protect itself from the monster that is a tired developer with a bad temper, going cold turkey on caffeine and nicotine.
Related
So I was busy with PHP, inserting data into mysql when I wanted to know: I have come accross some posts that say it's bad practice to use single quotes to insert data into a database. one of the examples: Why are VALUES written between quotes when sent to a database?
The post is about why they're written between quotes, but one thing was clear: It's bad practice to insert it like:
$sql = INSERT INTO example (example1, example2, example3) VALUES
('$example1', '$example2', '$example3');
Why is this be bad practice? Apparently it is vurnerable to injection as stated in the above link given. the OP his question was related to the comment was: We use mysqli_real_escape_string for this. The respons given was:
#XX To a large extent, yes, it is an alternative solution to the problem. It doesn't disable anything, but it escapes things so that for instance ' becomes '' or \' in the SQL string, keeping the attacker from ending the string. There are awkward cases where such escaping is hard, and it's easy to miss one escape call among many, which is why parametrised queries are considered the most reliable approach.
First of all: How does a script want to fool mysqli_real_escape_string into NOT escaping certain stuff? I found something that said the following and correct me if i'm wrong: mysqli_real_escape_string - example for 100% safety. As you can see he refers to another page, that has an answer. However He then makes a claim that should make his data 100% safe and someone else responds with:
Yes, that is generally safe. Mysql and mysqli are perfectly safe when used right (specific bugs in very specific encodings notwithstanding). The advantage of prepared statements is that it's more difficult to do things the wrong way.
I have the following example to make it clear for myself: I have 2 doors, 1 door is open, but behind a closed door. How would you attack an open door with a closed door in front of it?
There is an answer here: SQL injection that gets around mysql_real_escape_string(), but he says as an safe example:
mysql_query('SET NAMES utf8');
$var = mysql_real_escape_string("\xbf\x27 OR 1=1 /*");
mysql_query("SELECT * FROM test WHERE name = '$var' LIMIT 1");`
Isn't mysqli_real_escape_string already doing the same? he's just specifying what characters should be mysqli_real_escaped_string. So how can this all of the sudden become safe? Since it is doing the exact same thing as when you would say:
$example = mysqli_real_escape_string ($conn, $_POST['exampleVariable']);
So how does this:
mysql_query('SET NAMES utf8');
$var = mysql_real_escape_string("\xbf\x27 OR 1=1 /*");
mysql_query("SELECT * FROM test WHERE name = '$var' LIMIT 1");
become safe and this:
$example = mysqli_real_escape_string ($conn, $_POST['exampleVariable']);
not? Isn't he just narrowing down what mysqli_real_escape_string would escape, thus making it more vulnerable?
The thing is, mysqli_real_escape_string() or other proper escaping is actually technically secure, in the end, that's about what parameterized queries do too. However, there is always a however. For example it is only secure if you have quotes around variables. Without quotes it is not. When it's a 1000 line project with one developer, it's probably ok in the first 3 months. Then eventually even that one developer will forget the quotes, because they are not always needed syntactically. Imagine what will happen in a 2 million LOC project with 200 devs, after 5 years.
Similarly, you must not ever forget using your manual escape function. It may be easy first. Then there is a variable that is validated and can only hold a number, so you are sure it's ok to just put it in without escaping. Then you change your mind and change it into a string, because the query is ok anyway. Or somebody else does it after 2 years. And so on. It's not a technical issue. It's a management-ish issue, in the long run, your code will be vulnerable somehow. Hence it is bad practice.
Another point, it's much harder to automatically scan for SQL injection vulnerabilities if manual escaping is in place. Static code scanners can easily find all instances of concatenated queries, but it's very hard for them to correlate previous escaping if there is any. If you use something like parameterized queries, it is straightforward to find sql injections, because all concatenations are potential candidates.
Setting the character set for the connection does not change what mysqli_real_escape_string() escapes. But it avoids the multi-byte character bug because it controls how the string is interpreted after the backslash escape characters have been inserted.
Of course, you can avoid any uncertainty by using query parameters instead.
Edit if you plan on answering this question please at least read it. Don't simply read the title, then Google 'sql injection php', and paste the results as an answer
First, I'm well aware that there are lots of resources available on how best to prevent SQL injection, but my question is specifically about if very little effort can be enough.
An organization I contract for was recently told that partners' (PHP) websites developed by their previous contractor have been found to have major security issues (my personal favourite is by using the string 'Emergency' in a URL you can gain unauthenticated access to any page in the site...)
I have been asked to review the security of a PHP site and highlight any major issues. I know from previous experience with this site that the standard of coding is truly awful (e.g. huge swathes of code duplicated across pages with around 5% variation, hundreds of unused variables, $var = "yes" in place of booleans, SQL statements written into every single script, unsecure by default (some pages forget to authenticate users), etc). Reviewing the site is a painful reminder that there are some real morons in the world that call themselves developers.
Because of these code quality issues I want to only highlight the serious and semi-serious security problems. If I note every problem with the site my review will take weeks.
I am not an expert on SQL injection, but it's my understanding that you must be able to close an existing query's quoted string before injecting any other kind of statement. So is the following line of code sufficient?
"'".str_replace("'","''",$_POST['var_name'])."'"
I'm not interested in suggestions about improving or changing the code, just whether it's possible in this scenario for SQL injection via $_POST['var_name']. If you're not familiar with PHP str_replace does replace all instances of the first argument with the second, not just the first instance.
Any input much appreciated.
No. In all honesty, if you are not preparing your statements, you are ASKING for a world of hurt.
Just because you escape your quotes with quotes, you are not protecting yourself. Think about this:
A user send you: username'; drop database foo;
You will escape it as username''; drop database foo;
But! if the user does: username\'; drop database foo;
You will be in trouble. You will resolve this for username\''; drop database foo;
Meaning the quote the user placed is escaped, and your quote ended the field username. The drop will then be execute. This is very unsecure.
You need to make sure you Prepare your statements or apply a quote command such as PDO::quote or mysqli_real_escape_string as these escape special characters.
You've got two options - Escaping the special characters in your unsafe_variable, or using a parameterized query.
$safe_variable = mysql_real_escape_string($_POST["user-input"]);
$mysqli = new mysqli("server", "username", "password", "database_name");
$unsafe_variable = $_POST["user-input"];
$stmt = $mysqli->prepare("INSERT INTO table (column) VALUES (?)");
Both would protect you from SQL Injection. The parameterized query is considered better practice, but escaping characters in your variable will require fewer changes.
To answer your question: no, simply removing quotes is not enough to prevent SQL injection.
For example,
"SELECT * FROM user_table WHERE userid=$userid AND password=$password"
Could go badly wrong if $password contained "garbage OR 1", or something like that. So if they've got badly formatted queries, removing quotes won't help.
It depends on your database server, and its configuration.
Doubling ' to '' is the ANSI standard way of escaping string literal content, and should be enough.
But, if you're using MySQL or versions of PostgreSQL before 9.1, string literal syntax is not ANSI-conformant by default (it can be, if reconfigured), and the backslash character has a special meaning. This permits attacks like the \' in 680's answer.
Additionally, if you're passing byte strings to your data access function, and your database happens to be using an East Asian character encoding, you'll have the problem that str_replace does a byte replace on a ' that may be part of a multi-byte sequence, ending up with a high byte followed by '': the first quote gets eaten as part of the multi-byte sequence, then the second closes the string. (This doesn't happen in UTF-8 which is designed to avoid trailing low bytes.)
Using the appropriate escaping call for the DB you are using (eg mysql_real_escape_string), or, better, using parameterised queries, means you don't have to know about these obscure and annoying edge cases.
I'm developing a simple PHP database application for internal use but would like to code it to best practices. Some of my pages are receiving integer values from GET requests and I'm just wondering how much validation and sanitation is really required.
Currently I'm using $num = filter_input(INPUT_GET, 'num', FILTER_VALIDATE_INT, $num_options); with specified min and max values. From here I'm exiting with an error message if $num == false
Is it necessary to also use $mysqli->real_escape_string($num);
Currently I am not bothering because I think it's quite hard to do SQL injection using an integer...
Thanks,
Kevin
UPDATE: To clarify the query I'm doing looks like this
$sql = "SELECT employeeID, concat(FirstName, ' ', LastName) as Name FROM employee WHERE employeeID='$num'";
I see your using mysqli, your best option for security is to look into Prepared Statements.
PHP mysqli Prepared Statements
It's a bit involved for an example, but the above link has indepth examples.
Once you get the hang of it though, and build your class. It's really only a normal sql query but instead of including your values you use ?
"SELECT * FROM account WHERE username = ? AND password = ?"
and you bind your values to the statement:
array("bradley", "Passw0rd");
The security comes from, as a short answer, is the fact you don't concat the values into the query string yourself. Making it less prone to sql injection.
Like many other PHP users you are taking escaping wrong. You taking it as a some sort of magic wand which makes some "evil characters" "safe".
This is wrong idea.
though prepared statements can be taken as a sort of such a magic wand, escaping is not a synonym for "SQL injection protection". It is a merely string syntax rule - no more, no less.
Is it necessary to also use $mysqli->real_escape_string($num);
It is irrelevant question.
To escape or not to escape decision have to be bound to SQL, not to the data source or any validations:
real_escape_string() have to be used for the sql strings, i.e. parts of the query enclosed in quotes. Have to be used unconditionally, despite of whatever previous manipulations.
For the any other part of the query real_escape_string() being completely useless.
An explanation:
Data validation rules can be changed.
While SQL building rules have to be explicit and unconditional. To make a developer never ask himself a question like this.
In fact, it's completely different matters: data validation and query building. Why keep in mind such details and build the query accordingly? Why not to build the query based on some set of general purpose rules, irrelevant of the data nature at all?
So, to your question again:
if you are adding your data to the query as is, without quotes, real_escape_string() going to be completely useless in this case, but casting/validation become essential.
if you are adding your data to the query using prepared statement, real_escape_string() going to be completely useless and even harmful.
if you are adding your data to the query in quotes - you ought to do real_escape_string() in this case.
it is also worth to mention that if you are adding your data to the query as a part of SQL language - as an identifier or an SQL keyword - real_escape_string() is completely useless too, as well as prepared statement. Whitelisting is your only friend here
I have started in web development not long time ago. I know some stuff now, but I'm really concerned about security issues that may arise. I know simple security solutions like preg_replace , but I'm not confident with that.
So I would like to ask you for any sort of speaking "universal" security standards that can be applied in the following cases. As I mentioned, I'm not pro so it would be great if you can start with something simple, yet useful. If possible could you provide examples please?
I did have a look at php manual, although I would like to know additional info from person.
Here are some typical MySQL / PHP things I use in my projects. Could you suggest any improvements to make them more secure?
$sql = mysql_query("SELECT * FROM stories WHERE showing = 1 ORDER BY cr_date DESC LIMIT 5") or die (mysql_error("There was an error in connection"));
while($row = mysql_fetch_assoc($sql)){
$story_id = $row["id"];
// etc...
}
$username = $_POST['username'];
$sql = mysql_query("INSERT INTO myMembers (username, //etc... )
VALUES('$username' //etc.. ")or die (mysql_error());
$username = $_GET['username'];
//gets username from url like http://myweb.com/profile.php?username=blabla
First of all, thank you for caring about web security. Many PHP developers don't know anything about it, and don't care to learn. They are the ones who are exposing our passwords and bank accounts to hackers. Be part of the solution! :-)
1. Treat the mysql extension as if it is deprecated.
Use the PDO or mysqli extensions instead. The plain mysql extension does not support prepared statements, and some other features, such as transaction control. No one should be using mysql if they have PDO_mysql or mysqli available to them.
2. Do not interpolate external data into SQL.
Anytime you get a value from $_GET or $_POST, you should consider it to be unsafe to use in any SQL statement, or shell_exec(), or other instance where you execute the string as some kind of code.
3. Use prepared query parameters instead of interpolation.
It's really easy. In fact, it's easier to use query parameters than it is to interpolate variables into SQL strings. You don't need to worry about escaping, or long complex string-concatenation.
See example code here: http://us.php.net/manual/en/pdo.prepare.php
4. For corner cases, use careful filtering.
A query parameter takes the place for one literal value in an SQL expression. Not table names, not column names, not SQL keywords, not lists of values or full expressions. For those, you do need to use string interpolation, but see my presentation SQL Injection Myths and Fallacies for examples of how you can "whitelist" values to interpolate.
Also check out the PHP filter extension, which offers a flexible way of validating inputs or stripping off invalid characters to make sure only the valid part of the input is used.
Looking at your examples, the SELECT query has no dynamic values interpolated from external sources like $_GET. So that one is safe.
The INSERT query takes a value from the request, which could contain malicious content that changes the way your query runs. This one is a good candidate for using query parameters.
Also consider that SQL injection is one of the two most prevalent security issues with PHP. The other one is Cross-Site Scripting (XSS). This is not directly related to SQL, but you should learn about it too.
Here's a good resource for learning more about web programming security: OWASP.org cheat sheets.
Many frameworks have a good set of security measures already in place that will do a great deal in preventing things like SQL injections. Yii, CakePhP, CodeIgnitre all may be of some use.
Although it's almost impossible to beat Bill, I feel I must clarify answers stating that "you have to trust no user input".
In fact, quite contrary - SQL injection protection will do any good only if it would be totally ignorant of the data source. And treat ALL the data as potentially malicious. And process it accordingly.
Thus, to summarize all the advises:
Prepared statements is a good approach but not a complete one.
It has a brilliant idea of using some placeholder, a proxy to represent the actual value in the query. Thus this value can be properly sanitized.
But these placeholders, as Bill said, are limited to the strings and numbers only. So, it would be a good idea to add another placeholder of your own - for identifiers. But you still have to watch out SQL syntax keywords manually.
So, instead of "Do not interpolate external data into SQL." statement one have to use
"2. Do not interpolate values into query directly but only by some proxy, performing necessary precautions"
The most important thing to remember is never trust anything from an external source (eg user input, responses from other web services etc). Always sanitise all input and where possible use code from your database provider to do so.
In the case of MySQL parameterising all queries is essential, so use a prepared statement, eg
$statement = $db->prepare('SELECT * FROM stories WHERE title = :title');
$statement->execute(array(':title' => $title));
$rows = $statement->fetchAll();
Your current insert statement is vulnerable to an SQL injection attack, modify it to be closer to:
$username = $_POST['username'];
$statement = $db.prepare("INSERT INTO myMembers (username) VALUES(':username');
$statement->execute(array(':username' => $username));
You should also ensure that you never store any passwords in plain text, always store a hashed version of a password (along with a salt) and check that the hash matches rather than the actual string. This means that should your database become compromised, figuring out your user's credentials becomes a non-trivial task.
These are only a couple of ways of making your app more secure, I'd highly recommend reading OWASPs top 10 site vulnerabilities and researching these individually as each one in itself is quite a big topic!
I've been reading about SQL injection attacks and how to avoid them, although I can never seem to make the "awful" examples given work, e.g. see this post.
I created a PHP file and a table in the database, had a value passed through $_GET and tried to delete the table by doing bob'); drop table students; -- and it didn't work. PHP automatically escapes the \' and the query has an error, no harm done. Same issue when trying to replicate login "attacks" like AND WHERE 1=1 etc.
example code:
<?php
$id = $_GET['id'];
$sql = "INSERT INTO Users (Username) VALUES ($id)";
echo $sql;
mysql_query($sql) or die(mysql_error());
And I'd pass sql.php?id=1); delete from Users; --
So is this some dated thing that used to apply in the days of PHP3 or something, and nowadays even novices are protected from things like magic quotes?
I'm using PHP5 on Ubuntu.
Quite the contrary. Magic quotes are deprecated in PHP5 and will be completely removed in PHP 5.4, as they brought more confusion to the programming world than they did good. Checking whether magic quotes are active, and escaping any SQL input scrupulously if necessary, is still very, very important... No reason to feel bad though, we've all been there, and my unknowing ass has been saved by magic quotes countless times :)
The PHP manual on magic quotes explains everything.
No this is still very relevant.
As are XSS and CSRF. Never underestimate the importance of proper input filtering.
Heh, you're saved in this case by having magic_quotes_gpc set to "on".
You'll be screwed soon.
The largest identity-theft in history was achieved in 2007 by exploiting an SQL injection vulnerability: see "SQL injection attacks led to Heartland, Hannaford breaches" (ComputerWorld, 8/18/2009).
OWASP reported in 2007 that injection attacks (of which SQL injection is one example) continue to be one of the most common software security problems.
You can also search for recent SQL injection News and find many cases reported every month.
However, the example in the XKCD cartoon isn't necessarily the most common type of exploit. Dropping a table by executing a second SQL statement in one request probably wouldn't gain the attacker much in the way of valuable data, it would just be vandalism.
Also, some query interfaces disallow multi-query by default anyway. That is, the database client API executes only a single statement given the SQL string, regardless of semicolons. This defeats the example shown in the cartoon.
note: PDO's query() method is known to support multi-query by default. So it is susceptible to the XKCD-style attack.
As other folks have pointed out, the more likely risk is that an SQL injection will alter the logic of SQL expressions, and apply your query to extra rows besides those you intended.
For example:
$sql = "UPDATE Users SET PASSWORD = MD5('" . $_POST["password"] . "'||salt) " .
"WHERE user_id = " . $_POST["userid"];
What happens when I send a request with parameter userid set to the string 123 OR userid=456? I would reset my own password (userid 123) as well as the password of userid 456. Even hashing the password with a per-user salt wouldn't protect against this. Now I can log into either account.
There are lots of ways SQL injection can be perpetrated.
Magic quotes don't take character encoding into account, and thus are vulnerable to attacks based on multi-byte characters.
As for it being a risk today, Google searches turn up countless vulnerable sites. An SQL Injection vulnerability was reported for Bugzilla around September 10. So, yes, sites are still at risk. Should they be? The tools are there to prevent injection, so no.
That particular attack doesn't work, as mysql_query will only execute a single statement.
I can still abuse your code though, e.g. if I arranged for id to be SELECT password FROM Users WHERE Username='admin' I might have a fighting chance of being able to get your system to expose some internal information.
Basically, if you allow unfiltered input into your SQL, there will be some very creative ways of both creating data you didn't expect, and exposing data you didn't intend!
Oh my.. SQL Injection is not a risk, it is a gaping security hole. It mainly exists in php because the API makes you want to interpolate any old data into your SQL queries.
When I see a site written in PHP or ASP, I can just smell the SQL injection vectors that they reek of. People try to secure their PHP apps with mysql_real_escape_string() and intval() and do similarly in other languages. This is a mistake. It's like coding in C instead of Java or Python, where in the former, you make one mistake and you're dead, but in the latter, only semantic flaws can exist.
I strongly urge people to use either mysqli with prepared statements, or anything else that is parameterized, substituting text into code and then interpreting it is just bad practice in the first place IMHO.
On another note, PHP's magic quotes is just silly, and thankfully, deprecated. It can only cause more harm than good. If you rely on magic quotes, it means your app will be owned when magic quotes is disabled. Similarly, it may break other apps that don't expect escaped strings in inputs.
This is very much an active risk, magic quotes tries to give you a solution but I prefer to always develop with magic quotes off. This way I have to make sure I actually escape the inputs myself. Who knows if magic quotes will be on or off on the server where the script is actually deployed.
This is still a big problem. You can't assume that magic_quotes is turned on in every PHP installation you might use.
To see if magic qotes is turned on and clear out the mess from magic quotes:
if ( get_magic_quotes_gpc() !== 0 ) { $foo = stripslashes( $foo ); }
Then cleaning your statements a little:
$foo = mysql_real_escape_string( $foo );
$sql = "select * from foo where bar='{$foo}'";
etc.
In fact, you're better off just strictly turning of magic_quotes if you have the ability to do so.
I hope that helps you.
The bobby tables example will not work with the mysql interface because it doesn't do multiple queries in one call. The mysqli interface is vulnerable to the multiple query attack. The mysql interface is more vulnerable to the privilege boost attack:
In your form I type account: admin password: ' or 1=1 -- so that your typical login sql: select * from users where user_name = '$admin' and password = '$password'. The or causes this to be true and let's you log in.
Can't PHP do query parameters? If it can (as I'd be surprised if it didn't), that is the one solution which mitigates ALL SQL injection attacks.
As I've mentioned several times on stackoverflow before, I am a strong supporter of PDO, just stop using the old fashioned mysql, do yourself and your clients a big favor and learn PDO (it's really easy) and take advantage of prepared statements and bound parameters. Even if you do not need prepared statements performance wise, you still get the security benefits.
Also, I will recommend crashing your entire app in the clients face if magic quotes is set to on. It's just a drain on resources designed to protect the dumb and annoy the smart. (it uses more cpu than escaping manually, because it encodes everything, even when you don't need it)
There are a lot of different ways to perform a SQL Injection and quite a lot of ways to bypass basic safety precautions.
Those attacks have been within the top 10 web application vulnerabilities (rank #2) according to OWASP.
For more information, please refer to Top 10 2007-Injection Flaws.
No, and the less you worry about SQL Injection, the more likely you are to get hit by it.
Parameters passed to sql queries from the web pages ofen tend to be numeric IDs. For example let's assume you have an url http://foo.com/page.php?section=34 from which the section ID is used in a query like this:
SELECT content FROM sections WHERE section_id=$section;
No quotes to escape like in your example and whatever you'll put after the number in the URL will be passed to the query... So thew risk is real.
The simplest rule of thumb is to assume that all user input can be tainted. Check that data types are what you expect, variables are in the length/size ranges you were expecting, files are of the size and types you allow, etc. Other checks on non-external data can be warranted - before you call some important admin-level function, do a check - ($userlevel != ADMIN)?die():important_function();
There's always a bigger fish, or somebody who's a bigger jerk than you. Avoid assumptions about data and you've got a head start.
Not today yet, but it's only 20:34 UTC
Guardian jobs database attack demonstrates difficulties of database security, 06 Nov 2009
Guardian Jobs website hack may have been an SQL injection and not a 'sophisticated' attack, 27 Oct 2009
Whenever building up SQL from strings, SQL injection is a real danger.
I have also discovered that trying to avoid building up SQL from strings is a pointless endeavor. Sooner or later the full form of your SQL (not just things that could be parameters) must be generated at runtime.
I've have to develop for a server which has no way for me to disable magic_quotes! I include this on every page to undo the effects of magic quotes, so I can do proper escaping myself without \'double escaping\'. Even though I can taste vomit just from reading this, I haven't found a better solution.
if (get_magic_quotes_gpc()) {
$process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST);
while (list($key, $val) = each($process)) {
foreach ($val as $k => $v) {
unset($process[$key][$k]);
if (is_array($v)) {
$process[$key][stripslashes($k)] = $v;
$process[] = &$process[$key][stripslashes($k)];
} else {
$process[$key][stripslashes($k)] = stripslashes($v);
}
}
}
unset($process);
}
As per OWASP 2017 Top 10, still Injection is the most happened and dangerous attack.
"SQL injection is always the number one risk. That is a reflection of just how many incidents are out there, as well as other factors that keep it very high up there" Troy Hunt - founder of breach site haveibeenpwned.com
Just to remember, using SQL injection we can dump entire database, controlling web server by uploading web shell, etc.