Silently fails when truly prepared, works when emulated - php

For security purposes, I set ATTR_EMULATE_PREPARES option to false.
And in development environment, ATTR_ERRMODE is on ERRMODE_EXCEPTION.
But this code :
// $this->bdd is juste a regular PDO instance with some options
$req = $this->bdd->prepare('INSERT INTO users VALUES(NULL, :login, :passwd, :email, :firstname, :lastname, :role, :token_id, :confirmed, :registration_date, :last_connexion_date)');
$req->bindValue(':login', $login, PDO::PARAM_STR);
$req->bindValue(':passwd', $passwd, PDO::PARAM_STR);
$req->bindValue(':email', $email, PDO::PARAM_STR);
$req->bindValue(':firstname', $firstname, PDO::PARAM_STR);
$req->bindValue(':lastname', $lastname, PDO::PARAM_STR);
$req->bindValue(':role', $role, PDO::PARAM_INT);
$req->bindValue(':token_id', $token_id, PDO::PARAM_INT);
$req->bindValue(':confirmed', $confirmed, PDO::PARAM_BOOL);
$req->bindValue(':registration_date', $registration_date, PDO::PARAM_STR);
$req->bindValue(':last_connexion_date', $last_connexion_date, PDO::PARAM_STR);
return $req->execute() ? true : $req->errorInfo();
just fails silently, with in an errCode to 00000.
While browsing stackoverflow and other platforms, I found some similar bugs related to "truly prepared statement" which can be solved (doesn't work for me). I decided to turn on emulation, and it worked perfectly.
My problem : I want to keep truly prepared statements, and I don't know, what's wrong...
EDIT :
I just change from PDO to MySQLi for test purposes, MySQLi works, PDO don't (and still fails siltenty) here the scripts :
http://pastebin.com/jvjsfFVC
MySQLi always does truly prepared statement

Have the try catch between your code that way if we run into errors we can see the error array instead of blank.
try {
$req = $this->bdd->prepare('INSERT INTO users VALUES(NULL, :login, :passwd, :email, :firstname, :lastname, :role, :token_id, :confirmed, :registration_date, :last_connexion_date)');
$req->bindValue(':login', $login, PDO::PARAM_STR);
$req->bindValue(':passwd', $passwd, PDO::PARAM_STR);
$req->bindValue(':email', $email, PDO::PARAM_STR);
$req->bindValue(':firstname', $firstname, PDO::PARAM_STR);
$req->bindValue(':lastname', $lastname, PDO::PARAM_STR);
$req->bindValue(':role', $role, PDO::PARAM_INT);
$req->bindValue(':token_id', $token_id, PDO::PARAM_INT);
$req->bindValue(':confirmed', $confirmed, PDO::PARAM_BOOL);
$req->bindValue(':registration_date', $registration_date, PDO::PARAM_STR);
$req->bindValue(':last_connexion_date', $last_connexion_date, PDO::PARAM_STR);
$execute = $req->execute();
} catch (PDOException $error) {
print_r($error);
die();
}

Related

Someone kindly help me here: SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens

public function register($uname,$age,$sex,$image,$dpart,$joind,$job,$uposition,$phone,$umail,$upass,
$unumber,$address,$nssf,$bank,$passp,$home,$village,$nation,$permit)
{
try
{
$new_password = password_hash($upass, PASSWORD_DEFAULT);
$stmt = $this->conn->prepare("INSERT INTO users(user_name,birth,gender,image,job_title,curr_position,telephone,department,joining_date,user_email,user_pass,box_number,residence,nssf_number,bank_account,passport_number,home_district,village,nationality,work_permit)
VALUES(:uname,:age,:sex,:image,:dpart,:joind,:job,:uposition,:phone,:umail,:upass,:unumber,:nssf,:bank,:passp,:home,:village,:nation,:permit)");
$stmt->bindparam(":uname",$uname);
$stmt->bindparam(":age",$age);
$stmt->bindparam(":sex",$sex);
$stmt->bindparam(":image",$image);
$stmt->bindparam(":dpart",$dpart);
$stmt->bindparam(":joind",$joind);
$stmt->bindparam(":job",$job);
$stmt->bindparam(":uposition",$uposition);
$stmt->bindparam(":phone",$phone);
$stmt->bindparam(":umail",$umail);
$stmt->bindparam(":upass",$new_password);
$stmt->bindparam(":unumber",$unumber);
$stmt->bindparam(":address",$address);
$stmt->bindparam(":nssf",$nssf);
$stmt->bindparam(":bank",$bank);
$stmt->bindparam(":passp",$passp);
$stmt->bindparam(":home",$home);
$stmt->bindparam(":village",$village);
$stmt->bindparam(":nation",$nation);
$stmt->bindparam(":permit",$permit);
$stmt->execute();
return $stmt;
}
catch(PDOException $e)
{
echo $e->getMessage();
}
}
I'm posting this as a community wiki answer, since there shouldn't be any rep from this, nor do I want rep from it; given an answer that can't determine which one is missing.
It's the one for $stmt->bindparam(":address",$address); that is missing in the VALUES().
Also make sure that all variables do contain value.
PHP's error reporting will be of help:
http://php.net/manual/en/function.error-reporting.php
Side note: Using a code editor that automatically finds matching words when double-clicked and using the same naming convention would have helped you greatly.
One (free) of which that has option, is Notepad++.
Your sql statement is inconsistent: the table columns and the values
to insert don't correspond. For example, in a curr_position field
you are trying to insert a value of :joind, etc.
Also, in terms of number, the columns and the values to insert don't
coincide: 19 values to insert in 20 fields.
Recommendations:
My recommendation would be to always use column names for the marker names. Then you know exactly to which markers you are inserting the corresponding values.
NB: Markers: "...VALUES (:marker1, :marker2, ...);".
You should also define the type of input parameteres that you are binding. Example:
$stmt->bindparam(":age", $age, PDO::PARAM_INT);
Try to maintain some consistency between the function parameters and the field names, if it's possible and... makes sense.
My code proposal would look like this:
<?php
public function register(
$userName
, $birth
, $gender
, $image
, $jobTitle
, $currPosition
, $telephone
, $department
, $joiningDate
, $userEmail
, $userPass
, $boxNumber
, $residence
, $nssfNumber
, $bankAccount
, $passportNumber
, $homeDistrict
, $village
, $nationality
, $workPermit
) {
try {
$newUserPassword = password_hash($userPass, PASSWORD_DEFAULT);
$stmt = $this->conn->prepare('INSERT INTO users (
user_name,
birth,
gender,
image,
job_title,
curr_position,
telephone,
department,
joining_date,
user_email,
user_pass,
box_number,
residence,
nssf_number,
bank_account,
passport_number,
home_district,
village,
nationality,
work_permit
) VALUES (
:user_name,
:birth,
:gender,
:image,
:job_title,
:curr_position,
:telephone,
:department,
:joining_date,
:user_email,
:user_pass,
:box_number,
:residence,
:nssf_number,
:bank_account,
:passport_number,
:home_district,
:village,
:nationality,
:work_permit
)');
$stmt->bindparam(":user_name", $userName, PDO::PARAM_STR);
$stmt->bindparam(":birth", $birth, PDO::PARAM_INT);
$stmt->bindparam(":gender", $gender, PDO::PARAM_STR);
$stmt->bindparam(":image", $image, PDO::PARAM_STR);
$stmt->bindparam(":job_title", $jobTitle, PDO::PARAM_STR);
$stmt->bindparam(":curr_position", $currPosition, PDO::PARAM_STR);
$stmt->bindparam(":telephone", $telephone, PDO::PARAM_STR);
$stmt->bindparam(":department", $department, PDO::PARAM_STR);
$stmt->bindparam(":joining_date", $joiningDate, PDO::PARAM_STR);
$stmt->bindparam(":user_email", $userEmail, PDO::PARAM_STR);
$stmt->bindparam(":user_pass", $newUserPassword, PDO::PARAM_STR);
$stmt->bindparam(":box_number", $boxNumber, PDO::PARAM_INT);
$stmt->bindparam(":residence", $residence, PDO::PARAM_STR);
$stmt->bindparam(":nssf_number", $nssfNumber, PDO::PARAM_INT);
$stmt->bindparam(":bank_account", $bankAccount, PDO::PARAM_STR);
$stmt->bindparam(":passport_number", $passportNumber, PDO::PARAM_STR);
$stmt->bindparam(":home_district", $homeDistrict, PDO::PARAM_STR);
$stmt->bindparam(":village", $village, PDO::PARAM_STR);
$stmt->bindparam(":nationality", $nationality, PDO::PARAM_STR);
$stmt->bindparam(":work_permit", $workPermit, PDO::PARAM_STR);
$stmt->execute();
return $stmt;
} catch (PDOException $e) {
echo $e->getMessage();
}
}
Good luck!
Thank you all for your efforts and input i figured out the problem actually was this one:
$stmt->bindParam("userPass", $newUserPassword, PDO::PARAM_STR);
which had to be changed to this:
$stmt->bindParam("userPass", $userPass, PDO::PARAM_STR);
I was trying to use a parameter that i had not defined all because i di this:
$newUserPassword = password_hash($userPass, PASSWORD_DEFAULT);
So I thought of replacing it in the bindParameters....Hope it helps other!

Reversing AES_ENCRYPT Difficulties

I am consistently receiving null whenever I try to reverse the cipher text that I store in a MySQL database through PHP.
The PHP code used to insert the data:
public function insertChildren($employeeID, $empData, $key, $childName, $childBirth, $childGender, $childSSN, $isStep, $isFoster, $isStudent, $isHandicap, $address) {
$conn = $this->connect('insurance');
$insertChildren = $conn->prepare('INSERT INTO dependent_children (emp_id, ssn, name, dob, gender, handicap, student, foster, step, address) VALUES (:emp_id, AES_ENCRYPT(:ssn, AES_ENCRYPT(:key, UNHEX(sha1(:empData)))), :name, :dob, :gender, :handicap, :student, :foster, :step, :address)');
$insertChildren->bindParam(":emp_id", $employeeID, PDO::PARAM_INT);
$insertChildren->bindParam(":name", $childName, PDO::PARAM_STR);
$insertChildren->bindParam(':dob', $childBirth, PDO::PARAM_STR);
$insertChildren->bindParam(':empData', $empData, PDO::PARAM_STR);
$insertChildren->bindParam(':gender', $childGender, PDO::PARAM_STR);
$insertChildren->bindParam(':key', $key);
$insertChildren->bindParam(':ssn', $childSSN, PDO::PARAM_LOB);
$insertChildren->bindParam(':handicap', $isHandicap, PDO::PARAM_STR);
$insertChildren->bindParam(':student', $isStudent, PDO::PARAM_STR);
$insertChildren->bindParam(':foster', $isFoster, PDO::PARAM_STR);
$insertChildren->bindParam(':step', $isStep, PDO::PARAM_STR);
$insertChildren->bindParam(':address', $address, PDO::PARAM_STR);
$insertChildren->execute();
}
The SQL query that I thought would reverse it:
SELECT CAST(AES_DECRYPT(ssn, AES_DECRYPT('/ same random hexadecimal key bound in the php statement / ', unhex(sha1('1234')))) AS CHAR(50)) from dependent_children
Please note 1234 is the value that should be bound to the empData field in the PHP. I thought the latter query would correctly decrypt the first, but such is the case. Instead, I receive null. I am sure it is something simple, but I have not been able to locate the error source. Thanks so much!

filtered/sanitised form textarea causes MySQL insert to fail

I'm using the below prepared statement to submit data from a form via post
the user data has been filtered and sanitised. using PHP filter functions However the insert into MySQL fails on inserting the "Address" value which comes from a text area form input. I've tried various versions of the data and it seems that any input with newlines "\n\t\r" fails as well as their HTML encoded equivalents. I didn't think these were problamatic for MySQL? Am I missing the obvious?
Thanks
PS follows:
//DB_Connection
$SP1 = 'call account_register(:Title, :Name, :Surname, :Email, :Mobile, :Password, :Status, :LoginIP, :Token, :TokenExpiry, :Company, :BuildingNumber, :Address, :Street, :City, :County, :PostCode, :ReturnStatus)';
$Statement = $DBConnection->prepare($SP1);
#Bind parameters
$Statement->bindParam(':Title', $_UserData['Title'], PDO::PARAM_STR);
$Statement->bindParam(':Name', $_UserData['Name'], PDO::PARAM_STR);
$Statement->bindParam(':Surname', $_UserData['Surname'], PDO::PARAM_STR);
$Statement->bindParam(':Email', $_UserData['Email'], PDO::PARAM_STR);
$Statement->bindParam(':Mobile', $_UserData['Mobile'], PDO::PARAM_STR);
$Statement->bindParam(':Password', $_UserData['Password'], PDO::PARAM_LOB);
$Statement->bindParam(':Status', $_UserData['UserStatus'], PDO::PARAM_INT);
$Statement->bindParam(':LoginIP', $_UserData['LoginIP'], PDO::PARAM_STR);
$Statement->bindParam(':Token', $_UserData['ActivationToken'], PDO::PARAM_LOB);
$Statement->bindParam(':TokenExpiry', $_UserData['TokenExpiry'], PDO::PARAM_STR);
$Statement->bindParam(':Company', $_UserData['Company'], PDO::PARAM_STR);
$Statement->bindParam(':BuildingNumber', $_UserData['BuildingNumber'], PDO::PARAM_STR);
//$Statement->bindParam(':Address', $_UserData['Address'], PDO::PARAM_STR);
//$Address = 'line 1
line 2'; //This is the value of $_USERData after using FILTER_SANITIZE_SPECIAL_CHARS insert fails
//$Address = 'Line 1'; //after changing the value of the $_UserData to this the insert is successful
//$Address = 'line 1
line 2'; //After extracting from the $_UserData This fails
$Address = 'Line 1
line 2
line 3'; //This fails. I thought newlines were ok?
$Statement->bindParam(':Address', $Address, PDO::PARAM_STR);
$Statement->bindParam(':Street', $_UserData['Street'], PDO::PARAM_STR);
$Statement->bindParam(':City', $_UserData['City'], PDO::PARAM_STR);
$Statement->bindParam(':County', $_UserData['County'], PDO::PARAM_STR);
$Statement->bindParam(':PostCode', $_UserData['PostCode'], PDO::PARAM_STR);
$ReturnStatus = null; //Return variable for SP must be defined
$Statement->bindParam(':ReturnStatus', $ReturnStatus, PDO::PARAM_INT | PDO::PARAM_INPUT_OUTPUT, 1);
$Statement->execute();
Well finally got to the bottom of the problem. retyping the line calling the SP solved it.
I do copy and paste a lot so maybe some miscellaneous unprintable chars got in that line. That's the only thing I can think as my retype is exactly the same...

PHP Session with MySQL Insert Into using bind_parm

I am simply trying to insert the variable from a session into a MySQL database and it causes it to fail. var_dump shows SESSIONS all there. No problem there. Why doesn't this work?
$job = $_SESSION['job'];
$user_id = '1';
$name = 'allie';
$stmt = $mysqli->prepare("INSERT INTO
requests(name,job_info,user_id)
VALUES (?,?,?)");
$stmt->bind_param('sss', $name, $job, $user_id);
$stmt->execute();
see pdo bind_param
your parameter is incorrect:
change this:
$stmt->bind_param('sss', $name, $job, $user_id);
with this:
$stmt->bind_param(1, $name, PDO::PARAM_STR);
$stmt->bind_param(2, $job, PDO::PARAM_STR);
$stmt->bind_param(3, intval($user_id), PDO::PARAM_INT);

MSSQL store procedure is executing twice in PHP PDO

I have this block of code which getting executed twice
when the post hits from the payment gateway.Any help will be welcome
on this issue. I have already checked the code there is no 404 resuest
to any script.
$stmt = $dbAdapter->prepare('EXEC MyProcedure ?,?,?,?,?,?,?,?');
$stmt->bindParam(1,$id, PDO::PARAM_INT);
$stmt->bindParam(2,$Transaction, PDO::PARAM_STR);
$stmt->bindParam(3,$Person_id, PDO::PARAM_STR);
$stmt->bindParam(4,$Amount);
$stmt->bindParam(5,$OrderID, PDO::PARAM_STR);
$stmt->bindParam(6,$BankClientID, PDO::PARAM_STR);
$stmt->bindParam(7,$Transaction_Time, PDO::PARAM_STR);
$stmt->bindParam(8,$status, PDO::PARAM_INT);
$id = $stmt->execute();

Categories