I am trying to insert $_COOKIE['PHPSESSID'] in db with pdo, but i am having issue, can somebody help out?
here is the db table design : db table name: unregistered_customer_orders
session_id (int)
sel_article_id (varchar, 32)
sel_article_qty(smallint)
sel_article_color(varchar)
sel_article_size(varchar)
order_date(datetime)
HERE IS THE CODE
session_start();
try {
include_once'../includes/connect.inc.php';
$q ="INSERT INTO unregistered_customer_orders SET
session_id = $_COOKIE['PHPSESSID'] ,
sel_article_id = :sel_article_id,
sel_article_qty =:sel_article_qty,
sel_article_color = :sel_article_color,
sel_article_size = :sel_article_size,
order_date = NOW()";
$stm = $pdo->prepare($q);
$stm->bindValue(':sel_article_id', $sel_article_id);
$stm->bindValue(':sel_article_qty', $sel_article_qty);
$stm->bindValue(':sel_article_color', $sel_article_color);
$stm->bindValue(':sel_article_size', $sel_article_size);
$stm->execute();
if ($stm) {
echo "Insert";
exit();
}
else{
echo "Insert failed";
exit();
}
} catch (PDOException $e) {
echo "sth got wrong with the insert".$e->getMessage();
}
Your code has a serious SQL injection problem!
You inject unescaped SQL code into the query - or at least are trying to do so, from the cookie.
The cookie variable should go into the bindValue part just like everything else. Create a new variable name that goes into the prepared statement part, and bind the cookie value to it.
Note that PHP can be configured to use a different name for the session cookie! You don't have to access the $_COOKIE variable after you started the session, you can simply call the session_id() function to get the currently used session id.
Before using session_start(), the configured cookie name can be read by calling session_name(). Don't hardcode the cookie name into your code - it will create hard to debug errors when a new server has a different configuration.
Related
I have a button in a webapp that allows users to request a specially formatted number. When a user click this button 2 scripts run. The first that is fully functional, looks at a number table finds the largest number and increments it by 1. (This is not the Primary Key) the second script which is partially working gets the current date and runs a SQL query to get which period that date falls in. (Periods in this case not always equaling a full month) I know this script is at least partially working because I can access the $datetoday variable called in that script file. However it is not returning the requested data from the periods table. Anyone that could help me identify what I am doing wrong?
<?php
include 'dbh.inc.php';
$datetoday = date("Ymd");
$sql = "SELECT p_num FROM periods where '$datetoday' BETWEEN p_start AND p_end";
$stmt = mysqli_stmt_init($conn);
if(!mysqli_stmt_prepare($stmt, $sql)) {
header("Location: ../quote.php?quotes=failed_to_write");
exit();
} else {
mysqli_stmt_execute($stmt);
mysqli_stmt_store_result($stmt);
$result = mysqli_stmt_get_result($stmt);
$row = mysqli_fetch_assoc($result);
$pnum = $row;
mysqli_stmt_close($stmt);
}
If it helps any one I published my code to https://github.com/cwilson-vts/Quote-Appliction
So first off, I do not use msqli and never learned it. However, I believe I get the gist of what you want to do. I use PDO because I FEEL that it is easier to use, easier to read and it's also what I learned starting off. It's kinda like Apple vs. Samsung... no one product is exactly wrong or right. And each have their advantages and disadvantages. What I'm about to provide you will be in PDO form so I hope that you will be able to use this. And if you can't then no worries.
I want to first address one major thing that I saw and that is you interlacing variables directly into a mysql statement. This is not considered standard practice and is not safe due to sql injections. For reference, I would like you to read these sites:
http://php.net/manual/en/security.database.sql-injection.php
http://php.net/manual/en/pdo.prepared-statements.php
Next, I'm noticing you're using datetime as a variable name. I advise against this as this is reserved in most programming languages and can be tricky. So instead, I am going to change it something that won't be sensitive to it such as $now = "hello world data";
Also I'm not seeing where you would print the result? Or did you just not include that?
Another thing to consider: is your datetime variable the same format as what you are storing in your db? Because if not, you will return 0 results every time. Also make sure it is the right time zone too. Because that will really screw with you. And I will show you that in the code below too.
So now on to the actual code! I will be providing you with everything from the db connection code to the sql execution.
DB CONNECTION FILE:
<?php
$host = '127.0.0.1';
$user = 'root';
$pw = '';
$db = 'test'; // your db name here (replace 'test' with whatever your db name is)
try {
// this is the variable will call on later in the main file
$conn = new PDO("mysql:host=$host;dbname=$db;", $user, $pw);
} catch (PDOException $e) {
// kills the page and returns mysql error
die("Connection failed: " . $e->getMessage());
}
?>
The data file:
<?php
// calls on the db connection file
require 'dbconfig.php';
// set default date (can be whatever you need compared to your web server's timezone). For this example we will assume the web server is operating on EST.
date_default_timezone('US/Eastern');
$now = date("Ymd");
// check that the $now var is set
if(isset($now)) {
$query = $conn->prepare("SELECT p_num FROM periods WHERE p_start BETWEEN p_start AND :now AND p_end BETWEEN p_end AND :now");
$query->bindValue(':now', $now);
if($query->execute()) {
$data = $query->fetchAll(PDO::FETCH_ASSOC);
print_r($data); // checking that data is successfully being retrieved (only a troubleshooting method...you would remove this once you confirm it works)
} else {
// redirect as needed and print a user message
die("Something went wrong!");
}
$query->closeCursor();
}
?>
Another thing I want to mention is that make sure you follow due process with troubleshooting. If it's not working and I'm not getting any errors, I usually start at the querying level first. I check to make sure my query is executing properly. To do that, I go into my db and execute it manually. If that's working, then I want to check that I am actually receiving a value to the variable I'm declaring. As you can see, I check to make sure the $now variable is set. If it's not, that block of code won't even run. PHP can be rather tricky and finicky about this so make sure you check that. If you aren't sure what the variable is being set too, echo or print it with simply doing echo $now
If you have further questions please let me know. I hope this helps you!
I think I know what I was doing wrong, somebody with more PHP smarts than me will have to say for sure. In my above code I was using mysqli_stmt_store_result I believe that was clearing my variable before I intended. I changed that and reworked my query to be more simple.
<?php
include 'dbh.inc.php';
$datetoday = date("Ymd");
$sql = "SELECT p_num FROM periods WHERE p_start <= $datetoday order by p_num desc limit 1";
$stmt = mysqli_stmt_init($conn);
if(!mysqli_stmt_prepare($stmt, $sql)) {
header("Location: ../quote.php?quotes=failed_to_write");
exit();
} else {
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
while( $row = mysqli_fetch_assoc($result)) {
$pnum = $row['p_num'];
echo $pnum;
}
mysqli_stmt_close($stmt);
}
Thanks to #rhuntington and #nick for trying to help. Sorry I am such an idiot.
I want to delete some rows from my table. But when I click delete, this just show me a blank page. I'm sure about id value and my db connection.
This is my code:
// connect to the database
include('connect-db.php');
// confirm that the 'id' variable has been set
if (isset($_GET['id']) && is_numeric($_GET['id'])) {
// get the 'id' variable from the URL
$id = $_GET['id'];
// delete record from database
if ($stmt = $mysqli->prepare("DELETE FROM my_table WHERE id = ? LIMIT 1")) {
$stmt->bind_param("i",$id);
$stmt->execute();
$stmt->close();
} else {
echo "ERROR: could not prepare SQL statement.";
}
$mysqli->close();
// redirect user after delete is successful
header("Location: Dashboard.php");
} else {
// if the 'id' variable isn't set, redirect the user
header("Location: Dashboard.php");
}
There is a similar question MySQLi Prepared Statement not executing
. Basically, you can try running the SQL directly in the database to see if you get any errors. Also confirm that the database user has delete permissions and that the id is stored as an integer in your database.
First I'd suggest you use the $_POST method, you can read more about it GET vs. POST.
Try using bindValue() instead of bindParam(), I believe something else needs to be declared for bindParam() I forget (I'm new at PHP too).
Logging in we of course have set the $_SESSION['username'] and $_SESSION['password'] as usual. However I am then trying to pack that into a variable for use around the site:
$logged = mysql_query("SELECT * FROM `users` WHERE `username`='$_SESSION['username']' AND password = '$_SESSION['password']'");
$logged = mysql_fetch_array($logged);
One previous setups, this has enabled me to then use $logged around the site for various reasons, such as calling the logged in users email to echo in a form,
However, this time, when using this method, it fails to echo anything. I have tried using the session username variable which works to echo the username, but then I tried using the session to echo the email and it didn't work.
If someone could help me pinpoint why this is, I'd be grateful.
It just doesn't seem to be pulling any information from the user as it should.
For me this just seems like an escape-thing. Try
$logged = mysql_query("SELECT * FROM users WHERE username='".$_SESSION['username']."' AND password = '".$_SESSION['password']."'");
$logged = mysql_fetch_array($logged);
Also make sure to call session_start(); before sending any headers/echoing anything if you weren't aware.
Off topic-tip
As long as this query isn't used in anything public, it's fine. But if you're gonna use this code for anything, be sure to slash your query variables. If not, and if my credentials are not validated nor hashed, you could do some nasty SQL injection by setting your password to be something like '; DELETE * FROM USERS;# as the query would then say SELECT * FROM users WHERE username='JohnDoe' AND password = ''; DELETE * FROM USERS;#'
for the usage of session
if(!session_id())
session_start();
the above session start is a must in every page.
use print_r($_SESSION); to check the session variables initialized..
once done (try using mysqli insted of mysql)
$sql='SELECT col1, col2, col3 FROM table1 WHERE condition';
$rs=$conn->query($sql);
if($rs === false) {
trigger_error('Wrong SQL: ' . $sql . ' Error: ' . $conn->error, E_USER_ERROR);
} else {
$arr = $rs->fetch_all(MYSQLI_ASSOC);
}
foreach($arr as $row) {
echo $row['co1'];
}
comment your progress for further changes..
Example:
Database Connect and Filter
//Initialize MySQLi connection
$db = new mysqli($_CONFIG['mysql']['hostname'], $_CONFIG['mysql']['username'], $_CONFIG['mysql']['password'], $_CONFIG['mysql']['database']);
if ($db->connect_errno) {
die("MySQLi error: ".$db->connect_error);
}
//filter injections
function filter($var)
{
global $db;
return $db->real_escape_string(stripslashes(htmlspecialchars($var)));
}
Set cookie after a successful login, check cookie and re-update each time
if(login) {
// after successful login
$cookiehash = md5(sha1($_SESSION['user_id'] . $recentIP));
$db->query('UPDATE users SET loginHash = "'.filter($cookiehash).'" WHERE id = '.filter($_SESSION['user_id']).'') or die(mysqli_error($db));
setcookie("customCookie",$cookiehash,time()+3600*24*365,'/','.'.$_SERVER['HTTP_HOST'].'');
}
// if the cookie is set, update expiration and set session id
CheckCookieLogin() {
global $db;
if (!empty($_COOKIE['customCookie'])) {
$cookie = $_COOKIE['customCookie'];
$query = $db->query('SELECT * FROM users WHERE loginHash = "'.filter($cookie).'"');
if($query->num_rows > 0) {
$_SESSION['user_id'] = 1;
// reset expiry date
setcookie("customCookie",$cookie,time()+3600*24*365,'/','.'.$_SERVER['HTTP_HOST'].'');
}
}
}
Would this still be vulnerable to any sort of injection attack?
The cookie is stored on the client's computer, and thus vurnerable to attack. So called 'Cookie Poisoning attacks'. So treat the content with care. This is what you seem to do with your filter() routine.
It can still be improved however. What if you could check whether the cookie has been modified, without having to access your database? This might seem more difficult than it is.
A simple method is adding some sort of checksum to the content of the cookie, something you can check but is not obvious to the hacker. The hacker would first have to figure out what you're doing, before he, or she, can even start to change the data that enters your SQL statement. It is the difference between accepting any content from the cookie and put it in an SQL statement, or only accepting content which you can verify not to have been modified.
I'm trying to insert the current date/time to the database as the last time the user logged in. For some reason this doesn't work.
Other insertion scripts running on the very same page work well, and the connection is ok.
I use the same syntax to insert other stuff throughout the whole site, so I don't get what's wrong.
I can guarantee that the else part is being executed when I'm entering my password.
Here's the piece of code I am talking about.
if(!$pwVer){
// code to execute if the password is incorrect.
} else {
$dateT = date("Y-m-d H:i:s");
$up_date = $con->prepare("INSERT INTO tbl_user_test (user_last_login) VALUES (:l_login)");
$up_date->bindParam(':l_login', $dateT);
$up_date->execute();
validateUser($userid); //sets the session data for this user
header("Location: cart.php");
$con = null;
die();
}
Some background:
$pwVer returns `true` if the password is correct.
both `tbl_user_test` and `user_last_login` are written exactly as they're in the database.
Thanks in advance!
I'm trying to insert the current date/time to the database as the last time the user logged in. For some reason this doesn't work.
There is no error visible in your code, so it should be executed. One possible problem could be that PDO is in silent mode, which doesn't tell you what or if an error has occured. Set PDO to fail with an exception.
Also, there's no need to construct the current date yourself; you can use SQL's NOW().
<?php
$con->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
try {
$up_date = $con->prepare("INSERT INTO tbl_user_test (user_last_login) VALUES (NOW());");
$up_date->execute();
}
catch( Exception $e ) {
echo $e; exit;
}
header("Location: cart.php");
$con = null;
die();
Did you try NOW() for the current date time ?
Once check with this
$up_date->bindParam(':l_login', $dateT, PDO::PARAM_STR);