Keeping $_session['username'] inside a ajax function - php

I've been messing with a script, and i'm now currently at the protection part.
Basically i cant manage to receive a $_session['username'] request.
I can not use cookies, as these can be faked. And it's a pretty big security hole.
Is this a common issue?
(The non-ajax and ajax page have the same session-id, and yes. i do use session_start();)
If you know any good comment-scripts it would be appriciated if you would like to link! c: )
edit:
The user logs in, and the session is started.
Now i'm combining a page/post with a modified comment script. (found here: http://tutorialzine.com/2010/06/simple-ajax-commenting-system/ )
What i've done is that i made it work with multiple pages, and removed the user & password thing that was provided with the script.
The request is something similar to this:
$user = $_session['username'];
if(!($data['user'] = $user)){
$errors['error'] = $_session['username']; //just to see if it can find the username
}
The above request returns a null value, but if i run "echo $_session['username'];" on the page that calls java, i get "powback".
EDIT:
i couldn't get this to work, but i made a bypass. I managed to insert $_session['username'] directly into the database with an other kind of validation. The current one was stupid... It should work properly now. Thank you!

How are you passing the session ID if not via a cookie? If you're passing it via URL (which is an even bigger security risk), make sure you pass it in the URL of your AJAX request.

Try this
var v="any variable to be passed";
$.post( "passingfile.php",{name:v},
function(data) {
Alert("Pass OK");
});
return false;
});
If you for the security try not to pass session id via url

you can use this inside any function or document ready. and change page name where you want to post value.
var postRecord = 'variable='+value;
$.post("PHP_Page_Where_you_are_using_session.php", postRecord, function(response,status, xhr){
if (status == "success") {
alert('done');
}
else if (status == "error") {
alert('Something went wrong, we are working to fix it');
}
});
on another page you can get post value within $_POST['variable'];
change name of variable to another one that you want to use.

Related

AJAX Login form, update page content after logging in

Imagine that I have a page, with a login/logout function in the header, which works fully via AJAX.
If a user isn't logged in, I want to show him "Hey, login" and allow him to login via ajax. That's all good, and it works.
But if the user logs in, I can't access anything that DIDN'T get put on the page -- the content that is there when the user accesses the page when they are successfully logged in.
If I view the page source, elements are there, but if I do things such as $("#container").show(), .slideDown(), .html(), none of them are doing anything.
Do I have to make the user refresh the page, or store all of the code in javascript to deploy? I hope not.
I've included my Javascript for the login below, but that's not really the point. That's working. Where I say $("#all").slideDown() is the problem. Even when accessing it through the console, it won't do anything.
The problem is probably related to dying with PHP if the user isn't logged in. This code is executed in $(function() { }
Code:
/* Get the AJAX Login form Ready */
$("#login-form").submit(function() {
$("#login-error").hide();
var username = $("#username").val();
var password = $("#password").val();
if (username == "" || password == "") {
$("#login-error").show();
$("#login-error-heading").html("You've entered something wrong.");
$("#login-error-content").html("Please enter both a username and a password.");
return false;
}
$.get(
"process-login.php",
{
username:username,
password : password
}, function(data) {
if (data.success == 1) {
/* Hide the login form */
$("#login").modal("hide");
/* remove the login button */
$('#nav-login').remove();
/* add the logout button to the DOM */
$("#nav-container").append('<ul id="user-options" class="nav pull-right"><li class="divider-vertical"></li><li class="dropdown">Logged in as ' + data.username + '<b class="caret"></b><ul class="dropdown-menu"><li>Logout</li></ul></li></ul>');
$("#all").slideDown();
} else {
$("#login-error").show();
$("#login-error-heading").html("You've entered something wrong.");
if (data.success == 3) {
$("#login-error-content").html("This account is locked out because of incorrect password usage. Please try again in 10 minutes.");
} else {
$("#login-error-content").html("The username and password combination was not found.");
}
}
},
"json"
);
return false;
});
First of all, I don't think it's a good idea to use AJAX to divide your presentation logic. I'd use PHP to detect whether they're logged in first, and separate the views accordingly.
If you must use AJAX to do this, I'd suggest redirecting because that's what I like when I log in. It feels like a fresh start. If you don't want to redirect, why don't you put all of the layout changes in a separate function like:
function openSesame() {
$('div.welcome_page').slideUp();
$('div.treasure_trove').show();
}
And call it in your AJAX's success setting.
Without code, we can't do much. I would check to make sure that you aren't attempting to use a bound event on something that didn't exist at the time of the initial bind. If something doesn't exist until your AJAX callback, then you'll have to bind it after it's been loaded.
I may be wrong, but I believe the issue is that your new content, while in the DOM isn't bound to any of the jquery event handlers. The way to bind events to future elements is to use the .on() method, like so:
$("#dataTable tbody tr").on("click", function(event){
alert($(this).text());
});
As #jamie said, don't mix JS and business logic if you don't have to.
This is where you need to use a templating engine, and make an attempt at building something that resembles MVC. Check out Smarty http://www.smarty.net/, or if you really want a legit MVC framework you can go with CakePHP or Symfony.
You do not need to redirect. It's slow and not exactly enjoyable for the user.
Let's just take a pseudo-code example using Smarty:
global $smarty;
//go grab your user object
$user = PseudoUser::validate_current_user();
if( $user->login_status === true )
{
//user is logged in
$smarty->assign( 'user', $user );
$smarty->display( 'logged_in_template.tpl' );
}
else
{
//user is logged out
$smarty->display( 'logged_out_template.tpl' );
}
Bada bing bada boom.
With the js ajax login, yes, you should just refresh the page in this case. Your PHP controller should have already established what to do when the page is reloaded.
It sounds like you have a javascript error on your page. I'm assuming your logged in section is being served over HTTPS. If that's the case, and if your javascript functionality is stored in a .js file, then you might need to include your javascript file over https as well.
Using a network path reference (or protocol agnostic path) helps resolve these kinds of https vs http issues.
<script src="\\js\myJsFile.js"></script>
Edit:
You might try the $.ajax function so that you can catch any errors that do occur... This might tell you more about what is actually happening with your request.
$.ajax({
url: "process-login.php",
data: {
username: username,
password: password
},
success: function (data) {
// your function
},
error: function (jqXhr, error) { // see http://stackoverflow.com/a/1956505/296889
alert("readyState: " + jqXhr.readyState + "\nstatus: " + jqXhr.status);
alert("Response Received: " + jqXhr.responseText);
},
dataType: 'json'
});

How to restrict my app to a single browser tab?

Frankly, it's just causing too much hassle in in v1.0 to have a functionality which requires three form submissions, with $_SESSION session data holding all of the intermediate stuff - only to have a user start an operation, then open a second tab and perform a second operation which tramples over the session data.
I doubt that this is malicious (but can’t discount it). More likely the user starts an operation, gets interrupted, forgets that they started or can’t find the original tab so starts again (then later finds the original tab and tries to complete the operation a second time).
Since I am coding in PHP I can detect the existence of session data on form submission (how would I do that with JS if the user as much as opens another tab – I guess that I would need Ajax – right?).
So, each time I start an operation I check for a flag in session data and if set I reload to a “I’m sorry, Dave. I’m afraid I can’t do that” page, else I set the flag and continue (remembering to clear it at the end of the operation).
I guess that that would work, but:
1) Is it acceptable to restrict browser apps to a single tab/instance?
2) Should I attempt to allow multiple instances in v2.0 ?
Any other comments, help or advice?
A better design would be to avoid storing user interaction state in the session. Put it in hidden form fields or something so that each client request carries its associated state with it. If you're concerned about the user tampering with it, use an HMAC to prevent that, and possibly encrypt it if it contains things the user shouldn't be able to see.
Only state that should be shared between tabs — like the user's login identity, or something like a shopping cart — should be stored in the session.
At most you can is keep a "last requested page" listing in the session file, with flags to indicate that the user shouldn't be allowed to move off it if it's one of these critical form flags. So if you're on form.php and it's a no-move-off one, then any new page loaded should present an "abort or close window" option.
You cannot prevent a user from opening up another tab/window, but you can prevent them from moving elsewhere in your site in those other windows/tabs.
However, consider that this is a very poor user experience. Imagine if Amazon trapped you in the shopping cart page and never let you on to another page without having to actually buy something. Consider updating your code to allow multiple different windows use the same form.
With every browser supporting tabbed browsing it would be a poor user experience to try to restrict browsing to a single tab (you might as well make a desktop app then).
One way you could solve this is by adding a CSRF token to your forms (as a hidden variable), that would be submitted with the request.
CSRF reference
There are many ways to generate the token, but essentially you:
create the token
store in your $_SESSION
output the form with <input type="hidden" name="{token name}"
value="{token value}" />
Then when the form submits you check $_REQUEST['{token name}'] == $_SESSION[{token name}]`.
If that token is different you know it wasn't the form you originally generated and thus can ignore the request until the real form comes in with the correct token.
One thing: if an attacker can figure out how you generate your CSRF tokens then they can forge requests.
Added the below script after I login(say dashboard.php)
<script>
$(document).ready(function()
{
$("a").attr("target", "");
if(typeof(Storage) !== "undefined")
{
sessionStorage.pagecount = 1;
var randomVal = Math.floor((Math.random() * 10000000) + 1);
window.name = randomVal;
var url = "url to update the value in db(say random_value)";
$.post(url, function (data, url)
{
});
}
else
{
var url = "url to remove random_value";
$.post(url, function (data, url)
{
sessionStorage.removeItem('pagecount');
sessionStorage.clear();
window.location = 'logout.php';
});
}
});
</script>
Added the below script in Header in rest of my pages - 'random_value' is from db for that user
<script>
$(document).ready(function()
{
$("a").attr("target", "_self");
if(typeof(Storage) !== "undefined")
{
if (sessionStorage.pagecount)
{
if('<?=$random_value?>' == window.name)
{
sessionStorage.pagecount = Number(sessionStorage.pagecount) + 1;
}
else
{
var url = "url to remove random_value";
$.post(url, function (data, url)
{
sessionStorage.removeItem('pagecount');
sessionStorage.clear();
window.location = 'logout.php';
});
}
}
else
{
var url = "url to remove random_value";
$.post(url, function (data, url)
{
sessionStorage.removeItem('pagecount');
sessionStorage.clear();
window.location = 'logout.php';
});
}
}
else
{
var url = "url to remove random_value";
$.post(url, function (data, url)
{
sessionStorage.removeItem('pagecount');
sessionStorage.clear();
window.location = 'logout.php';
});
}
});
</script>
If I were doing this now, I would probably code a single page AngularJs app (although any form of Js will do).
On start-up, look in local storage for a flag. If set, refuse to start, with suitable message, else set the flag & run the app.
Sure, a malicious user could get around it, since it's not a server-side check, but I would just refuse to support such.

How to call jquery function with php script...?

I tried to make a login module. I require the ability to show the message "UNAME OR PASS INCORRECT", but when uname and pass are not matching I am not able to display that error message div.
So does anyone have an idea about how to display that div when user is not authenticated?
Thanks in advance.
Like GOV said, you probably want to do this via ajax calls because it doesn't require the user to leave the page as he tries to login.
If you use jquery, the script would be very simple, such as :
$.post(url,{user:UNAME,pass:PASS},function(data){
try{
// EDIT: server MUST return response in text/plain as "true" or "false".
// EDIT: if(data) changed to if(data == "true")
if(data == "true")
window.location = redirectPage;
else
showError();
}catch(e){
showError();
}
});
function showError(){
$('#'+errorDivID).show();
}
where url is the url of the page that verifies the user & pass combination, which returns "true" if the user & pass values are true and "false" otherwise.
UNAME and PASS are variables that hold the user info,
redirectPage is the url of the page you want to redirect your authentificated users,
and errorDivId is the id of the div element that you want to show. The error DIV probably contains a warning message such as "invalid user+pass combination !".
Hope this helps!
EDIT: Edited to remove "eval" as it's not necessary if the server is returning a boolean.
I would presume you could do a jQuery POST to a PHP script that handels your login.
<form id='login'>
<input type='text' name='username' id='username'>
<input type='password' name='password' id='password'>
</form>
Then posting this form with jQuery instead of PHP
$.post("login.php", { username: username, password: password } );
This would post the username and password field to login.php. Then have login.php output something you can process in the same jQuery script. Have PHP return true if login is correct and false if not, then have jQuery display an error if the PHP script returns false and have jQuery do whatever as correct login if the PHP returns true.
Ashvin ,
You need to use ajax for this
http://api.jquery.com/jQuery.ajax/
make ajax call to the database and let php send a resposne back to the UI either success or failure.
If it is failure , lets show a div with different colors...
You indeed don't have to specifically use PHP for this. A good way to do this is the separation of model (your database with the user information and the queries used to access and retrieve data from it), your controller which is putting everything in motion and sending data to your template and your view (the template).
The above structure makes also clear that PHP is not specifically used for this, PHP should only have the role to access your database and give data back to the template.
Have a look at jQuery or Prototype with the Ajax examples, once you get the hang of that a whole new world opens up. :)

Delete file using a link

i want to have function like delete file from database by using link instead of button. how can i do that? do i need to use href/unlink or what?
Can i do like popup confirmation wther yes or no. i know how to do that, but where should i put the code?
this is the part how where system will display all filename and do direct upload. Beside each files, there will be a function for 'Remove':
$qry = "SELECT * FROM table1 a, table2 b
WHERE b.id = '".$rs[id]."' AND a.ptkid = '".$rs[id]."' ";
$sql = get_records_sql($qry);
foreach($sql as $rs){ ?>
<?echo ''. basename($rs->faillampiran).'';
?><td><?echo ' [Remove]';?></td><?
?><br>
<? }
?>
thankz all
The elegant way of doing this would be to use both PHP and JavaScript. PHP is a server-side language, and should probably be removed as much as possible from the client side stuff. One great way to do it would be to essentially create yourself an API.
The API would be a PHP script that deletes a row. It takes a variable in via GET and returns a boolean that says "yes we deleted the row" or "something went wrong." I like to use JSON, which in JavaScript is easier to work with than XML, and jQuery's getJSON function, a package that makes it really easy to get going.
In the .php file (we call it api.php later), if your results are successful return out success boolean. We use PHP's json_encode on an array, and echo out the result:
$variable = someFunctonToSanitize($_REQUEST['idToDelete']);
$query_to_run = "delete query using $variable";
$result = mysql_query($query_to_run);
// set headers
header('Content-type: text/json');
header('Content-type: application/json');
// if the query was successful, echo true
if($result) {
echo json_encode(array("success"=>"true"));
} else { // else echo false
echo json_encode(array("success"=>"false"));
}
In your JavaScript, here using jQuery (this is discouraged, see comments below):
$('#deleteLink').click(function(event) {
// prevent link from actually going anywhere
event.preventDefault();
// Fire off API request
$.getJSON("api.php?idToDelete=whatever", function(data){
if(data.success) {
alert("Item was deleted.");
} else {
alert("There was an error");
}
});
});
With a .post() request, per #Col. Shrapnel and #josh3736's comments (note: also changed $_GET to $_REQUEST to work with both):
$.post("api.php", { "idToDelete": "whatever" },
function(data){
if(data.success) {
alert("Item was deleted.");
} else {
alert("There was an error");
}
}, "json");
In your HTML:
Delete!
No links nor buttons can be used for the database interaction. It is server-side code to do such things. You have to understand that your application has 3 layers:
an HTML form
an server-side code
a database
the first one cannot interact with the last one directly.
So, on the one hand, it doesn't matter, with link or button you do call your server side code (the code remains the same).
But, on the other hand, there is a rule:
use GET method (link) to request information and POST (form/button) to modify it.
So, you should not use links to remove files, because some too smart bot can wipe all your database in a second.
As for your question where to place the code, just write a php script, unlink.php which deletes a file by hardcoded path. Then, after you've done that, make this file an action for the HTML form. Hardcoded one. Once you've done that - you can try to generate this form from your database.
This - step-by-step way - is the only possible way to develop a wab-application
Make a link:
Delete
Then make a delete.php that handles deleting and make sure you check that the session is authorised.
In PHP you use unlink() to delete a file. If you provide a page which accepts the file name (or better yet, file Id) as a parameter you can call unlink() on the file. Obviously there are some serious security implications which you will need to account for.
For confirm Delete, use this in onclick function()
In a href tag, itself :
<a href="" onclick="return ConfirmDelete();" ></a>
In upper Page use javascript like this,
function ConfirmDelete() {
var confm = window.confirm("Are you sure want to delete this !");
if(confm == true) {
return true;
} else {
return false;
}
}
For delete option give the same page link and pass the parameter and get the parameter by get function
<a href='samepagename?deleteid='.<?php echo $id;?>
In get parameter use like this,
$deleteid = $_GET["deleteid"];

How to deal with session timeouts in AJAX requests

I'm sure you're all familiar with the voting systems that use AJAX (Um... look right over there <----)
I have something similar and when you vote up or down it uses AJAX to request the new value from votes.php. The problem is that I am using a session to get the userid so a person can only vote once. What happens if they sit on the page for an hour and then vote so the session is no longer there? What would be a good way of handling this situation? Should I redirect their page to the login screen? If so, how can I do that from the votes.php page that is being referenced by the AJAX request? Am I overlooking a good way of handling this situation? Any advice would be helpful.
Consider returning an http status of 401, and a JSON object detailing the reason. If you're using jQuery, that'll drop you to the error() callback, which you can then parse your object.
$.ajax({
data: {},
dataType: 'html',
success: function(data) {
// do whatever here
},
type: 'POST',
url: 'myserver.com',
error: function(XMLHttpRequest, textStatus, errorThrown) {
// XMLHttpRequest.responseText has your json string
// XMLHttpRequest.status has the 401 status code
if (XMLHttpRequest.status === 401) {
location.href = 'login.php';
}
}
});
I'm not familiar with PHP anymore, but this should work for just about any environment. You may have to suppress any automatic login form redirection though. In asp.net mvc the framework will see the 401 and push the default login form back, with a status of 200.
You should only store a link to the users identity in the session. Use sessions to identify a user as x and then get user x's information from the database.
If your problem is with users sessions timing out then you should reconsider how you're using your sessions. Perhaps make them last until the browser closes? If you really want to make them a duration, then perhaps ping the server in intervals to keep the session alive.
Decide in your php script whether or not the user should be able to vote. If the session isn't set, or if they have already voted, return a message that you can identify with on the client side. If they already voted perhaps return "voted":"true" in a JSON object. Use JS to parse this object and understand what it means, taking the appropriate action. If the session isn't set, perhaps return "session_set":"false", and then make javascript redirect with a window.location = "login.php" etc.
Only increment the counter for the user on a successful return of a counted vote.
This is an old thread, but I wanted to share my solution that is working really well.
In my framework the system redirects the user to the login form any time they try to access a page and the session has timed out or is not valid.
I added to the top of the login form the following html comment:
<!--LOGINFORM-->
I created a wrapper for jQuery's $.ajax function which checks for this string on every request, and if it is there it shows a dialog popup saying that their session has timed out.
You can use this by just calling:
ajax.get('http://someurl.com', function(data){
//Do stuff
});
Hope it helps someone.
var ajax = {
check_login : function(resp){
if (resp.substring(0, 16) === "<!--LOGINFORM-->"){
// Show a popup or redirect them to login page!
return true;
}
return false;
},
get : function(url, success){
if (typeof data =='undefined'){
data = null;
}
$.ajax({
url: url,
type : 'GET',
success : function(resp){
if (!ajax.check_login(resp)) {
success(resp);
}
},
});
}
};
You structure the Javascript code that makes the Ajax request to accept a special result (say, -1 where a >=0 number would normally be, such as, a count of votes) to mean "sorry bub, you're timed out" and redirect to the re-login page (which can take as an optional parameter a message explaining to the user they timed out, &c).
You could create a javascript function that could ping the server every 10 minutes via something like
setTimeout("Ping()", 60000);
If you want to navigate the user to the login page if they connect with a faulty session then I would first verify the session and if it fails send a
header("Location: ...");
http://ca2.php.net/manual/en/function.header.php
From a user perspective, the best solution is to pop up a message and login form, saying something like "You are not logged in or your session timed out". Digg does this very well.
As for the actual AJAX implementation, swilliams' 401 suggestion is solid. Alternatively, you can simply return a specific string on failure.

Categories