How To Fix SQL Injection in this code?
Thanks
function safeQuery($query) {
$db = new SQLite3(dirname(__FILE__) . "/private/database.db") or die ("Unable to open database");
SQLite3::escapeString($query);
$result = $db->query($query);
$row = $result->fetchArray();
$db->close();
return $row;
}
function areUserAndPasswordValid($user, $password) {
$query = "SELECT count(*) FROM userTable WHERE username = '$user' AND password = '$password'";
$row = safeQuery($query);
$count = $row[0];
return $count > 0;
}
function getFileList($user) {
$query = "SELECT fileId, filename, createdBy, owner FROM filesTable WHERE owner = '$user'";
$db = new SQLite3(dirname(__FILE__) . "/private/database.db") or die ("Unable to open database");
$result = $db->query($query) or die ("Unable to execute query");
$rows = array();
while($row=$result->fetchArray()){
$rows[] = $row;
}
$db->close();
return $rows;
}
You should always use prepared statements rather than directly passing user input into your query.
Replace SELECT count(*) FROM userTable WHERE username = '$user' AND password = '$password' with something like this:
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)");
$stmt->bindParam(':name', $name);
$stmt->bindParam(':value', $value);
(That code snippet taken from http://php.net/manual/en/pdo.prepared-statements.php)
Prepared statements will prevent users from injecting SQL.
See How can I prevent SQL injection in PHP? for a bunch of other useful answers.
Related
I've got a problem with my PHP Registration Script that firstly checks, if the user exists.
It always outputs "false".
<?php
$username = $_GET['username'];
$passwort = $_GET['passwort'];
$database = #mysql_connect("***********", "********", "******") or die("Can't connect to the server. Error: ".mysql_error());
//$username = mysql_real_escape_string($username);
$passwort = hash("sha256", $passwort);
$numrows = mysql_query("SELECT * FROM *******.mikgames WHERE username='".$username."' LIMIT 1");
$checkuserexists = mysql_num_rows($numrows);
if($checkuserexists==0) {
$abfrage = mysql_query("INSERT INTO *******.mikgames (username,passwort) VALUES ('$username', '$passwort')");
echo'true';
}
else {
echo'false';
}
?>
Edit: Now I'am using MySQLi and I've changed the code into this:
<?php
$username = $_GET['username'];
$passwort = $_GET['passwort'];
$con = mysqli_connect('************','******','******') or die(mysqli_error());
mysqli_select_db($con, "*******") or die("cannot select DB");
$passwort = hash("sha256", $passwort);
$query = mysqli_query($con,"SELECT * FROM *******.mikgames WHERE username='".$username."'");
$result = mysqli_num_rows($query);
if($result==0) {
$abfrage = mysqli_query($con, "INSERT INTO ********.mikgames (username,passwort) VALUES ('$username', '$passwort')");
$result = mysqli_query($con,$abfrage);
echo 'true';
}
else {
echo 'false';
}
?>
And it works.
You could go one step better and take an OOP approach using the PDO driver; PDO invokes security by allowing secure parameter binding and uses the SQL preferred functions.
Inside your pdo_driver.php file:
namespace ProjectName\App\Drivers;
if(!defined('IN_PROJECTNAME'))
{
die('No Script Kiddies Please...');
}
interface EntityContainer
{
public function query($statement, array $values = array());
}
class Entity extends \PDO implements EntityContainer
{
public function __construct(
$dsn = 'mysql:host=XXXX;dbname=XXXX', $user = 'XXXX', $pass = 'XXXX'
) {
try {
parent::__construct($dsn,$user,$pass);
} catch (PDOException $ex) {
die('FATAL ERROR: ' . $ex->getMessage());
}
}
public function query(
$statement, array $values = array()
) {
$smpt = parent::Prepare($statement);
(empty($values)) ? $smpt->execute() : $smpt->execute($values);
return $smpt;
}
}
Inside any other php file:
define('IN_PROJECTNAME', 0);
require_once dirname(__FILE__) . '/path/to/pdo_driver.php';
$container = array();
$container['Connection'] = new ProjectName\App\Drivers\Entity();
$username = $_GET['username'];
$passwort = $_GET['passwort'];
if(empty($container['Connection']->query('SELECT passwort FROM ******.mikgames WHERE username = ?', [$username])->fetch()['passwort'])) {
$container['Connection']->query('INSERT INTO ******.mikgames (username,passwort) VALUES (?, ?)', [$username,$passwort]);
}
Two Factors:
Firt Factor
You need to add an error output for debugging purposes:
$query = mysqli_query($con,"SELECT * FROM <tablename> WHERE
username='".$username."'") or die(mysqli_error($con));
I can't see a clear error with the information you have displayed here so far so you should also check what the value of $username acutally is and how closely it fits the value in the DB. Also read and take on board what the error output tells you.
Second Factor:
Your problem is you're running/articulating a query twice, here:
if($result==0) {
$abfrage = mysqli_query($con, "INSERT INTO ********.mikgames
(username,passwort) VALUES ('$username', '$passwort')");
$result = mysqli_query($con,$abfrage);
You see $abfrage is a MySQL result object and you're then plugging it back into a MySQL query call, with the variable declaration $result. So your result is querying a query. This is an error.
What you probably want to do is use MySQLi_affected_rows to count how many rows have been inserted and run the appropriate IF clause:
if($result==0) {
$abfrage = mysqli_query($con, "INSERT INTO ********.mikgames
(username,passwort) VALUES ('$username', '$passwort')");
$result = mysqli_affected_rows($con);
echo 'true';
}
else {
echo 'false';
}
Use #mysql_***** for your ptoject.
$sql="SELECT * FROM table_name";
$result=#mysql_query($sql, $conn);
while ($name = # mysql_fetch_array($result)){
echo $name ['username'];
}
You just used simple mysql_***
i just want to know if this is possible. Establishing connection without using the doctrine setup.
private function userExist($username){
$con = Doctrine_Manager::getInstance()->getConnection('doctrine');
$sql = 'SELECT username FROM tbl_user WHERE username =\''.$username.'\'';
$stmt = $con->prepare($sql);
$stmt->execute();
//$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
$result = $stmt->fetchAll();
if(!empty($result)){
return true;
}else{
return false;
}
}
to
private function userExist($username){
$con = new PDO('pgsql:host=xx.xxx.xxx;dbname=support_tool','xx','xxx');
$sql = 'SELECT username FROM tbl_user WHERE username =\''.$username.'\'';
$stmt = $con->prepare($sql);
$stmt->execute();
//$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
$result = $stmt->fetchAll();
if(!empty($result)){
return true;
}else{
return false;
}
}
i just want to test it if it is possible. if not please tell me why, thanks for the help.
<?
session_start();
if(($connection = mysql_connect("localhost", "root", "")) == false)
die ("Couldn't connect to database");
if(mysql_select_db("Social", $connection) == false)
die ("Couldn't select db");
if (isset($_POST['username']) && isset($_POST['pass']) && isset($_POST['login'])){
$sql = sprintf("SELECT * FROM users WHERE username LIKE '%s' AND password LIKE '%s'", $_POST['username'], $_POST['pass']);
$query = mysql_query($sql);
if (mysql_num_rows($query) == 0){
$error = "<br />Wrong Username or Password";}
else{
$_SESSION['user'] = $_POST['username'];
header("Location: home1.php");
}
}
if (isset($_POST['register'])){
$sql2 = sprintf("INSERT INTO Social.users (username, password) VALUES (%s, %s)", $_POST['newUser'], $_POST['newPass']);
$query2 = mysql_query($sql2);
if (!$query2){
print "Registration failed";
}
else{
print "Registration sucessfull";
}
}
?>
My program is not inserting any data into mySQL table. I know all the syntax is right, everything should work out fine. I double checked on the command that mySQL uses in order to enter data into the table. Why is this not working? My query2 should be successful, but idk why its not.
Please help.
Thanks
to prevent sql injections, try mysqli or pdo
here is mysqli prepared statements version. However if you are trying to create user management system, I wouldn't recommend you do it. There are so many scripts which provide more security, http://www.usercake.com is a good user management system.
session_start();
$db = new mysqli('localhost', 'root', 'password', 'database');
if ($mysqli->connect_errno) {
echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}
if (isset($_POST['username'] && $_POST['pass'] && $_POST['login']))
{
$user_name = ''; //define these here.
$pass = '';
$stmt = $db->prepare("select * from users where username = ? and password = ?");
echo $db->error;//this will echo the error.
$stmt->bind_param('ss', $user_name, $pass);
$stmt->execute();
$result = $stmt->get_result();//get rows
if($result->num_rows < 1) //check if result is less than 1
{
$error = "<br />Wrong Username or Password";}
else{
$_SESSION['user'] = $_POST['username'];
header("Location: home1.php");
}
}
if (isset($_POST['register'])){
$uname = $_POST['newUser'];
$pass = $_POST['newPass'];
if(empty($uname))
{
echo "Please enter your username.";
}
elseif(empty($pass))
{
echo "Please enter your password.";
}
else{
$stmt = $db->prepare("insert into Social.users (username, password) values (?,?)");
echo $db->error;//this will echo the error.
$stmt->bind_param('ss', $uname, $pass);
$stmt->execute();
echo "You have successfully registered.";
}
}
The variables in the INSERT must be the username and password
$sql2 = sprintf("INSERT INTO Social.users (username, password) VALUES (%s, %s)", $_POST['username'], $_POST['pass']);
Use prepared statements and parameterized queries. These are SQL statements that are sent to and parsed by the database server separately from any parameters. This way it is impossible for an attacker to inject malicious SQL.
You basically have two options to achieve this:
Using PDO:
$stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name');
$stmt->execute(array('name' => $name));
foreach ($stmt as $row) {
// do something with $row
}
Using mysqli:
$stmt = $dbConnection->prepare('SELECT * FROM employees WHERE name =
?'); $stmt->bind_param('s', $name);
$stmt->execute();
$result = $stmt->get_result(); while ($row = $result->fetch_assoc()) {
// do something with $row }
Font: How can I prevent SQL injection in PHP?
its a little difficult to explain. I've build the mysql function which works fine and with the depreciation of mysql I will need to change this function to use mysqli rather than the mysql method.
I current have:
$con = mysql_connect("host", "username", "pass");
mysql_select_db("db", $con);
$Username = mysql_real_escape_string($_POST['user']);
$Password = hash_hmac('sha512', $_POST['pass'], '&R4nD0m^');
$Query = mysql_query("SELECT COUNT(*) FROM users WHERE username = '{$Username}' AND password = '{$Password}'") or die(mysql_error());
$Query_Res = mysql_fetch_array($Query, MYSQL_NUM);
if($Query_Res[0] === '1')
{
//add session
header('Location: newpage.php');
}
else {
echo 'failed login';
}
Now I've applied mysqli to this and it's not returning any data or errors but the function still complies.
$log = new mysqli("host", "user", "pass");
$log->select_db("db");
$Username = $log->real_escape_string($_POST['user']);
$Password = hash_hmac('sha512', $_POST['pass'], '&R4nD0m^');
$qu = $log->query("SELECT COUNT(*) FROM users WHERE username = '{$Username}' AND password = '{$Password}'");
$res = $qu->fetch_array();
if($res[0] === '1'){
//add session
header('Location: newpage.php');
}
else {
$Error = 'Failed login';
sleep(0.5);
}
echo $res['username'].' hello';
}
But I'm unsure on why this is wrong. I know it's probably a simply answer
Just to have it as an answer:
http://php.net/manual/en/pdo.prepared-statements.php
http://php.net/manual/en/pdo.prepare.php
e.g.
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)");
$stmt->bindParam(':name', $name);
$stmt->bindParam(':value', $value);
You may check if the connection is establishing before using real_escape_string()
if ($log->connect_errno) {
echo "Failed to connect to MySQL: (".$log->connect_errno.")".$log->connect_error;
}
afaik, there's no problem with $log->real_escape_string($_POST['user']);
I've been trying to convert a mysql_connect connection into a PDO connection with no success, here is what I have:
$host = 'localhost';
$user = 'root';
$pwd = '';
$db = 'jdlferreira';
$connection = mysql_connect($host, $user, $pwd) or die("Could not connect");
mysql_select_db($db) or die("Could not select database");
$query = "SELECT COUNT(*) FROM blog";
$result = mysql_query($query) or die(mysql_error());
$num_rows = mysql_fetch_row($result);
$pages = new Paginator;
$pages->items_total = $num_rows[0];
$pages->mid_range = 9; // Number of pages to display. Must be odd and > 3
$pages->paginate();
$query = "SELECT id, title, resume, date
FROM blog
ORDER BY date DESC $pages->limit";
$result = mysql_query($query) or die(mysql_error());
while ($row = mysql_fetch_row($result)) {
//do stuff
}
And what I tried to do with PDO:
include_once 'inc/db.inc.php';
$db = new PDO(DB_INFO, DB_USER, DB_PASS);
mysql_select_db("jdlferreira") or die("Could not select database");
$query = "SELECT COUNT(*) FROM blog";
$result = mysql_query($query) or die(mysql_error());
$num_rows = mysql_fetch_row($result);
$pages = new Paginator;
$pages->items_total = $num_rows[0];
$pages->mid_range = 9; // Number of pages to display. Must be odd and > 3
$pages->paginate();
$query = "SELECT id, title, resume, date
FROM blog
ORDER BY date DESC $pages->limit";
$result = mysql_query($query) or die(mysql_error());
while ($row = mysql_fetch_row($result)) {
//do stuff
}
I'm getting a "Could not select database" error, I don't really care for the 'or die' cases, I would just like to make this connection functional on PDO, any help would be great.
You cant use PDO and then exepect to use mysql_* functions they arent related.
Theres no need to select a db like that with pdo because its included in the DSN which is the contructors first argument:
$db = new PDO('mysql:host=localhost;dbname=jdlferreira', DB_USER, DB_PASS);
Then you need to use the PDO interface to interact with the DB, not the mysql ones:
$stmt = $db->prepare("SELECT COUNT(*) FROM blog");
$stmt->execute();
$num_rows = $stmt->fetchColumn();
$stmt->closeCursor();
$pages = new Paginator;
$pages->items_total = $num_rows;
$pages->mid_range = 9; // Number of pages to display. Must be odd and > 3
$pages->paginate();
$query = "SELECT id, title, resume, date
FROM blog
ORDER BY date DESC $pages->limit";
$stmt = $db->prepare($query);
$stmt->execute();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
// do stuff
}