I currently have this code
$main_cat = "Antiques-collectables";
$mcat = "0187-1443";
$sub_cat = "toys";
mysql_query("
INSERT INTO categories
(id, main_cat, sub_cat, mcat)
VALUES
('', '$main_cat', '$sub_cat', '$mcat')
");
For some reasons the $mcat value is not stored properly . When I check it in the database it appears as "1" , "347" values etc ... only 1 or 3 digits value . I think that the "-" is interpreted by the sql engine as operator . Is there any way to escape it ? I also tried
$mcat = str_replace("-", "\-", $mcat);
but still doesn't work .
When you are inserting strings into the database, you need to make sure to use mysql_real_escape_string() on them. This prevents any unintentional problems, and also SQL injections which can really cause a lot of problems for your site.
You can, also, look at using prepared statements, which effectively eliminate this problem.
You didn't mention your data type of column in your table.
I think datatype of mcat is numeric type.
Probably by changing mcat data type to string solve your problem.
No, '-' is not a SQL operator when within single quotes (as you have it there).
The mcat column probably has the wrong data type. Is it a VARCHAR? To store what you've got there, it should be.
Related
My application is working fine. DB connection has been opened before call SQL commands in PHP.
The problem is that some parameters in an input form is blank, and after using real_escape_string the parameters have an empty string stored in database. The database columns are set to default to NULL.
Is this expected? I can't find anything relevant in PHP documentation.
Is it possible to simply make it store NULL?
Code is as below:
"INSERT INTO address SET firstname = '" . $mysqli->real_escape_string($data['firstname']) . "'";
It’s expected if you tell the server to use the empty string, which you are doing. You need to add some logic to your code to use null when a string is blank.
Also, you are wide open to SQL injection. You need to use prepared statements, rather than concatenating variables into your query. Escaping strings is not enough. See How can I prevent SQL injection in PHP?.
You probably should separate the data verification from the query creation. This can be done as follows:
$firstName = strlen($data['firstname'])? "'".$mysqli->real_escape_string($data['firstname'])."'": "NULL";
$sql = "INSERT INTO address SET firstname = " . $firstName;
This will check that $data['firstname'] has a value in it and if not, Null is used. This then is combined into your query that you then will run in some subsequent step.
This is by no means the only (or even the best) approach, but based on the code that you have provided, this should give you a start.
I wrote a script to insert record in my DB. The only issue I am getting is when I try to store data which contains ' character then the script does not work and it does not store anything in the DB. For example John's Birthday , Amy's Home etc . Any solution to this problem which allows special character like ' to store in the DB and retrieving them without any harm to security?
mysqli_query($con,"INSERT INTO Story (desc)
VALUES ('$mytext')");
PHP's mysqli_real_escape_string is made specifically for this purpose. You problem is that quotes are being interpreted by MySQL as part of the query instead of values. You need to escape characters like this so they won't affect your query - this is what SQL injection is.
$mytext = mysqli_real_escape_string($con, $mytext);
// continue with your query
Manual: http://php.net/manual/en/mysqli.real-escape-string.php
Filter the variable part of the query through mysqli_real_escape_string.
The table has company names which are not escaped.
My qry looks like
$sql = "SELECT id FROM contact_supplier WHERE name = '$addy' LIMIT 1";
The problem comes in where the company name values in the table are sometimes things like "Acme Int'l S/L".
(FYI: values of the $addy match the DB)
Clearly, the values were not escaped when stored.
How do I find my matches?
[EDIT]
Ahah!
I think I'm we're on to something.
The source of the $addy value is a file
$addresses = file('files/addresses.csv');
I then do a
foreach ($addresses as $addy) {}
Well, when I escape the $addy string, it's escaping the new line chars and including "\r\n" to the end of the comparison string.
Unless someone suggests a more graceful way, I guess I'll prob strip those with a str_replace().
:)
[\EDIT]
Why do you think the data already stored in the table should be escaped?
You should escape data only right before it is written directly into a text-based language, e.g. as a part of an SQL query, or into an HTML page, or in a JavaScript code block.
When the query is executed, there's nothing espaced. MySQL transforms it and inserts, otherwise it wouldn't insert and gives error because of syntax or we escape them for security like sql injection.
So your query with escaped values will be working fine with the data in your database.
If the values were not escaped when stored then they would have caused SQL errors when you tried to enter them.
The problem is that the data is not being escaped when you make the query.
Quick hack: Use mysql_real_escape_string
Proper solution: Don't build SQL by mashing together strings. Use prepared statements and parameterized queries
Another option would be to change your query to this...
$sql = "SELECT id FROM contact_supplier WHERE name = \"$addy\" LIMIT 1";
Use mysql_real_escape_string:
$addy = mysql_real_escape_string($addy);
Or try using parameterized queries (PDO).
Regarding this statement:
Clearly, the values were not escaped when stored.
This is incorrect logic. If the values weren't escaped in the original INSERT statement, the statement would have failed. Without escaping you'd get an error along the lines of syntax error near "l S/L' LIMIT 1". The fact that the data is correctly stored in the database proves that whoever inserted it managed to do it correctly (either by escaping or by using parameterized queries).
If you are doing things correctly then the data should not stored in the database in the escaped form.
The issue turned out to be new-line characters
The source of the $addy value starts out like this
$addresses = file('files/addresses.csv');
I then goes through
foreach ($addresses as $addy) {}
When I escape the $addy string, it's escaping the new line chars and inserting "\r\n" on the end of the comparison string.
As soon as I dropped those chars with string_replace() after escaping, everything went swimmingly
Thanks-a-BUNCH for the help
I'm still learning about SQL injection, but always the best way for me was using examples, so this is part of my code:
$sql = "INSERT INTO `comments` (`id`, `idpost`, `comment`, `datetime`, `author`, `active`)
VALUES (NULL, '" . addslashes($_POST['idcomment']) . "', '" .
addslashes($_POST['comment']) . "', NOW(), '" .
addslashes($_POST['name']) . "', '1');";
mysql_query($sql);
Knowing that all the POST vars are entered by the user, can you show me how can i make an injection to this script? so i can understand more about this vulnerability. Thanks!
my database server is MySQL.
Don't use addslashes(), always use mysql_real_escape_string(). There are known edge cases where addslashes() is not enough.
If starting something new from scratch, best use a database wrapper that supports prepared statements like PDO or mysqli.
Most of the other answers seem to have missed the point of this question entirely.
That said, based on your example above (and despite your code not following the best practice use of mysql_real_escape_string()) it is beyond my ability to inject anything truly detrimental when you make use of addslashes().
However, if you were to omit it, a user could enter a string into the name field that looks something like:
some name'; DROP TABLE comments; --
The goal is to end the current statement, and then execute your own. -- is a comment and is used to make sure nothing that would normally come after the injected string is processed.
However (again), it is my understanding that MySQL by default automatically closes the DB connection at the end of a single statement's execution. So even if I did get so far as to try and drop a table, MySQL would cause that second statement to fail.
But this isn't the only type of SQL injection, I would suggest reading up some more on the topic. My research turned up this document from dev.mysql.com which is pretty good: http://dev.mysql.com/tech-resources/articles/guide-to-php-security-ch3.pdf
Edit, another thought:
Depending on what happens to the data once it goes to the database, I may not want to inject any SQL at all. I may want to inject some HTML/JavaScript that gets run when you post the data back out to a webpage in a Cross-Site Scripting (XSS) attack. Which is also something to be aware of.
As said before, for strings, use mysql_real_escape_string() instead of addslashes() but for integers, use intval().
/* little code cleanup */
$idcomment = intval($_POST['idcomment']);
$comment = mysql_real_escape_string($_POST['comment']);
$name = mysql_real_escape_string($_POST['name']);
$sql = "INSERT INTO comments (idpost, comment, datetime, author, active)
VALUES ($idcomment, '$comment', NOW(), '$name', 1)";
mysql_query($sql);
Addslashes handles only quotes.
But there are some more important cases here:
Be careful on whether you use double or single quotes when creating the string to be escaped:
$test = 'This is one line\r\nand this is another\r\nand this line has\ta tab';
echo $test;
echo "\r\n\r\n";
echo addslashes($test);
$test = "This is one line\r\nand this is another\r\nand this line has\ta tab";
echo $test;
echo "\r\n\r\n";
echo addslashes($test);
Another one:
In particular, MySQL wants \n, \r and \x1a escaped which addslashes does NOT do. Therefore relying on addslashes is not a good idea at all and may make your code vulnerable to security risks.
And one more:
Be very careful when using addslashes and stripslashes in combination with regular expression that will be stored in a MySQL database. Especially when the regular expression contain escape characters!
To store a regular expression with escape characters in a MySQL database you use addslashes. For example:
$l_reg_exp = addslashes( �[\x00-\x1F]� );
After this the variable $l_reg_exp will contain: [\\x00-\\x1F].
When you store this regular expression in a MySQL database, the regular expression in the database becomes [\x00-\x1F].
When you retrieve the regular expression from the MySQL database and apply the PHP function stripslashes(), the single backslashes will be gone!
The regular expression will become [x00-x1F] and your regular expression might not work!
Remember, that the magic may happen in:
addslashes which may miss something
before adding to database
after retrieving from database
Your example is just an excerpt. The real problem might not be visible here yet.
(based on comments from php.net which are very often more valuable than the manual itself )
I'm not sure why this has stumped me. I have the following code
$website = "http://www.google.com";
$name = "Person";
if(!empty($website) {
$name = "[url=$website]$name[/url]";
}
Then i try to insert that into mysql. I tried adding mysql_real_escape_string to both $website and $name (after the if statement), thinking the "/url" might also cause problems.
$name = mysql_real_escape_string($name);
Still no luck though. Any advice? What am I missing? It's giving me this error
"Parse error: syntax error, unexpected '/', expecting T_STRING or T_VARIABLE or T_NUM_STRING"
try
if(!empty($website)) {
$name = "[url={$website}]{$name}[/url]";
}
then use,
mysql_real_escape_string ($name);
This is a PHP syntax problem.
The parser thinks $name[ is the start of a array reference you have to add curly bracelets to tell the parser where the variable name starts and end:
"[url={$website}]{$name}[/url]"
There wont be any problem at all. When reading from database you should then put stripslashes() around your value.
e.g.
$query = "SELECT field FROM table";
$row = mysql_fetch_array(mysql_query($query));
echo(stripslashes($row['field']));
And your output will be the same like YOUR input.
Make sure you're quoting values you send into a query, like so:
$sql = "INSERT INTO table (column) VALUES ('$value')";
Whatever is in $value gets passed into the query. If you leave out the quotes, bad things may happen even if you use mysql_real_escape_string(). Inside strings, forward slashes do not have any special meaning in MySQL, and so mysql_real_escape_string() leaves them intact. This is not a bug, but the documented, correct behaviour. Basically, you need to quote all values in your query.
However, the best solution IMHO is to use PDO and its parametrized queries instead of the mysql_XXX API. It's a bit more complicated (not much though), and it allows you to pass parameters into a query through an associative array, doing all the escaping and quoting you need for you.
Are you putting quotes around the value you want to insert? This will work
INSERT INTO table_name (column_name)
VALUES ('[url=$website]http://www.google.com[/url]')
This will fail
INSERT INTO table_name (column_name)
VALUES ([url=$website]http://www.google.com[/url])
So you might have in you php
$query = "INSERT INTO table_name (column_name) VALUES ('$name')";
// DO MYSQL_QUERY