How can i prevent SQL injection when using MySQLi? [duplicate] - php

This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 9 years ago.
How would i prevent SQL injections in a SQL query like this?
<?php
$mysqli = new mysqli("ip", "username", "pass", "database");
/* check connection */
if (mysqli_connect_errno()) {
printf("Sorry, the login server is 'Under Maintainance'");
exit();
}
$username = $_POST["username1"];
$username = strtolower($username);
$password = $_POST['password1'];
$hash = sha1(strtolower($username) . $password);
$query = "SELECT * FROM accounts WHERE name='$username'";
if ($result = $mysqli->query($query)) {
/* determine number of rows result set */
$rownum = $result->num_rows;
if($rownum != 0)
{
while ($row = $result->fetch_assoc()) {
{
$acct = $row['acct'];
$pass = $row['pass'];
}
if($hash == $pass){
session_start();
$_SESSION['name']=$username;
$_SESSION['acct']=$acct;
header('Location:index.php');
} else {
echo 'There was an error when logging in. Make sure your password and username are correct.';
}
}
$result->close();
}
else
{
echo 'Account does not exist. Please Register an account before logging in.';
}
$mysqli->close();
}
?>
I have already added encryption but i cannot seem to find a prevention method that i know how to use yet. Also, is it possible for a user to use a MySQL injection without using an input box? (page dissection???)

Encryption and query sanitation are not related.
You're already using mysqli, which is nice, but you don't sanitize the input to the query (namely $username, which probably doesn't need to be strtolowered either).
You should use properly parameterized queries for sanitation.
$query = "SELECT * FROM accounts WHERE name = ?";
$stmt = $mysqli->prepare($query);
$stmt->bind_param("s", $username);
$stmt->execute();
$stmt->bind_result($acct, $pass);
$stmt->fetch();
//$act and $pass are now properly set
The limits on SQL injection have nothing to do with the user. It's even possible for you to accidentally inject yourself in your own code, and injection does not even have to be malicious. For that reason, you should always properly parameterize your queries even if you don't think there's any risk of malicious injection.

Related

"Cant process the request", dealing with basic parameterized queries

I am trying something I found online (Extremely new to this) and none of it works. It's some random science project I decided to learn more about yet I am stuck on part 2 of the "procedures". https://www.sciencebuddies.org/science-fair-projects/project-ideas/Cyber_p008/cybersecurity/sql-injection#procedure
I watched videos but they only consist of just a user_ID and not a username and password. NOTE: Only the code dealing with login.php is causing problems.
<?php
include("global.php");
include("db.php");
session_start();
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// username and password are sent in the form
$username = $_POST['username'];
$password = $_POST['password'];
// Check if the username and password exist in the database
$sql = "SELECT username FROM users WHERE username = '$username' AND password = '$password'";
$stmt = msqli_stmt_init($db);
if (!mysqli_stmt_prepare($stmt, $sql)) {
echo "SQL Statement Failed";
} else {
mysqli_stmt_bind_param($stmt, "ss", $username, $password );
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
$count = mysqli_num_rows($result);}
// If username and password matched then there is one row in the result
if ($count != 0) {
$_SESSION['login_user'] = strtolower($username);
header("location: search.php");
}
else {
$error = "Your Username or Password is invalid";
}
}
?>
It should have prevented a basic " 'or''=' " injection attack but it decided not to work entirely.
If you use query parameters — which is definitely a good idea — you must leave placeholders in your query. Use ? as the placeholder.
Like this:
$sql = "SELECT username FROM users WHERE username = ? AND password = ?";
You later bind variables to those parameters. You must bind the same number of variables as the number of parameter placeholders.
You got the error you described because you tried to bind variables to a query that had no parameter placeholders.

Sql injection on a php code [duplicate]

This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
What is SQL injection? [duplicate]
(9 answers)
Closed 6 years ago.
Hello guys the below given php code is mine i need to know it is vulnerable or not
$sql = "select Email,Password from user where Email='$emailid'";
$ctr=0;
try
{
$result = $con->query($sql);
foreach($result as $row)
{
$ctr++;
$pword = $row['Password'];
}
}
catch(PDOException $e)
{
$errTyp = "danger";
$errMSG = "Something went wrong, try again later...";
}
if($ctr == 0)
{
$errTyp = "danger";
$errMSG = "Invalid Username | Password";
}
else
{
if( $pword==$password ) {
$_SESSION['Id']=$emailid;
Here is my php login page code Just to confirm, how vulnerable is the above code to sql injection?
Simple,
$sql = "select Email,Password from user where Email='$emailid'";
If $emailid could be,
$emailid = 'or 1=1';
Injection,
$sql = "select Email,Password from user where Email=''or 1=1";
It will return the first record of your database.
So attack will happen !
I see that the main problem could be the origin of the $emailid
Email='$emailid'"
You can't trust in the data sent from client($_POST,$_GET). That's a main principle in security.
So if you have Sanitize/Filtered the POST variables you should be ok.
If not you should at least use Prepared statements
http://php.net/manual/en/pdo.prepare.php

Why doesn't my mysqli login authentication work? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I can't for the life of me figure out why this code doesn't work. I'm new to MySQL queries so I may be doing something wrong there.
Here's my login.php
<?php
/**
* Created by PhpStorm.
* User: Michael
* Date: 10/25/2015
* Time: 4:35 AM
*/
require 'connect.php';
if(empty($_POST['Login_Username']) || empty($_POST['Login_Password'])){
header("Location: http://www.socksdevsite.com/PHP_Files/Display_Files/Login/displayloginfailed.php");
} else {
$username = "'DevSock'";
if($db->query('SELECT username FROM users WHERE username = $username')){
echo "Found user";
}else {
echo "Didn't find user";
}
}
My connect.php
<?php
/**
* Created by PhpStorm.
* User: Michael
* Date: 10/25/2015
* Time: 11:58 AM
*/
$db = mysqli_connect('127.0.0.1', 'username', 'password') or die("Error logging in. Please notify an administrator!");
$db->select_db('Website_Storage');
echo "Connected and DB selected <br>";
And finally a screenshot of my phpMyAdmin.
Firstly your problem is the following:
WHERE username =$username'
Secondly change the code to:
WHERE username ='$username'"
Because $username is a string check out out when to use single and double quotes
Lastly you should use prepared statements for the login system, you are already using mysqli_ so the transition shouldn't be too difficult. Something like this:
if ($stmt = $mysqli->prepare('SELECT password FROM users WHERE username = ?')) {
// Bind parameters (s = string, i = int, b = blob, etc), hash the password using the PHP password_hash function.
$username = $_POST['username'];
$stmt->bind_param('s', $username);
if(!$stmt->execute()){
trigger_error("there was an error....".$mysqli->error, E_USER_WARNING);
}
$stmt->store_result();
You could also use PDO! Check out this, Stackoverflow on PDO and mysqli pros and cons
Check out this SO question on Stopping SQL injections
Using PDO you can use something like this:
if (empty($_POST['Login_Username']) || empty($_POST['Login_Password'])){
header("Location: http://www.socksdevsite.com/PHP_Files/Display_Files/Login/displayloginfailed.php");
} else {
//Make the connection using PDO
try {
$conn = new PDO("mysql:host=localhost;dbname=mysql", $username, $password);
echo "PDO connection object created";
$username = "DevSock";
//SQL query
$sql = "SELECT username FROM users WHERE username = :username";
//Prepare your query
$stmt = $conn->prepare($sql);
//Execute your query binding variables
$stmt->execute(array(':username' => $username));
//Fetch all results
$result = $stmt->fetchAll();
if (count($result) > 0) {
foreach ($result as $row) {
//Do something here
echo '<p>'.$row['username'].'</p>';
}
} else {
echo "Didn't find user";
}
}
catch(PDOException $e) {
echo $e->getMessage();
}
}
You can find examples for PDO here: http://www.phpro.org/tutorials/Introduction-to-PHP-PDO.html

How to prevent sql injection in a site [duplicate]

This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 9 years ago.
I have the following code in my php file:
session_start();
include "connect.php";
if (isset($_POST['email']) && isset($_POST['password'])) {
$email = htmlspecialchars(mysqli_real_escape_string($conn, $_POST['email']));
$password = htmlspecialchars(mysqli_real_escape_string($conn, $_POST['password']));
function process() {
include "connect.php";
if (isset($_POST['email']) && isset($_POST['password'])) {
$email = $_POST["email"];
$password = $_POST["password"];
}
mysqli_select_db($conn, "users");
$sql = "SELECT * FROM users WHERE email='$email' AND password='$password'";
$result = mysqli_query($conn, $sql);
$count = mysqli_num_rows($result);
if ($count >= 1) {
$_SESSION['id'] = $id;
$_SESSION['email'] = $email;
$_SESSION['password'] = $password;
header('location:index.php');
} else {
echo "Email/Password is incorrect";
}
}
if ($email != "" or $password != "") {
if (isset($_POST['submit'])) {
process();
} else {
echo "Error: " . mysql_error();
}
}
}
How would I go about preventing sql injection in my login page?
I searched on the internet and most sites said I must use the mysqli_real_escape_string() function, but this did not seem to change things at all when I used the sql injection in my site again.
please help :)
Yes, use PDO and prepare statements with try/catch blocks. When using prepare, each passes as a secure parameter, eliminating risk of injection.
Use sql prepare :)
http://www.php.net/manual/en/mysqli.prepare.php
From what I know this filters any sql injection
foreach($_POST as $key => $value) $_POST[$key] = mysqli_real_escape_string($value);
Most simple way, anyway i suggest of use prepare statements
First of all, - to avoid sql injection you need to filter any kind of user input. And simplest way to do it, is to use PDO
You need to use prepared statements. I think following code snippet will give you some idea how to use it. please change according to your requirements
/* Create a prepared statement */
if($stmt = $mysqli -> prepare("SELECT * FROM users WHERE email=? AND password=?")) {
/* Bind parameters
s - string, b - blob, i - int, etc */
$stmt -> bind_param("ss", $email, $password);
/* Execute it */
$stmt -> execute();
$res = $stmt->get_result();
$row = $res->fetch_assoc();
$_SESSION['id'] = $row['id'];
$_SESSION['email'] = $row['email'];
$_SESSION['password'] = $row['password'];
header('location:index.php');
/* Close statement */
$stmt -> close();
}
/* Close connection */
$mysqli -> close();
Docs Link: http://www.php.net/manual/en/mysqli.prepare.php
http://www.php.net/manual/en/mysqli.quickstart.prepared-statements.php
http://forum.codecall.net/topic/44392-php-5-mysqli-prepared-statements/

mysql - want to create error

im new at programing and php, and i want to create an error on my registration system that when the user creates an account with the same username already existing in the database it says something like this: "Username already in use" and then if it isnt an existing username it says "Registation Complete"
I tried this code:
<?
require ("conect.php");
$user = $_POST['user'];
$pass = $_POST['password'];
$email = $_POST['email'];
$email_check = $_POST['email_check'];
$register = mysql_fetch_array;
if($user = $register[user]) {
echo"Username already in use";
}
else
{
$insert = mysql_query("INSERT INTO registration (user, password, email)
VALUES('$_POST[user]','$_POST[password]','$_POST[email]')");
echo "The account $user was successfully created.";
}
?>
But it didnt work, can someone help please
As pointed out by the other users, you should be using prepared statements through PDO (or mysqli, but I definitely prefer PDO)
You're storing the POSTS in variables, but then in the database query you are just using the $_POST variable again?
I'm not sure what your doing with the $register = mysql_fetch_array part, but to get the desired functionality you should use a select query to count the number of users using the username.
You're not using any secure hash format to store the password. I switched it to use password_hash().
Try something like this (I haven't tested the code yet though, so there might be errors):
<?php
//Put all POSTS in variables
$user = $_POST['user'];
$pass = password_hash($_POST['password'], PASSWORD_DEFAULT);
$email = $_POST['email'];
$email_check = $_POST['email_check'];
//Database config- probably should store in a separate file
$database_host = "";
$database_name = "";
$database_user = "";
$database_password = "";
$conn = new PDO("mysql:host=$database_host;dbname=$database_name",$database_user,$database_password);
//Find out if the username is taken.
$sql = "SELECT count(*) FROM `registration` WHERE user = :user";
$q = $conn->prepare($sql);
$q->execute(array(':user' => $user));
$number_of_rows = $q->fetchColumn();
//Clear $sql and $q so you can use them again
$sql = NULL;
$q = NULL;
if ($number_of_rows > 1) {
//Username already taken
echo "Username already taken";
}
else {
$sql = "INSERT INTO registration (user,password,email) VALUES (:user,:password,:email)";
$q = $conn->prepare($sql);
$q->execute(array(':user'=>$user, ':password'=>$password, ':email'=>$email));
echo "The account " . $user . " was successfully created";
}
?>
You really, really need to read about prepared statements. The method you are using is very old, incredibly insecure, and generally a bad-practice by today's standards.
Your code isn't even worth fixing for these reasons, it should be re-written using prepared statements.

Categories