I have produced a login system which uses a basic ajax request and some feedback, and its working well (code is at the bottom).
Apart from hashing and salting passwords which I'm about to put in (so don't get hung up on that), what are the security implications of using Ajax/jQuery to handle these requests: Most importantly:
What is the general view when it es to this being JS dependant as opposed to pure PHP - do people put in redundancies, is it legitimate to simply say this is a JS only site (a huge amount of the website is based on the Twitter bootstrap, so its kinda reliant on JS).
Is my PHP and JS interfacing in the correct way? (and will my cookie still work?)
How can I create a secure way to now use jQuery .load() to bring in my content upon successful login?
Any general advice on making my system secure?.
$(function login() { $("form .button").click(function () { // getting form values and assigning variable names var username = $("form #username").val(); var password = $("form #password").val(); var remember = $("form #remember").val(); // concatenating variables to form the data used by the Ajax post method var dataString = 'username=' + username + '&password=' + password + '&remember=' + remember; // begin Ajax post function $.ajax({ type: "POST", url: "controls/login/process.php", data: dataString, success: function (response) { if (response == 'success') { alert("SUCCESS"); } else { $('.alert').find('span').text('Incorrect username or password'); $('.alert').addClass('alert-error').fadeIn('fast'); } }, error: function () { $('.alert').find('span').text('An error occured, try again'); $('.alert').addClass('alert-error').fadeIn('fast'); } }); return false; }); });
This interfaces with
<?php
session_start();
// Starting the session
require '../../tools/db/connect.php';
// Including the database connection file
session_set_cookie_params(2*7*24*60*60);
// Making the cookie live for 2 weeks
if($_SESSION['reference'] && !isset($_COOKIE['unifyLogin']) && !$_SESSION['remember']){
// If you are logged in, but you don't have the cookie and you have not checked the remember checkbox (a browser restart), destroy the session
$_SESSION = array();
session_destroy();
echo "expired";
}
$_POST['username'] = mysql_real_escape_string($_POST['username']);
$_POST['password'] = mysql_real_escape_string($_POST['password']);
$_POST['remember'] = (int)$_POST['remember'];
// Escaping all input data
$row = mysql_fetch_assoc(mysql_query("SELECT ID,REFERENCE FROM USER WHERE USERNAME='{$_POST['username']}' AND PASSWORD='{$_POST['password']}'"));
if($row['REFERENCE']) {
$_SESSION['secure'] = false;
// If everything is OK login
$_SESSION['id'] = $row['ID'];
$_SESSION['reference'] = $row['REFERENCE'];
$_SESSION['remember'] = $_POST['remember'];
// Store some data in the session
setcookie('unifyLogin',$_POST['remember']);
// We create the cookie
echo "success";
} else {
echo "failure";
}
?>
I have produced a login system which uses a basic ajax request and some feedback, and its working well (code is at the bottom).
Apart from hashing and salting passwords which I'm about to put in (so don't get hung up on that), what are the security implications of using Ajax/jQuery to handle these requests: Most importantly:
What is the general view when it es to this being JS dependant as opposed to pure PHP - do people put in redundancies, is it legitimate to simply say this is a JS only site (a huge amount of the website is based on the Twitter bootstrap, so its kinda reliant on JS).
Is my PHP and JS interfacing in the correct way? (and will my cookie still work?)
How can I create a secure way to now use jQuery .load() to bring in my content upon successful login?
Any general advice on making my system secure?.
$(function login() { $("form .button").click(function () { // getting form values and assigning variable names var username = $("form #username").val(); var password = $("form #password").val(); var remember = $("form #remember").val(); // concatenating variables to form the data used by the Ajax post method var dataString = 'username=' + username + '&password=' + password + '&remember=' + remember; // begin Ajax post function $.ajax({ type: "POST", url: "controls/login/process.php", data: dataString, success: function (response) { if (response == 'success') { alert("SUCCESS"); } else { $('.alert').find('span').text('Incorrect username or password'); $('.alert').addClass('alert-error').fadeIn('fast'); } }, error: function () { $('.alert').find('span').text('An error occured, try again'); $('.alert').addClass('alert-error').fadeIn('fast'); } }); return false; }); });
This interfaces with
<?php
session_start();
// Starting the session
require '../../tools/db/connect.php';
// Including the database connection file
session_set_cookie_params(2*7*24*60*60);
// Making the cookie live for 2 weeks
if($_SESSION['reference'] && !isset($_COOKIE['unifyLogin']) && !$_SESSION['remember']){
// If you are logged in, but you don't have the cookie and you have not checked the remember checkbox (a browser restart), destroy the session
$_SESSION = array();
session_destroy();
echo "expired";
}
$_POST['username'] = mysql_real_escape_string($_POST['username']);
$_POST['password'] = mysql_real_escape_string($_POST['password']);
$_POST['remember'] = (int)$_POST['remember'];
// Escaping all input data
$row = mysql_fetch_assoc(mysql_query("SELECT ID,REFERENCE FROM USER WHERE USERNAME='{$_POST['username']}' AND PASSWORD='{$_POST['password']}'"));
if($row['REFERENCE']) {
$_SESSION['secure'] = false;
// If everything is OK login
$_SESSION['id'] = $row['ID'];
$_SESSION['reference'] = $row['REFERENCE'];
$_SESSION['remember'] = $_POST['remember'];
// Store some data in the session
setcookie('unifyLogin',$_POST['remember']);
// We create the cookie
echo "success";
} else {
echo "failure";
}
?>
Share
Improve this question
asked Jan 3, 2013 at 13:39
user282835user282835
7
- 1 This question appears to be on topic for the Code Review beta SE site. – PleaseStand Commented Jan 3, 2013 at 13:46
-
I was hoping to (find some SQL injection), but it seems you've escaped your
$post
. Darnit :P – Cerbrus Commented Jan 3, 2013 at 13:47 -
You should ditch the deprecated
mysql_*
functions and go for PDO (or mysqli). – jeroen Commented Jan 3, 2013 at 13:47 - bear with me here, PDO? is that prepared statements? – user282835 Commented Jan 3, 2013 at 13:57
- The line if($row['REFERENCE']) { will generate an error if no match was found in the database: use isset(). Besides, my personal opinion is that it is nicer to use JSON to municate between PHP and JavaScript in situations like this, however that is just an opinion... When you implement the hashing, remember that JavaScript is capable of hashing too! Thus, you can hash the password in the clients browser, securely send it over the internet and catch it in PHP. That way the pass is not sent as plain text over the internet (which makes things a little saver) – Jeffrey Commented Jan 3, 2013 at 14:00
5 Answers
Reset to default 2The best way to ensure security on your website is to encrypt your passwords with SHA-512.
$rounds = 5000
$cryptedPwd = crypt($password, '$6$rounds=' . $rounds . '$SOMeSILLySTrInG$');
To decrypt :
$pwdEntered = trim($_POST['password']);
if (crypt($pwdEntered, $pwdHashed) == $pwdHashed){
// do something
}
You can also add a bruteforce protection, maybe with a logfile ...
I advise you to use PDO instead of normal mysql connect.
To answer question #3: Escape and sanitize untrusted data when inserting it into HTML, just as you would for a "conventional" PHP site. If the server returns unescaped text, use jQuery's .text() method to insert the text into an element; do not insert the text as HTML (e.g. $(...)
).
I think the answer to question #1 is already clear; there is a small percentage of users (including search engines) who cannot, or for privacy or security reasons, choose not to, run JavaScript. You might not want to deny service to them.
My ments pertaining to questions #2 and #4 are below.
var dataString = 'username=' + username + '&password=' + password + '&remember=' + remember;
jQuery can do this for you (including the query string escaping you are missing). Just store them in an object, which you can pass to jQuery instead of a string:
var dataObject = {
username: username,
password: password,
remember: remember
};
Also note jerome.s's suggestions to return AJAX responses as JSON and to avoid deprecated jQuery features. For JSON responses, ensure the outermost object is an object, not an array.
$_POST['username'] = mysql_real_escape_string($_POST['username']);
$_POST['password'] = mysql_real_escape_string($_POST['password']);
$_POST['remember'] = (int)$_POST['remember'];
// Escaping all input data
$row = mysql_fetch_assoc(mysql_query("SELECT ID,REFERENCE FROM USER WHERE USERNAME='{$_POST['username']}' AND PASSWORD='{$_POST['password']}'"));
The PHP MySQL extension is deprecated as of PHP 5.5. I would have used either the MySQLi extension or PDO. Both offer prepared statements, which allow you to avoid manually SQL escaping the parameter values.
To implement per-user salts, you will need to change this query. Specifically, you must retrieve the hashed password and corresponding salt and then hash the entered password with that salt. The hash puted should match the hash stored in the database if the password is correct.
if($row['REFERENCE']) {
$_SESSION['secure'] = false;
// If everything is OK login
$_SESSION['id'] = $row['ID'];
$_SESSION['reference'] = $row['REFERENCE'];
$_SESSION['remember'] = $_POST['remember'];
// Store some data in the session
setcookie('unifyLogin',$_POST['remember']);
// We create the cookie
echo "success";
PHP uses a rather permissive session handling model in that it will accept arbitrary session ID values, and your code does not regenerate the session ID upon a successful login. As such, your site may be vulnerable to a session fixation attack.
I also do not see any protection against either "login CSRF" or clickjacking.
Also note Jeffrey's ment: "The line if($row['REFERENCE']) {
will generate an error if no match was found in the database".
Edit: You also ought to implement rate limiting for unsuccessful login attempts (to slow down automated password guessing).
What is the general view when it es to this being JS dependant as opposed to pure PHP - do people put in redundancies, is it legitimate to simply say this is a JS only site (a huge amount of the website is based on the Twitter bootstrap, so its kinda reliant on JS).
Is my PHP and JS interfacing in the correct way? (and will my cookie still work?)
It's hard to say how many people today use internet with javascript disabled, but your javascript shouldn't be obstrusive, and your website should still work with javascript disabled. It's not too hard to do. Instead of using the .click()
for your AJAX query, you should use the .submit()
one and bind it to your form. That way you will still be able to process the form via PHP only.
And also that's one of the best practice not too bind a .click()
event on a submit button, otherwise I can't submit the form by pressing enter.
Then in your PHP you will be able to know if the request has been sent from jQuery by checking the $_SERVER['X-Requested-With']
.
And you can then have two different behaviours :
if ( isset( $_SERVER['X-Requested-With'] ) ) {
// es from jQuery
} else {
// basic submit
}
I think that's roughly how you should interface your app.
How can I create a secure way to now use jQuery .load() to bring in my content upon successful login?
You could just return true or false from your PHP. Or if you need to re-display some data you could pass a json object. Let's say you have an array of your data that you want to pass back
PHP
if ( isset( $_SERVER['X-Requested-With'] ) ) {
$data = array('success' => true , 'username' => $username );
return json_encode( $data );
}
Any general advice on making my system secure?.
You send the data in POST (via AJAX), that's not any less secure than POSTing your data the normal way.
The best password security method I've found is php's inner method, when of course using php for your logins.
http://php/manual/en/function.password-hash.php
password_hash("rasmuslerdorf", PASSWORD_DEFAULT);
password_verify('rasmuslerdorf', $hash);
It stores the salt in your dabatabase and does all the round checking for you.
Took me a long time to find this method after hours of reading into encryption & security and not only is it reliable, it is extremely simple to use.
I suggest you send the info through post and then use this. Also on the round trip, if you don't have a round trip someone could just jump over your javascript hashing and use the pure hash to login. This way if they attempt to use the hash it'll re-hash it and return it as wrong pw which is what it is.
You are using JS as just another way to interact with your server, instead of regular browsing. So its not less secure then any other page you request.
If you post the login credidentials to a PHP page to check the login, store the information like you would with a regular request (perhaps a session). Now every time you request data from your server with AJAX, check the session again server side before sending back the data. If its not authorized, simply return an error. In JS you can now check the responds and take action based on that.
My advise to making it secure is to develop every page as if it is requested by a regular browser. If you can do that, its also safe when using AJAX.
As a none-security advise. Dont make a javascript only site unless you are willing to sacrifice some visitors (older phones, tablets or just js disabled browsers).
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742277250a4413821.html
评论列表(0条)