How to prevent in codeigniter to not insert single quotes around in our query?
When we write query in codeigniter it inserts automatically single quotes, like this:
$this->db->select('id, ifnull(name,\'\') as name');
$this->db->from('table');
which creates database error.
$this->db->select('id, ifnull("name",\'\') as name', false);
$this->db->from('table');
Is what you're after. The quotes are escaping to stop sql injection, be sure not to mix unsanitized input from the user.
I guess I should also note that using this false parameter will stop double quote encapsulation, if you're using postgres you'll probably need to encapsulate any kew words used as column names yourself. (see difference between name and "name")
Active Record - Selecting Data
Related
I have an input field named "eventName". everytime I will put single quote (e.g uncle's birthday) it won't be inserted to the database. I mean no data at all will be posted to database. the system will just say that the event was saved but no data is being stored in the database.
You need to escape the single quote. The escape character used in this case of a '\', you can use inbuilt functions like mysqli_escape_string or add-slashes.
When you add a single quote in a variable and add it to a query, this will change your query by considering the single quote as a comment. e.g
Insert into Table ('name') values ('uncle's birthday');
Your query got ended at uncle and the part after that won't be considered, essentially this would result in failure. You should check what the error code as well depending on which database you are using.
Update:
$eventName = add_slashes($_POST['eventName']);
Rather than simply adding slashes, consider prepared statements, thus preventing SQL injection attacks. More details about this here: How can I prevent SQL injection in PHP?
It's good practice to escape values before writing them to your database.
$escapedName = mysqli_real_escape_string($_POST['eventName']);
Do I need to use mysqli_real_escape_string when reusing data from a database for a query. The data was previously escaped so it can be safely inserted into the database. I am aware that when inserting data into a database, backslashes are removed.
Thanks.
Yes, you have to re-escape data that came from a DB when you're re-using it in another query. Consider escaping to be the equivalent of gift wrapping on a present. You "wrap" some data for the database in one query. It'll UNWRAP the data and put it in the data store. When you retrieve that data again later, the wrapping's gone and the data's "dangerous" again.
e.g. consider something like this:
$name = "Miles O'Brien";
$safe = mysql_real_escape_string($name); // name becomes Miles O\'Brien
$sql = "INSERT INTO people (names) VALUES '$safe'";
$result = mysql_query($sql) or die(mysql_error());
Now that name's in the database, but the escaping you performed is NOT PRESENT anymore - it was removed by the database as it processed the query, so if you do something like this:
$sql = "SELECT name FROM people"
$result = mysql_query($sql) or die(mysql_error());
while($row = mysql_fetch_asssoc($result)) {
$name = $row['name']; // get Miles O'Brien from the DB again
here you'll literally have retrieved Miles O'Brien with no escaping at all.
$other_sql = "UPDATE ... WHERE name=$name"; <---INJECTION HERE
}
Escaping is not something you do only with "outside" data... ANY data you insert into a query string is "outside" data, even if you just got that data from the database just a few lines of code ago.
TL;DR: You can easily inject yourself.
Yes, you need it. The escapes are only used to make the query syntactically valid, they're not part of the data that's stored in the table. Any time you're interpolating strings into a query, you need to escape it.
As an example, suppose you have a table of full names, and there's someone with the last name O'Reilly. You perform a query to get this name into $lname, and then you want to use that variable in another query, e.g.
$query = "SELECT username WHERE last_name = '$lname'";
If you don't escape the string, the resulting query will be:
SELECT username WHERE last_name = 'O'Reilly'
As you can see, the quotes are not properly balanced. You need to escape it so that it will be:
SELECT username WHERE last_name = 'O\'Reilly'
However, if you use prepared queries with placeholders for these parameters, you don't need to worry about this much at all (in fact, it would be wrong to escape a variable that's bound to a placeholder, as you will then store the backslashes). This is generally preferred.
Also, consider NOT extracting and re-storing the data at all, but moving data around using SQL itself:
INSERT INTO Table1 (last_name)
SELECT last_name
FROM Table2
WHERE ...
This is also likely to be more efficient, since the data doesn't have to move between the database and the application.
That's not what escaping means.
Escaping text means inserting escape characters so that it can be inserted into a SQL string and be interpreted as the original text.
It has no effect on the actual value, unless you use the wrong escape characters.
You need to correctly escape your text every time you concatenate it into any kind of structured language.
When using SQL, you should ideally use parameters instead of concatenation.
There are a lot of misunderstanding on the topic.
People keep using improper words, and a real danger coming from such a confusion.
escaping being confused with safety
data being confused with strings
formatting being confused with trusting
One have to sort these matters out.
Otherwise we still have an accepted answer implying that using mysql_real_escape_string does produce a "safe" variable. While it is not.
Just remember to validate properly all user inputted data that you plan on using and don't allow html or javascript code to be inserted. You also need to keep in mind XSS attacks, not just MySQL Injections. A good way to prevent xss is using htmlspecialchars() to convert HTML characters into HTML entities.
I'm familiar with prepared statements and I know that they are best practice when it comes to protecting against MySQL injection. But I'm wondering how this PHP/MySQL statement could be at risk of an injection attack:
$result = mysqli_query($db,"SELECT name FROM users WHERE id = '".$_POST['name']."';");
It seems to me like the input from the user would be contained inside the single quotes. Can you execute more than one query in one mysqli_query statement?
Also, is making the above safe just as easy as this...
$result = mysqli_query($db,"SELECT name FROM users WHERE id = '".mysqli_real_escape_string($_POST['name'])."';");
It seems to me like the input from the user would be contained inside the single quotes
It would unless you include single quotes in the posted name, which would allow you to break out of the quotes. Example, post the name as:
' or 1 or '
The WHERE clause becomes:
WHERE id = '' or 1 or '';
This would match and retrieve all rows in the table because of the or 1 part. As you can see, it breaks out of the quotes to inject some SQL, then it goes back into the quotes to make the query valid.
Can you execute more than one query in one mysqli_query statement?
No, but if it was executed with mysqli_multi_query then yes you could add multiple queries on to the end.
is making the above safe just as easy as mysqli_real_escape_string?
Generally yes but a Prepared Statement would be better. Using escaping, the WHERE clause would become (using my example above):
WHERE id = '\' or 1 or \'';
This is no longer vulnerable because the quotes can't be broken out of, and would only match rows if the name literally matches ' or 1 or ' which is obviously unlikely.
It seems to me like the input from the user would be contained inside the single quotes
All the attacker has to do is put a single quote inside the name POST data, and it won't be any more.
name=' OR 1=1
Also, is making the above safe just as easy as this
That looks OK … but it hurts my eyes. Use prepared statements. They are much easier to read then SQL built by concatenating strings together.
Basic explaination:
If you simply insert $_POST['name'] into the query as per your first example, the resulting SQL string will be invalid if the name variable contains a single quote character.
This will immediately annoy anyone named O'Brien, or similar.
But this can then be exploited by a hacker, who could modify his "name" to include valid SQL code after the single quote. This could be any valid SQL, allowing the hacker to do anything to your DB or query anything from it. Exactly what he can do would depend on other factors in your code, but suffice to say that even in the best case scenario, he could do some pretty devastating things.
To answer your second question: Yes. Escaping using mysqli_real_escape_string() will mitigate this problem.
However, to take things one step further, you might also want to investigate using Prepared Queries, which is a feature of the mysqli extension. This can make your code a lot neater as it avoids having to use that nasty long mysqli_real_escape_string() function name all over the place. It also has other benefits such as improved query caching.
Hope that helps answer the question.
What if I passed the following value for $_POST['name']?
'; DELETE FROM users WHERE name <> '
I would be closing the first single quote, then introducing the damaging query which just has a single open quote at the end, which would be closed by the single quote in your original query.
You second query is fine. Though you really ought to consider use of prepared statements (which are supported by mysqli)
If you're using mysqli you should always be using the SQL placeholder method for doing this. The escaping functions are the hard way.
$stmt = $db->prepare("SELECT name FROM users WHERE id = ?");
$stmt->bind_param('i', $_POST['name']);
$stmt->execute();
If you don't understand the risk here, you really need to read up on SQL injection attacks in general, and read what automated hacking tools can do to those that aren't cautious enough.
I have a query that looks at a list of files inside a folder and enters the names of everything into a database so I can control the sort when showing the images.
Now I had an image today which had a name of image123('2).jpg. The single quote caused my query from crashing so how can I get around this? To make things simpler I have made example scenario
I have list of 4 variables which have the following strings
$myVAR1 -- "MyName IS Leo";
$myVAR2 -- "MyName IS 'Tiger";
I am running a SQL query to enter them into a database
$sql = "INSERT INTO `names` (`StringID`, `StringValue`) VALUES (NULL, ' $myVAR1');";
$sql2 = "INSERT INTO `names` (`StringID`, `StringValue`) VALUES (NULL, ' $myVAR2');";
So how can I detect that the single quote is inside the string $myVar2 and how can I ignore it when entrying into the database?
You need to escape your data. Use prepared queries with PDO so you don't have to worry about this.
You are currently wide open to SQL injection.
At a minimum, use mysql_real_escape_string(), assuming you are using the standard MySQL library in PHP. It takes care of quotes, among many other things, escaping them properly so they will be inserted into your database.
I'm trying to wrap my head around writing queries in SQL and I'm having some difficulty understanding this example that I've found.
$q = "INSERT INTO `dbUsers` (`username`,`password`,`email`) "
."VALUES ('".$_POST["username"]."', "
."PASSWORD('".$_POST["password"]."'), "
."'".$_POST["email"]."')";
I guess I'm stumbling over the use of double quotes, single quotes, and the back-ticks. I compared this statement to the example on the W3 website and am just really confused as it seems much more complicated. Could you please explain to me what is going on in the above query? Thank you for your help!
$sql="INSERT INTO Persons (FirstName, LastName, Age)
VALUES
('$_POST[firstname]','$_POST[lastname]','$_POST[age]')";
The double quotes are used to define the elements that build your $q string. The single quotes identify strings within the SQL query that you are building and the backticks are used to escape object names in MySQL.
The double quotes surround the strings that will be a part of the query string. The dots between each double-quoted section are the concatenation operator. They are joining individual string pieces together.
You'll notice that there is a double-quote and dot before every $_POST[] array variable, and a dot and double-quote after.
e.g. " . $_POST["username"] . "
The first double quote ends the previous string section. The one at the end starts the next string section. Everything between the two dots is the POST variable. The reason the dots are necessary is because of the quotes around "username". In your W3 version they did not use quotes around the $_POST[] array key string (e.g. $_POST[firstname] and not $_POST["firstname"] or $_POST['firstname']) and so they did not need to use dots and quotes.
If you want to keep things simple, don't use the quotes inside of the $_POST[] variables and you won't have to use all those dots and quotes around them.
If you try version 1 without the dots and quotes the php parser will fail and you will see an error.
Backticks ` are to escape MySQL keywords (usually used for table and column names). Single or double quotes are required around any strings which are inserted.
Note that you should call mysql_real_escape_string on any string you're concatenating into a SQL query. Otherwise, it's possible to break out of quotes if $_POST also includes quotes. This can potentially be used to allow the execution of arbitrary SQL commands in what is known as a SQL injection attack.
The `back ticks` are optionally used to quote mysql field names, you will need them if you accidentally use one of mysqls reserved words to name a field - otherwise you don't need them.
When you enter a string into a field you have to 'quote it'.
The whole statement has to be quoted, but not clash with 2) above, hence the use of "double quotes".
Non scalar values such as arrays do not automatically expand, so you have to "drop out" . and . "back in" to PHP to build your string using concatenation sign a dot .
The backticks are a MySQL artifact in case you are using reserved words as your table/field names, and the single quotes delineate string literals in SQL. The double quotes are PHP-specific and separate strings in PHP. So, your query below would look like the following:
$sql="INSERT INTO Persons (FirstName, LastName, Age)
VALUES
('".$_POST["firstname"]."','".$_POST["lastname"]."','".$_POST["age"]."')";
One thing that the author above is doing is also breaking the PHP string into separate strings, probably to improve readability. MySQL server doesn't care about that.
There's actually a lot of unnecessary stuff in that first query. There are best practices to take into account but it could be re-written as such:
$q = "INSERT INTO dbUsers (username, password, email)
VALUES ('".$_POST["username"]."',
PASSWORD('".$_POST["password"]."'),
'".$_POST["email"]."')";
First thing: INSERT INTO dbUsers:
All this is doing is telling us what table we're inserting our data into.
(username, password, email)
Specifying the columns we're inserting into (order specific)
VALUES ('".$_POST["username"]."', PASSWORD('".$_POST["password"]."'), '".$_POST["email"]."')
Our values to be inserted (dependent on the order of the columns), then a terminating semicolon.
If you re-write this with hard coded values rather than concatenation, it would look like:
VALUES ('myUserName', PASSWORD('myPassword'), 'myEmail')
All of that should be self explanitory. Each value is contained within single quotes (') as they are strings. Then the password value is passed through the MySQL function PASSWORD which hashed the password for security purposes.
The double quotes are part of the PHP code, telling it that the items inside the double quotes are strings. They're not part of the SQL being built.
The single quotes are used to surround values in the resulting SQL. Ie, you're telling the database the value "bob" is used here. For some types of value (integers, boolean, etc) you don't need the single quotes. For many others (varchar, dates, etc), you need the single quotes.
The backticks perform much the same function as single quotes, except they're used around table names, field names, etc... rather than around actual values. They're used when the name in question wouldn't be interpreted by the database correctly there, for example if you had a field named count, since that's a keyword in SQL. As noted elsewhere, the backticks aren't necessary in your example, but many people put them in all the time because it doesn't hurt to have them; as a safety net, kindof.
To give a visible, simpler example
$name = "bob";
$sql = "SELECT * FROM `mytable` WHERE `name` = '" . $name . "'";
This would result in the $sql variable being
SELECT * FROM `mytable` WHERE `name` = 'bob'
As you can see, the double quotes are not part of the string.. they're just used in creating it. In the resulting SQL, the backticks surround the table/field names, and the single quotes surround the actual value bob.
As a complete side note, using the POST values directly in created SQL is dangerous as it allows for SQL injection attacks. The values should be escaped or a parametrized query should be used.