Don't quite understand SQL injection - php

I have read a lot about sql injection and I understand how it could cause problems (ie: DROP TABLE __ etc). But I am unsure how the tutorials I have followed actually prevent this from happening. I am just learning PDO and I think I understand it.
Is this code safe from SQL injection? and why is it? (It takes quite a bit more work using these prepared statements so I want to be sure I am not just wasting my time - also if the code can be improved please let me know!)
$conn = new PDO("mysql:host=$DB_HOST;dbname=$DB_DATABASE",$DB_USER,$DB_PASSWORD);
// Get the data
$firstname = $_POST["v_firstname"];
$lastname = $_POST["v_lastname"];
$origincountry = $_POST["v_origincountry"];
$citizenship = $_POST["v_citizenship"];
$gender = $_POST["v_gender"];
$dob = $_POST["v_dob"];
$language = $_POST["v_language"];
$landing = $_POST["v_landing"];
$email = $_POST["v_email"];
$phone = $_POST["v_phone"];
$cellphone = $_POST["v_cellphone"];
$caddress = $_POST["v_caddress"];
$paddress = $_POST["v_paddress"];
$school = $_POST["v_school"];
$grade = $_POST["v_grade"];
$smoker = $_POST["v_smoker"];
$referred = $_POST["v_referred"];
$notes = $_POST["v_notes"];
//Insert Data
$sql = "INSERT INTO clients (firstname, lastname, origincountry, citizenship, gender, dob, language, landing, email, phone, cellphone, caddress, paddress, school, grade, smoker, referred, notes)
VALUES (:firstname, :lastname, :origincountry, :citizenship, :gender, :dob, :language, :landing, :email, :phone, :cellphone, :caddress, :paddress, :school, :grade, :smoker, :referred, :notes)";
$q = $conn->prepare($sql);
$q->execute(array(':firstname'=>$firstname,
':lastname'=>$lastname,
':origincountry'=>$origincountry,
':citizenship'=>$citizenship,
':gender'=>$gender,
':dob'=>$dob,
':language'=>$language,
':landing'=>$landing,
':email'=>$email,
':phone'=>$phone,
':cellphone'=>$cellphone,
':caddress'=>$caddress,
':paddress'=>$paddress,
':school'=>$school,
':grade'=>$grade,
':smoker'=>$smoker,
':referred'=>$referred,
':notes'=>$notes));

Yes, the code is safe, as PDO will properly escape and quote the array of parameters for you.

Your code is safe from SQL injection because you're using paramaterized query, which basically means that once the query is being built and sent to the sql server, it's being escaped, same could be achieved by using php's built in function mysql_real_escape_string().
The following video is great informational video about sql injection from OWASP:
SQL Injection

The rule is: Do not construct sql by hand, in which you do something like:
sqlStatement = 'select field1, field2, field3 from mytable where index = '' + myVariable + ''
The above is dangerous, because if your app allows a user to pass data into myVariable, they could potentially send full SQL commands to your db server.
Using parameterized queries, as you do above, is the solution.

Related

Query not inserting data

trying to submit data from a form but does not seem to be working. Can't spot any problems?
//Include connect file to make a connection to test_cars database
include("prototypeconnect.php");
$proId = $_POST["id"];
$proCode = $_POST["code"];
$proDescr = $_POST["descr"];
$proManu = $_POST["manu"];
$proCPU = $_POST["cpu"];
$proWPU = $_POST["wpu"];
$proBarCode = $_POST["barcode"];
$proIngredients = $_POST["ingredients"];
$proAllergens = $_POST["allergenscon"];
$proMayAllergens = $_POST["allergensmay"];
//Insert users data in database
$sql = "INSERT INTO prototype.Simplex_List (id, code, descr, manu, cpu, wpu, barcode, ingredients, allergenscon, allergensmay)
VALUES ('$proId' , '$proCode', '$proDescr' , '$proManu' , '$proCPU' , '$proWPU' , '$proBarCode' , '$proIngredients' , '$proAllergens' , '$proMayAllergens')";
//Run the insert query
mysql_query($sql)
First and foremost, please do not use mysql_*** functions and please use prepared statements with
PDO http://php.net/manual/en/pdo.prepare.php
or mysqli http://php.net/manual/en/mysqli.quickstart.prepared-statements.php instead. Prepared statements help protect you against sql injection attempts by disconnecting the user submitted data from the query to the database.
You may want to try using mysql_real_escape_string http://php.net/manual/en/function.mysql-real-escape-string.php to ensure no stray " or ' is breaking your query.
$proId = mysql_real_escape_string($_POST["id"]);
$proCode = mysql_real_escape_string($_POST["code"]);
$proDescr = mysql_real_escape_string($_POST["descr"]);
$proManu = mysql_real_escape_string($_POST["manu"]);
$proCPU = mysql_real_escape_string($_POST["cpu"]);
$proWPU = mysql_real_escape_string($_POST["wpu"]);
$proBarCode = mysql_real_escape_string($_POST["barcode"]);
$proIngredients = mysql_real_escape_string($_POST["ingredients"]);
$proAllergens = mysql_real_escape_string($_POST["allergenscon"]);
$proMayAllergens = mysql_real_escape_string($_POST["allergensmay"]);
Additionally ensure your form is being submitted by calling var_dump($_POST) to validate the data
You can also see if the query is erroring by using mysql_error http://php.net/manual/en/function.mysql-error.php
if (!mysql_query($sql)) {
echo mysql_error();
}
advices about PDO, prepared statements were done.
1) Do you have a database and connection to it?
Look at your prototypeconnect.php and find database name there. check that its name and password is similar that u have.
2) Do you have a table named prototype.Simplex_List in your database?
a) IF YOU HAVE:
check if your mysql version >= 5.1.6
http://dev.mysql.com/doc/refman/5.1/en/identifiers.html
b) IF YOU HAVE BUT ITS NAME is Simplex_List:
b-1) if your database name IS NOT prototype:
replace your
$sql = "INSERT INTO prototype.Simplex_List
with
$sql = "INSERT INTO Simplex_List
b-2) if your database name IS prototype:
you should escape your $_POST data with mysql_real_escape_string as #fyrye said.
c) IF YOU HAVE NOT:
you should create it
3) Check your table structure
does it have all theese fields id, code, descr, manu, cpu, wpu, barcode, ingredients, allergenscon, allergensmay?
if you have there PRIMARY or UNIQUE keys you should be sure you are not inserting duplicate data on them
but anyway replace your
$sql = "INSERT INTO
with
$sql = "INSERT IGNORE INTO
PS: its not possible to help you without any error messages from your side

How to insert Integer value in DB - PHP

I have using PHP for inserting integer value in Database.
Iam using like this
$postcode = $_POST['postcode'];
$mysql_user_resultset = mysqli_query($con, "INSERT into user (postcode) VALUES ($postcode)");
I have several field in DB. like name, username, etc. all are defined as varchar, but postcode only defined as int. If not enter the value for postcode, it doesn't insert into database
You could simply cast your variable into int:
$postcode = (int) $_POST['postcode'];
$mysql_user_resultset = mysqli_query($con, "INSERT into user (postcode) VALUES ($postcode)");
Note that you're not using any precautions regarding SQL injections, I would suggest you to bind your parameters before query them, using PDO class.
Convert $_POST['postcode'] to int, using
$postcode = (int)$_POST['postcode'];
Use PDO or sprintf for formatting mysql query:
sprintf example:
$mysql_user_resultset = mysqli_query($con, sprintf(
"INSERT into user (postcode) VALUES (%d)",
$_POST['postcode']));
PDO example:
$st = $db->prepare("INSERT into vendors user (postcode) VALUES (:postcode)");
$st->bindParam(':postcode', $_POST['postcode'], PDO::PARAM_INT);
$mysql_user_resultset = $st->execute();

Store Facebook users like

I'm working on an application but what i want to do is get the user likes and store it in my database
But when i try to save it in the database it won't insert it in my database
$likes = $facebook->api('/me/likes');
$fblikes = '';
foreach($likes['data'] as $like){
$fblikes .= $like['name'].', ';
}
$insert = "INSERT INTO users (name, email, gender, liked)
VALUES (
'$fbname',
'$fbemail',
'$fbgender',
'$fblikes'
)";
$add_bericht = mysql_query($insert);
But whenever i remove $fblikes from the insert sql it will insert into my database
Any idea's ?
I think there is an escaping problem in your query. You are (Very) susceptible to SQL Injection.
See this post on how to prevent it: How can I prevent SQL injection in PHP?

Form is submitting empty values to database

After being advised that i MUST validate my form so that no-one could hack my database i then made some changes which were adding the mysql_real_string()
$query="INSERT INTO allymccoist (id, firstname, lastname, email, date)
VALUES (NULL, '".$firstname."', '".$lastname."', '".$email."', '".mysql_real_escape_string($new_date)."')";
$firstname = mysql_real_escape_string($_POST['firstname']);
$lastname = mysql_real_escape_string($_POST['lastname']);
$email = mysql_real_escape_string($_POST['email']);
$datepicker = mysql_real_escape_string($_POST['date']);
since doing this, nothing is being sent to firstname lastname or email although the date seems to be sending ok though
is thereanything that may be causing this that you can see from my code?
If you're sure that those data actually are set (var_dump your $_POST array to check that),then make sure you have a connection active before using mysql_real_escape_string(), as it would return FALSE otherwise:
A MySQL connection is required before using mysql_real_escape_string()
otherwise an error of level E_WARNING is generated, and FALSE is
returned. If link_identifier isn't defined, the last MySQL connection
is used.
So you can well be entering FALSE in every value.
$link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password')or die(mysql_error());
mysql_select_db('database_name', $link) or die('cannot select database '.mysql_error());
$firstname = mysql_real_escape_string($_POST['firstname']);
$lastname = mysql_real_escape_string($_POST['lastname']);
$email = mysql_real_escape_string($_POST['email']);
$datepicker = mysql_real_escape_string($_POST['date']);
You'd be better off altogether by using prepared statements, so you won't have to worry about SQL injections.
Also, I'd advice you against using NULL in your insert query for the field ID. If you're table is strcutred as I can guess, and ID is a primary key with AutoIncrement, you don't need to enter it in your query, as it would be automatically filled by the engine.
For wheter it is better to use prepared statements or mysql_real_escape_string(), check this resource mysql_real_escape_string vs prepared statements
The issue of missing data is likely as Damien suggests. Establish a connection, then use mysql_real_escape_string(). The connection is required in part so that mysql_real_escape_string() can take into account the current character set of the connection.
Also, mysql_real_escape_string() is perfectly safe when used in combination with the sprintf() function (full details on sprintf). Most important with sprintf() is setting the correct type specifier so that values get cast properly. Generally, for integers you will use %d. For floats use %f. And for string and date values use %s.
So for your program the code should look something like (note: as Damien suggests, leave id out of the query):
/* Read form data. */
$firstName = $_POST['firstname'];
$lastName = $_POST['lastname'];
$email = $_POST['email'];
$date = $_POST['date']);
/* Your form validation code here. */
/* Your db connection code here. */
/* Setup and run your query. */
$query = sprintf("INSERT INTO allymccoist (firstname, lastname, email, date)
VALUES ('%s', '%s', '%s', '%s')",
mysql_real_escape_string($firstName),
mysql_real_escape_string($lastName),
mysql_real_escape_string($email),
mysql_real_escape_string($date));
$result = mysql_query($query);
/* Check for errors with query execution. */
if (!$result) echo("Query Error! Process aborted.");

What does this mean?

I found this in some code examples while googling :
$sql = 'INSERT INTO users (username,passwordHash) VALUES (?,?)';
it's new to me, but I would guess that it a substitution method and equivalent to
$sql = "INSERT INTO users (username,passwordHash) VALUES ($username,$passwordHash)";`
or
$sql = 'INSERT INTO users (username,passwordHash) VALUES (' . $username . ',' . $passwordHash . ')';`
would that be correct? Is it an actual PHP syntax, or was he just trying to simplify his example?
Thanks for the feedback, folks
This is pretty common in prepared statements. The ? merely serves as a placeholder, as seen below from the PHP documentation:
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (?, ?)");
$stmt->bindParam(1, $name);
$stmt->bindParam(2, $value);
// insert one row
$name = 'one';
$value = 1;
$stmt->execute();
// insert another row with different values
$name = 'two';
$value = 2;
$stmt->execute();
The question marks are placeholders for values in prepared SQL statements - and are an important protection against SQL Injection Attacks. Your first alternative would not work properly unless every user encloses their name in quotes* and you enclose the password hash in quotes. Your second alternative is vulnerable to SQL Injection Attacks.
With placeholders, you pass the values for the placeholders when you execute the SQL.
* And Tim O'Reilly knows he really has to type "'Tim O''Reilly'".
it's not the same. question marks are used for prepared statement queries. these basically allow you to run the same query multiple times while only having the system parse the query once.

Categories