PHP Preventing of SQL injection with OOP - php

Here's a well known example how to prevent sqlinjection. There are two files like login.php and profile.php But it doesn't do anything with ether entering a correct login and pass or incorrect data. Doesn't echo about any case. SQL server goes by MAMP.
Here's the code:
<?php
$con = new mysqli("localhost", "root", "root", "phpsec");
if ($con->connect_error){
echo $con->connect_error;
}
if (isset($_POST["submit"])) {
$pre_stmt = $con->prepare("SELECT * FROM userinfo WHERE email = ? AND pass = ?");
$pre_stmt->bind_param("ss",$_POST["email"],$_POST["pass"]);
$pre_stmt->execute();
$result = $pre_stmt->get_result();
if($result->num_rows > 0){
$row = $result->fetch_assoc();
header("location:profile.php?email=".$row["email"]);
} else{
echo "login fail";
}
}
?>
and profile.php:
<?phpecho "Welcome ".$_GET["email"]; ?>
What and where did I do wrong?

you can prevent your page from sql injection using prepared statement in php
try this code in while performing sql statements.
<?php
// prepare and bind
$stmt = $conn->prepare("INSERT INTO example(firstname, lastname, email) VALUES (?, ?,
?)");
$stmt->bind_param("sss", $firstname, $lastname, $email);
// set parameters and execute
$firstname = "parth";
$lastname = "gandhi";
$email = "gandhi#example.com";
$stmt->execute();
?>
here in bind_param method in first parameter s is stands for string. if you want to use integer there you can use "i" and for decimal "d".
thanks for reading my solution.

Related

securing login php script

I have made a login system where the inserted_id and inserted_password are sent to the login.inc.php via the XMLHttpRequest. I'm not sure if my php script is secure. I need some securing advice for my script.
..............................................................................
login.inc.php:
<?php
session_start();
$conn = mysqli_connect("localhost", "root", "", "users");
$params = json_decode(file_get_contents('php://input'), true);
$inserted_id = $params['inserted_id'];
$inserted_password = $params['inserted_password'];
$stmt = mysqli_stmt_init($conn);
if (mysqli_stmt_prepare($stmt, "SELECT * FROM user WHERE account_name=? OR email=?;")) {
mysqli_stmt_bind_param($stmt, "ss", $inserted_id, $inserted_id);
mysqli_stmt_execute($stmt);
$row = mysqli_fetch_assoc(mysqli_stmt_get_result($stmt));
if ($row == null) {
echo ("DOESNT EXISTS");
} else {
if (password_verify($inserted_password, $row['password'])) {
$_SESSION['user_id'] = $row['id'];
echo("SUCCESS");
} else {
echo("PASSWORD_FAIL");
}
}
}
?>
signup.inc.php:
<?php
$conn = mysqli_connect("localhost", "root", "", "users");
$params = json_decode(file_get_contents('php://input'), true);
$inserted_first_name = $params['first_name'];
$inserted_last_name = $params['last_name'];
$inserted_dob = $params['dob'];
$inserted_email = $params['email'];
$inserted_account_name = $params['account_name'];
$inserted_password = $params['password'];
$stmt = mysqli_stmt_init($conn);
if (mysqli_stmt_prepare($stmt, "SELECT * FROM user WHERE email=?;")) {
mysqli_stmt_bind_param($stmt, "s", $inserted_email);
mysqli_stmt_execute($stmt);
if (mysqli_num_rows(mysqli_stmt_get_result($stmt)) > 0) {
echo("EMAIL_TAKEN");
} else {
$hashed_password = password_hash($inserted_password, PASSWORD_DEFAULT);
$created_id = rand(111111111, 999999999);
$stmt = mysqli_stmt_init($conn);
if (mysqli_stmt_prepare($stmt, "INSERT INTO user(id, first_name, last_name, dob, email, account_name, password) VALUES (?, ?, ?, ?, ?, ?, ?);")) {
mysqli_stmt_bind_param($stmt, "issssss", $created_id, $inserted_first_name, $inserted_last_name, $inserted_dob, $inserted_email, $inserted_account_name, $hashed_password);
$result = mysqli_stmt_execute($stmt);
echo ($result ? "SUCCESS" : "FAIL");
}
}
mysqli_stmt_close($stmt);
}
?>
Security is an entire field of study, and there's no easy way to measure whether or not something is "secure" or not secure. Security often involves not only code, but software releases, organizational changes, etc.
Here are the first things I noticed right off the bat in your posted code:
Using $_GET to pull in a password means the password was not POST'd, and therefore may exist in logs (client, server, and even some ISPs)
your mysqli_connect call is using root as a username. Don't use root in production code. Make an other user.
your root mysql user .... has no password?!?!?!
Using SELECT * FROM may return more rows than anticipated, especially because you have no LIMIT argument. Depending on database size, and how things get entered into the database, this could be abused.
WHERE account_name=? OR email=? - what if I make an account name that's someone else's email? Or enter the account name of another user in my "email" field? Your code might give me access to their profile (or lock me out of mine)
The code is not wrapped in a function, which means someone who can edit other PHP files (such as extensions) - which might be included'd after this php file - might be able to see the $inserted_password variable, which reveals the password!

Catchable fatal error: Object of class mysqli_result could not be converted to string on line 12

I'm getting this error for the following php code on line 12. I'm trying to insert data into a table and if it succeeds, redirect to another page after alert.
<?php
session_start();
include 'dbconn.php';
$name = $_POST["name"];
$hof = $_POST["hof"];
$tier = $_POST["tier"];
$services = $_POST["services"];
$proced = $_POST["proced"];
$addr = $_POST["addr"];
$phone = $_POST["phone"];
$depname = $_SESSION['depname'];
$qry = "INSERT INTO '.$depname.'(name,hof,tier,services,method,address,phone) VALUES ('$name','$hof','$tier','$services','$proced','$addr','$phone')"; //This is where the problem is;
if(mysqli_query($conn,$qry) === TRUE) {
echo "<script type='text/javascript'>alert('Success');
window.location='welcome.php';
</script>";
}
else{
echo "<script type='text/javascript'>alert('Error');
window.location='welcome.php';
</script>";
}
?>
In addition to what everyone else said this should fix your errors. You will still have security problems that you need to fix.
Also, I don't use mysqli I use PDO so you will have to forgive me if the syntax is slightly wrong.
Your problem is that mysqli_query() doesn't return a row. You need to need to fetch a row from your result and then assign it to $_SESSION['depname']
Login.php should look like this
// Note we are using prepared statements to prevent SQL injections
// Also note the use of backticks `, which are used for identifiers
$mysqli = new mysqli('host', 'user', 'password', 'database');
$stmt = $mysqli->prepare('SELECT `id`,`depname` FROM `admin` WHERE `username` = ? and password = ?');
$stmt->bind_param('ss', $myusername, $mypassword);
$stmt->execute();
$result = $stmt->get_result();
if($result->num_rows == 1) {
session_start();
$row = $result->fetch_assoc();
$_SESSION['depname'] = $row['depname'];
header("location: welcome.php");
exit;
}
Other Script
<?php
session_start();
include 'dbconn.php';
$name = $_POST["name"];
$hof = $_POST["hof"];
$tier = $_POST["tier"];
$services = $_POST["services"];
$proced = $_POST["proced"];
$addr = $_POST["addr"];
$phone = $_POST["phone"];
$depname = $_SESSION['depname'];
$qry = "INSERT INTO `{$depname}` (`name`,`hof`,`tier`,`services`,`method`,`address`,`phone`) VALUES (?,?,?,?,?,?,?)";
// prepare our query to prevent sql injections
$stmt = $mysqli->prepare($qry);
$stmt->bind_param('sssssss', $name, $hof, $tier, $services, $proced, $addr, $phone);
$stmt->execute();
// not sure why you aren't using header here like #JayBlanchard said, but whatever
if($stmt->affected_rows == 1) {
echo "<script type='text/javascript'>alert('Success');
window.location='welcome.php';
</script>";
}
else
{
echo "<script type='text/javascript'>alert('Error');
window.location='welcome.php';
</script>";
}

data is not inserted into mysql database but code runs without error

I am trying to insert form data into mysql database but it is not inserted into table and there is no error!
Here is my code
<?php
$con = mysqli_connect('localhost', 'root', '', 'register');
if (isset($_POST['submit'])) {
$shop = $_POST['shopname'];
$name = $_POST['name'];
$user = $_POST['username'];
$email = $_POST['email'];
$password = $_POST['password'];
$repassword = $_POST['repassword'];
$phone = $_POST['phone'];
$sql = "INSERT INTO registration (shop_name,name,username,email,password,repassword,phone) VALUES ('$shop','$name''$user','$email','$password','$repassword','$phone')";
if (mysqli_query($con, $sql)) {
echo "Signup Sucessfull";
} else {
echo mysqli_error();
}
}
?>
How can I resolve this problem?
Turns out you forgot to mention a comma after the name.
'$name''$user' // Missing comma in between
Also, it should be mysqli_error($con) instead of mysqli_error()
Try some debugging:
$sql = "INSERT INTO registration (shop_name,name,username,email,password,repassword,phone) VALUES ('".$shop."','".$name."', '".$user."','".$email."','".$password."','".$repassword."','".$phone."')";
mysqli_query($con, $sql) or die(mysqli_error($con));
You seems to miss "," between the insert values. This code will work fine.
<?php
$con = mysqli_connect('localhost', 'root', '', 'register');
if (isset($_POST['submit'])) {
$shop = $_POST['shopname'];
$name = $_POST['name'];
$user = $_POST['username'];
$email = $_POST['email'];
$password = $_POST['password'];
$repassword = $_POST['repassword'];
$phone = $_POST['phone'];
$sql = "INSERT INTO registration (shop_name,name,username,email,password,repassword,phone) VALUES ('".$shop."','".$name."','".$user."','".$email."','".$password."','".$repassword."','".$phone."')";
if (mysqli_query($con, $sql)) {
echo "Signup Sucessfull";
} else {
die(mysqli_error($con));
}
}
?>
Yes, As already #ObjectManipulator pointed your silly mistake
near '$name''$user'.
I will strongly recommend you to use mysqli_prepare to avoid SQL Injection.
<?php
$con = mysqli_connect('localhost', 'root', '', 'register');
if (isset($_POST['submit'])) {
$stmt = mysqli_prepare($con, "INSERT INTO registration (shop_name,name,username,email,password,repassword,phone) VALUES (?, ?, ?, ?,?, ?, ?)");
mysqli_stmt_bind_param($stmt, 'sssssss',$_POST['shopname'],$_POST['name'],$_POST['username'],$_POST['email'],$_POST['password'],$_POST['repassword'],$_POST['phone']);
if (mysqli_stmt_execute($stmt)) {
echo "Signup Sucessfull";
} else {
echo mysqli_error($con);
}
}
?>
And, as #JonStirling suggested not to store password in plain text
and use any Password API to encrypt password.
There are many ways to encrypt your password. Use anyone of them. Right now, I illustrated with md5().
And, Why to store password and repassword in database table. While storing user data into database table, check there itself if password & repassword matches or not.
Just a suggestion. It's upto you to choose.
<?php
$con = mysqli_connect('localhost', 'root', '', 'register');
if (isset($_POST['submit'])) {
if(isset($_POST['password']) && isset($_POST['repassword']) && ($_POST['password'] == $_POST['repassword'])){
$stmt = mysqli_prepare($con, "INSERT INTO registration (shop_name,name,username,email,password,phone) VALUES (?, ?, ?, ?, ?, ?)");
mysqli_stmt_bind_param($stmt, 'ssssss',$_POST['shopname'],$_POST['name'],$_POST['username'],$_POST['email'],md5($_POST['password']),$_POST['phone']);
if (mysqli_stmt_execute($stmt)) {
echo "Signup Sucessfull";
} else {
echo mysqli_error();
}
} else {
echo "Password must match.";
}
}
?>
else {
echo mysqli_error($con);
}
Problem solved. You forgot the connection details $con for your MySQL error output. This will now correctly output your MySQL Syntax mistakes from your query.
Other Notes:
Use Prepared statements for MySQLi (link)
Use a proper Password hashing algorithm such as Password_hash. Do not use MD5 (it's too fast and has too many collisions) and NEVER store passwords as plaintext.
Use the various filter_Var on your POSTed variables to clean them and make sure you catch any invalid data (such as improper email addresses)
Put comma in your sql query as below
$sql = "INSERT INTO registration (shop_name,name,username,email,password,repassword,phone)VALUES
('$shop','$name','$user','$email','$password','$repassword','$phone')";

Inserting data into multiple SQL tables from single form

Hey.. I'm a bit stuck on PHP code to insert data into multiple SQL tables. I an unable to get the data into both tables within a single action. This is for a registration page to create a user login and start of company profile. Any suggestions would be much appreciated. Thanks
<?php
session_start();
if(isset($_SESSION['user'])!="")
{
header("Location: home.php");
}
include_once 'resources/php/dbconnect.php';
if(isset($_POST['btn-signup']))
{
$uname = mysql_real_escape_string($_POST['uname']);
$email = mysql_real_escape_string($_POST['email']);
$upass = md5(mysql_real_escape_string($_POST['pass']));
$orgname = mysql_real_escape_string($_POST['orgname']);
$uname = trim($uname);
$email = trim($email);
$upass = trim($upass);
$orgname = trim($orgname);
// email exist or not
$query = "SELECT user_email FROM users WHERE user_email='$email'";
$result = mysql_query($query);
$count = mysql_num_rows($result); // if email not found then register
if($count == 0){
if(mysql_query("START TRANSACTION;
INSERT INTO users('user_name','user_email','user_pass')
VALUES('$uname','$email','$upass');
INSERT INTO companies('name','owner_id')
VALUES('$orgname','$email');
END;"))
{
?>
<script>alert('Registration Successful');</script>
<?php
}
else
{
?>
<script>alert('error while registering you...');</script>
<?php
}
}
else{
?>
<script>alert('Sorry Email ID already taken ...');</script>
<?php
}
}
?>
As you can see here the mysql extension is deprecated and you MUST stop using it. Great alternatives are PDO and mysqli
You should also use Prepared Statements to safeguard your code against SQL Injection attacks.
To complete a Transaction using PDO you can do this:
$conn->query("START TRANSACTION");
$stmt = $conn->prepare("INSERT INTO users(user_name,user_email,user_pass) VALUES(?,?,?)");
try
{
$stmt->bindValue(1,$user_name);
$stmt->bindValue(1, $user_email);
$stmt->bindValue(3, $user_pass);
$stmt->execute();
$secondStmt = $conn->prepare("INSERT INTO companies(name,owner_id) VALUES(?,?)");
$secondStmt->bindValue(1, $name);
$secondStmt->bindValue(2, $owner_id);
$secondStmt->execute();
$conn->query("COMMIT"); //This commits all changes if no error occured
}
catch(Exception $e)
{
$conn->query("ROLLBACK"); //This reverts any changes made in case of an error
}
You can do two inserts like this:
$queryUsers = INSERT INTO users('user_name','user_email','user_pass')
VALUES('$uname','$email','$upass');
mysql_query($queryUsers);
$queryCompanies = INSERT INTO companies('name','owner_id')
VALUES('$orgname','$email');
mysql_query($queryCompanies);
In addition, carefully with mysql_query, is deprecated, try to use mysqli().
Regards

PHP script throwing 500 internal error

I have a Javascript script that sends an Ajax request via POST to the following PHP script. $db is passed from up above, but I know that part works. I'm getting a 500 Internal Server Error from this. I am unable to see the server logs, so I can't get more detailed information than this. Anyone know what I can do to fix it?
function register($db) {
$user = $_POST['username'];
$pass = $_POST['password'];
$query = "SELECT username FROM users WHERE username='$user'";
$result = mysqli_query($db, $query);
if (mysqli_fetch_array($result)[0] == $user) {
echo "taken";
}
else {
$query = "INSERT INTO users (username, password) VALUES ('$user', '$pass')";
if (mysqli_query($db, $query)) {
echo "success";
}
}
}
This is more of a corollary than an actual answer, but it is far too long for the format of a comment.
For the sake of a followup to #MarcB's comment, you should change your code to be invulnerable to SQL injection:
$user = $_POST['username'];
$pass = $_POST['password'];
$link = new mysqli($host, $username, $password, $database);
if(!$link)
{
die("Unable to connect to MySQL");
}
$stmt = $link->prepare("SELECT username FROM users WHERE username=?");
$stmt->bind_param("s", $user);
$stmt->bind_result($testUsername);
$stmt->execute();
$stmt->store_result();
$stmt->fetch();
if($stmt->num_rows > 0)
{
echo "taken";
}
else
{
$stmt = $link->prepare("INSERT INTO users (username, password) VALUES(?, ?)");
$stmt->bind_param("ss", $user, $pass);
$stmt->execute();
echo "success";
}
I believe you have a parse error which is fixed in later versions of PHP. The following line of code is not valid <= PHP 5.4:
if (mysqli_fetch_array($result)[0] == $user) {
In order to fix this, you need to change that line to the following:
$row = mysqli_fetch_array($result);
if ($row[0] == $user) {
Also, your code also has a pretty severe SQL injection vulnerability. You need to sanitise your variables before using them in queries. For integers and floats, I recommend you do the following:
$myInt = (isset($_POST['myInt']) ? (int)$_POST['myInt'] : null);
$myFloat = (isset($_POST['myFloat']) ? (float)$_POST['myFloat'] : null);
For strings, you should use mysqli_real_escape_string() as follows:
$myStr = (isset($_POST['myStr']) ? mysqli_real_escape_string($_POST['myStr']) : null);
In your case, your $user and $pass variables need to be sanitised as the string is above. The reason for forcing the types of numbers you're receiving via $_POST is that it entirely negates any possibility of someone passing through a value which is not valid. Anything which is not 0, 1, 2, 3, 4, etc that is cast as (int) will become 0.

Categories