Do I need to sanitize user inputs when using Ajax? - javascript

I am creating a login form that does not require the page to reload on submit. I am doing this using Ajax. Below is my code:
HTML:
<form id="myForm" method="post">
Username: <input name="username" id="username" type="text"/><br/>
Password: <input name="password" id="password" type="password"/><br/>
<input type="button" id="submitFormData" onclick="SubmitFormData();" value="Submit" />
</form>
JS/Ajax:
function SubmitFormData() {
var username = $("#username").val();
var password = $("#password").val();
$.post("submit.php", { username: username, password: password},
function(data) {
$('#results').html(data);
$('#myForm')[0].reset();
});
}
PHP (submit.php):
$username = mysqli_real_escape_string($connect, $_POST["username"]);
$password = mysqli_real_escape_string($connect, $_POST["password"]);
$query = "SELECT * FROM users WHERE username = '$username'";
$result = mysqli_query($connect, $query);
if(mysqli_num_rows($result) > 0)
{
while($row = mysqli_fetch_array($result))
{
if(password_verify($password, $row["password"]))
{
//return true;
$_SESSION["username"] = $username;
$_SESSION["uuid"] = $row["uuid"];
echo "success";
header ("location: https://durzst.com/main");
}
else
{
//return false;
echo '<script>alert("Wrong User Details")</script>';
}
}
}
I am already sanitizing the inputs in my PHP (Yes, I will be switching to prepared statements later), but do I need to do anything with the Ajax, such as sanitizing inputs, in order to prevent any kind of attacks. If so, how?

Yes, always Sanitize & Validate your data. Both Client Side and Server Side.
Sanitize your data, so you don't get unexpected formats, symbols etc.
Validate your data, to ensure it's data your program expects/accepts. An email address vs some random string, a date vs a string or phone number etc.
I suggest, reading up on the subject, a quick google will get you started, also StackOverflow has tones of articles on the subject, here is one.
I say always, and both Client Side and Server Side, not because you should trust your Client Side sanitization and validation, on the server, but you want to ensure both of your applications operate on correctly formatted and valid data.

Related

Decode JSON package from PHP using AJAX

I am building a simple login system. I do not want the page to reload when the user submits the form, in case there is an error, and I need to seamlessly display an error message (Like wrong password). When the users submits the data, AJAX passes it onto the submit.php script. This script validates the data and then sets a JSON object to a number 1-3 based on what is wrong or right with the submitted credentials. I don't know how to have the AJAX call, decode the JSON, and then have some if statements that decide what to do based on the value of that JSON.
Below is the code I am using for the form.
HTML:
<form method="post" id="myForm">
<h1 class="title" unselectable="on">Login</h1>
<input placeholder="Username" type="text" name="username" class="form" id="username"/>
</br>
<input placeholder="Password" type="password" name="password" class="form" id="password"/>
</br>
<input class="button" type="button" id="submitFormData" onclick="SubmitFormData();" value="Submit"/>
</br>
</form>
JS/AJAX (Same page):
function SubmitFormData() {
var username = $("#username").val();
var password = $("#password").val();
$.post("submit.php", { username: username, password: password},
function(data) {
$('#results').html(data);
$('#myForm')[0].reset();
});
}
Next is the PHP (submit.php). The PHP will look at the incoming data from the AJAX script, and then assign an error number to a JSON object depending on what is wrong with the credentials.
$username = mysqli_real_escape_string($connect, $_POST["username"]);
$password = mysqli_real_escape_string($connect, $_POST["password"]);
$query = "SELECT * FROM users WHERE username = '$username'";
$result = mysqli_query($connect, $query);
if(mysqli_num_rows($result) > 0)
{
while($row = mysqli_fetch_array($result))
{
if(password_verify($password, $row["password"]))
{
$Obj->error = "three";
$myJSON = json_encode($Obj);
}
else
{
$Obj->error = "two";
$myJSON = json_encode($Obj);
}
}
}
else {
$Obj->error = "one";
$myJSON = json_encode($Obj);
}
//error one=user not found
//error two=wrong password
//error three=all detials are correct
Now, the trouble I am having is back at the main page where the user is. I want the JS to look at the $myJSON variable and decide what to do based on that. I have written some pseudo code below, but I don't know if or how I can do this in JS or AJAX.
decode JSON package
if error=one, do something
if error=two, do something else
if error=three, run a php script that sets some session variables. (Is it possible to run php inside of JS?)
Any help accomplishing these results would be greatly appreciated.
This is a vanilla javascript solution:
const xmlhttp = new XMLHttpRequest;
xmlhttp.onreadystatechange = function() {
if (this.readyState === 4 && this.status === 200) {
//passes results to a function
start(JSON.parse(this.responseText));
}
}
xmlhttp.open("POST", "PHP WEBSITE URL", true);
//sends the request with a FormData object based on the form
xmlhttp.send(new FormData(document.getElementById("myForm")));
function start(object) {
alert(object);
}
For this to work, your PHP script will have to echo your result object. Example:
if ($_POST["username"] === "correctUsername" && $_POST["password"] === "correctPassword") {
//echo javascript object
echo json_encode(['success'=>true]);
} else {
//echo javascript object
echo json_encode(['success'=>false]);
}
Obviously it needs to be more complex but this is the idea.
I have made login pages before and instead of returning a success I used the current PHP page as the main one and echoed the info to fill the page as well as credentials that can be used with AJAX requests. Hopefully this helps.

Creating a simple Password login without the password hardcoded [PHP,Javascript,MySQL]

I'm trying to create a simple login promt on my local website. I already tried with Javascript, but I don't want the password to be hardcoded. The Users get the password by mail so there is no registration form needed. I searched on the Internet and I think it should work with PHP and Javascript. This is what i've come up with:
<SCRIPT>
function passWord() {
var testV = 1;
var pass1 = prompt('Enter password',' ');
while (testV < 3) {
if (!pass1)
window.open('Website.html',"_self");
if (pass1.toLowerCase() == "password") {
alert('Correct!');
window.open('./test/sitetwo.html',"_self");
break;
}
testV+=1;
var pass1 =
prompt('Wrong Password','Try again');
}
if (pass1.toLowerCase()!="password" & testV ==3)
return " ";
}
</SCRIPT>
<CENTER>
<FORM>
<input type="button" value="Enter Protected Area" onClick="passWord()">
</FORM>
</CENTER>
Does anyone of you know how to code this? Thank you for your help.
Login prompt is just one of possible approaches to hide information on your website. You have to decide first what are you trying to hide. For instance, if you if are providing some paid information to your clients - you can send the information itself by mail (instead of password). If you want to hide some part of site from other people - you can just give it weird url, like site.com/jkhgdsdkgf
Creating login backend with php and database obviously requires your php, mysql (or other database) and server administration skills and completely depends on details of your task, so it's hard to provide a useful advice here.
In my opinion, you should use a database to store all your credentials (like username, password, etc..)
If you don't know how to do it, you should know that if you want to run your php code, you need a php server and somewhere to put your db.
Here is how to set up a php server with Apache
https://www.ultraedit.com/support/tutorials-power-tips/uestudio/local-php-mysql-dev-environment.html
Here is how to set up a db with PhpMyAdmin
https://www.siteground.com/tutorials/phpmyadmin/create-populate-tables/
You need a login.php (where you log in), a test.php page (then you put in it whatever you want) and a check_User.php page (where to control if the credentials are correct).
Login.php
<html>
<head> <title>Login</title> </head>
<body>
<form action="check_User.php" method="post" id="login_form">
<label><b>Username</b></label>
<!-- USERNAME -->
<input type="text" placeholder="Enter Username" name="username" required>
<!-- PASSWORD -->
<label><b>Password</b></label>
<input type="password" placeholder="Enter Password" name="password" required>
<!-- LOGIN -->
<button type="submit">Login</button>
</form>
<body>
</html>
check_User.php
<?php
session_start();
$_POST["username"] = htmlspecialchars($_POST["username"]);
$_POST["password"] = htmlspecialchars($_POST["password"]);
$link = mysqli_connect("your_host", "your_db_username", "your_db_password", "your_db_name");
$query = "SELECT username, password
FROM your_db_name
WHERE username = \"".$_POST["username"]."\" AND password = \"".$_POST["password"]."\"
";
mysqli_query($link, $query);
$rows = array();
$result = mysqli_query($link, $query);
while($row = mysqli_fetch_array($result,MYSQLI_ASSOC))
$rows[] = $row;
/* correct match */
if(mysqli_affected_rows($link) == 1)
{
$_SESSION["username"] = $_POST["username"];
$_SESSION["password"] = $_POST["password"];
}
if(isset($_SESSION["username"]) && isset( $_SESSION["password"]))
header("Location:test.php");
else {
alert("Wrong username or password");
}
?>
test.php
<?php
session_start();
// not logged in, not showing this page
if((!isset($_SESSION["username"]) || !isset( $_SESSION["password"]))
header("Location:login.php");
?>
<html>
....whatever you want this page to do
</html>

Many spaces before javascript result

I have a login script that should return 'success' or 'failure' respectively, but it adds many spaces before the result, in the console it shows tha value as "<tons of space> success". This is the PHP for the login script:
public function login() {
global $dbc, $layout;
if(!isset($_SESSION['uid'])){
if(isset($_POST['submit'])){
$username = mysqli_real_escape_string($dbc, trim($_POST['email']));
$password = mysqli_real_escape_string($dbc, trim($_POST['password']));
if(!empty($username) && !empty($password)){
$query = "SELECT uid, email, username, password, hash FROM users WHERE email = '$username' AND password = SHA('$password') AND activated = '1'";
$data = mysqli_query($dbc, $query);
if((mysqli_num_rows($data) === 1)){
$row = mysqli_fetch_array($data);
$_SESSION['uid'] = $row['uid'];
$_SESSION['username'] = $row['username'];
$_SERVER['REMOTE_ADDR'] = isset($_SERVER["HTTP_CF_CONNECTING_IP"]) ? $_SERVER["HTTP_CF_CONNECTING_IP"] : $_SERVER["REMOTE_ADDR"];
$ip = $_SERVER['REMOTE_ADDR'];
$user = $row['uid'];
$query = "UPDATE users SET ip = '$ip' WHERE uid = '$user' ";
mysqli_query($dbc, $query);
setcookie("ID", $row['uid'], time()+3600*24);
setcookie("IP", $ip, time()+3600*24);
setcookie("HASH", $row['hash'], time()+3600*24);
echo 'success';
exit();
} else {
//$error = '<div class="shadowbar">It seems we have run into a problem... Either your username or password are incorrect or you haven\'t activated your account yet.</div>' ;
//return $error;
$err = 'failure';
echo($err);
exit();
}
} else {
//$error = '<div class="shadowbar">You must enter both your username AND password.</div>';
//return $error;
$err = "{\"result\":\"failure\"}";
echo json_encode($err);
exit();
}
}
} else {
echo '{"result":"success"}';
exit();
}
return $error;
}
and the form and JS
<div class="shadowbar"><form id="login" method="post" action="/doLogin">
<div id="alert"></div>
<fieldset>
<legend>Log In</legend>
<div class="input-group">
<span class="input-group-addon">E-Mail</span>
<input type="email" class="form-control" name="email" value="" /><br />
</div>
<div class="input-group">
<span class="input-group-addon">Password</span>
<input type="password" class="form-control" name="password" />
</div>
</fieldset>
<input type="submit" class="btn btn-primary" value="Log In" name="submit" />
</form></div>
$(function login() {
$("#login").validate({ // initialize the plugin
// any other options,
onkeyup: false,
rules: {
email: {
required: true,
email: true
},
password: {
required: true
}
}
});
$('form').ajaxForm({
beforeSend: function() {
return $("#login").valid();
},
success : function(result) {
console.log(result);
if(result == " success"){
window.location = "/index.php";
}else if(result == " failure"){
$("#alert").html("<div class='alert alert-warning'>Either you're username or password are incorrect, or you've not activated your account.</div>");
//$("#alert").show();
}
}
});
});
but the result always has a lot of spaces for some reason. I'm new to JS, so if this is common, I don't already know.
<?php
error_reporting(E_ALL); ini_set('display_errors', 1);
define("CCore", true);
session_start();
//Load files...
require_once('include/scripts/settings.php');
require_once('include/scripts/version.php');
require('include/scripts/core.class.php');
require('include/scripts/nbbc_main.php');
$parser = new BBCode;
$core = new core;
$admin = new admin;
require_once('include/scripts/layout.php');
require_once('include/scripts/page.php');
//Set Variables...
global $dbc, $parser, $layout, $main, $settings, $core;
$page = new pageGeneration;
$page->Generate();
?>
this is my index, and anything before the page is generated and login() is called, is in there.
I suppose you are using Ajax calls. I had the same problem, but it my case the result hadn't contain spaces, it was returned in new line. The problem was that my script which was requested by Ajax, contained "new line" character before the PHP script. Search your script file for spaces before PHP script starting with <?php //code... If you had included some scripts in the script which returns success note, search them as well.
I dont know if it matters but your
if(result == " success"){ // <<<<<< Here is a Problem maybe
window.location = "/index.php";
}else if(result == " failure"){ // <<<<<< Here is a Problem maybe
$("#alert").html("<div class='alert alert-warning'>Either you're username or password are incorrect, or you've not activated your account.</div>");
//$("#alert").show();
}
compares your result from the server which is i.e. "success" with " success". There is space too much.
EDIT:: I dont get ether why you jumps between the response format. Sometimes you echo "success" which is plain and good with your if condition but sometimes you return json encodes strings.
These Responses you can't just compare with plain text. These Responses you have to Parse into a JSON Object. Then you could compare with:
if (parsedJSONobject.result == "success"){}
The comments on the question are most probably correct: the spaces are being (again, probably, nobody can know for sure without reading the whole source) echoed by PHP included before this. For example, if you do:
<?php
// there's a space before the previous line
you'd get that space in the output.
What you can do is a bit of a hack, you include a header, for example:
header('Content-Type: text/html');
just before your success output, this will (yet again, probably) output something like:
Warning: Cannot modify header information - headers already sent by (output started at /some/file.php:12) in /some/file.php on line 23
(note the "output started" part) and now you know where to start looking.
HTH.

Kendo UI login functionality

I am currently making a iPhone application using Kendo UI which i am running through phone gap to test on my iPhone.
The design is all mapped out nicely and I am getting to grips with the Kendo framework. I am trying to make some functionality whereby they log into an account.
My external PHP file which runs the query and returns JSON:
<?php
$arr = array();
//Takes the username and password from the login form and queries the database to find out if they have access to the site.
//Cleanse inputs
$username = $_GET['username'];
$password = md5_base64($_GET['password']);
$stmt = $memberMysqli->prepare("SELECT id, firstname, dob, sex, recordingWeight, blocked, enabled FROM member WHERE email = ? AND password = ?");
$stmt->bind_param('ss', $username, $password);
$stmt->execute();
$stmt->bind_result($memberid, $firstname, $dob, $sex, $recordingWeight, $blocked, $enabled);
$stmt->store_result();
session_start();
while ($stmt->fetch())
{
$userIsBlocked = $blocked;
$enabled = $enabled;
}
if(($numRows = $stmt->num_rows) > 0) //If num rows is 1 the combination exists therefore it is a succesful login
{
if($userIsBlocked)
{
$arr['status'] = "error";
$arr['message'] = "Sorry, your account isnt active. Please contact us to re-activate it.";
}
else if(!$enabled)
{
$arr['status'] = "error";
$arr['message'] = "Sorry, your account isn't enabled. Please contact us.";
}
else
{
$_SESSION['memberid'] = $memberid;
$_SESSION['memberFirstname'] = $firstname;
$_SESSION['dob'] = $dob;
$_SESSION['sex'] = $sex;
$_SESSION['recordingWeight'] = $recordingWeight;
$arr['status'] = "success";
$arr['message'] = "Logged in";
}
}
else
{
$arr['status'] = "error";
$arr['message'] = "Sorry, Wrong Username/Password Combination";
}
header("Content-type: application/json");
echo json_encode($arr);
/* close connection */
function md5_base64 ( $data )
{
return preg_replace('/=+$/','',base64_encode(md5($data,true)));
}
?>
So this returns success, logged in or sorry wrong username/password combination..
Here is my form code:
<form>
<fieldset>
<p><label style="color:white;" for="email">E-mail address</label></p>
<p><input type="email" id="email" value=""></p>
<p><label style="color:white; font" for="password">Password</label></p>
<p><input type="password" id="password" value=""></p>
<p><input type="submit" value="Sign In"></p>
</fieldset>
and the JS:
<script>
$("form").on("submit", function() {
var username = document.getElementById('email').value;
var password = document.getElementById('password').value;
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: 'http://myurl.co.uk/appqueries/login.php?username='+username+'&password='+password,
dataType: "json"
}
}
});
//alert("Your username is "+username+" and your password is: "+password);
});
</script>
Can anybody help me getting what the JSON that the PHP file returns and then letting the user into the app if login is successful, or displaying a message if they were not.
I don't think you want a DataSource for this (it could be done, but the DataSource expects an array of objects from the read operation), unless there are additional requirements.
If this is your HTML:
<input id='username' type='text' value='user'></input>
<input id='password' type='text' value='password'></input>
<button id='loginbutton'>Login</button>
<div id='loginresult'></div>
Then you can use jQuery (which I assume you're using since it's a requirement for Kendo UI):
function loginClick() {
var username = $("#username").val();
var password = $("#password").val();
var loginUrl = 'http://myurl.co.uk/appqueries/login.php?username='+username+'&password='+password;
$.ajax({
url: loginUrl,
type: 'GET',
dataType: 'json',
success: function (data) {
handleLoginResult(data);
}
});
}
$(document).on("click", "#loginbutton", loginClick);
function handleLoginResult(data) {
var status = data.status;
var message = data.message;
if (status === "success") {
// do whatever needs to be done after successful login
$("#loginresult").html(message);
}
}
See a working example here (there are a few differences because this is using jsfiddle's echo api): http://jsfiddle.net/lhoeppner/9TGJd/
This works almost the same for Kendo Mobile, except you'd use the mobile button and the data-click binding:
<a id="loginbutton" data-role="button" data-click="loginClick">Login!</a>
You should not use form submit in Kendo Mobile application as a Kendo mobile application is basically a Single Page Application. What you need to do is to have a Kendo button and on the click event handler, fire the JSON call. You can see the demo of Kendo Button click event here: http://demos.kendoui.com/mobile/button/events.html#/

Check for empty field after encryption

I have this piece of html code:
<form action="register.php" method="post">
Email: <input type="text" name="email" /><br />
Username: <input type="text" name="username" /><br />
Password: <input type="password" name="p" id="password" /><br />
<input type="button" value="Register" onclick="formhash(this.form, this.form.password);" />
</form>
Once the register button is pressed, an encryption gets called and the password gets encrypted immediately. I thought this would be a very good and secure way to do it, however I can't seem to check if the passworld field named "p" is empty or not because if the user leaves the field empty when registering, the encryption encrypts the empty field, hence it's not empty anymore. I need a way to check if the user leaves the "p" field empty or not, because it shouldn't be possible to make a password with 0 characters.
I know this problem can be solved by javascript, but I need a secure way to check if the field is empty or not, therefore I'd like to get a PHP solution.
The register.php:
<script type="text/javascript" src="sha512.js"></script>
<script type="text/javascript" src="forms.js"></script>
<?php
include 'db_connect.php';
//Just to check that the p field is encrypted already at this point.
echo $_POST['p'];
// The username
$username = $_POST['username'];
// The email
$email = $_POST['email'];
// The hashed password from the form
$password = $_POST['p'];
// Create a random salt
$random_salt = hash('sha512', uniqid(mt_rand(1, mt_getrandmax()), true));
// Create salted password (Careful not to over season)
$password = hash('sha512', $password.$random_salt);
// Add your insert to database script here.
// Make sure you use prepared statements!
if ($insert_stmt = $mysqli->prepare("INSERT INTO members (username, email, password, salt) VALUES (?, ?, ?, ?)")) {
$insert_stmt->bind_param('ssss', $username, $email, $password, $random_salt);
// Execute the prepared query.
$insert_stmt->execute();
}
?>
If anyone monitor your traffic they can still get that password. It's just changed from the original string to the hash. It is not a security feature!
If you are worried about someone intercepting the data, use https.
Remove your client side hash:
<form action="register.php" method="post">
Email: <input type="text" name="email" /><br />
Username: <input type="text" name="username" /><br />
Password: <input type="password" name="p" id="password" /><br />
<input type="submit" name="submit" value="Register" />
</form>
Note: password_hash is new in PHP 5.5, if your version is older try this userland implementation.
Change your PHP code to this:
<?php
include 'db_connect.php';
if (!isset($_POST['p']) || (10 > strlen($_POST['p']))) {
//password too short!
}
if (!isset($_POST['username']) || (3 > strlen($_POST['username']))) {
//username too short!
}
// The username
$username = $_POST['username'];
// The email
$email = $_POST['email']
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
//not a valid email (mostly)
}
// The unaltered password from the form
$password = $_POST['p'];
// Create salted password (Careful not to over season)
$password = password_hash($password, PASSWORD_BCRYPT);
// Add your insert to database script here.
// Make sure you use prepared statements!
if ($insert_stmt = $mysqli->prepare("INSERT INTO members (username, email, password) VALUES (?, ?, ?)")) {
$insert_stmt->bind_param('sss', $username, $email, $password);
// Execute the prepared query.
$insert_stmt->execute();
}
Use this to verify the password on login/auth:
password_verify($password, $passwordFromDb)
have a javascript function that validates the form when the register button is clicked:
use this to check if the password field has any input:
if (document.getElementById('Password').value.length!=0) {
//encrypt and submit form
} else {
//return to form and display error to user
}
side note, always use SSL to submit passwords, forcing the user to hash their password before sending and then hashing it again could be excessive and won't prevent anyone from reusing the password or hash in an attack.

Categories

Resources