I use <input type="hidden" /> to pass some value so I want to make the hidden field is safe I have a user profile page I get username of member by this
$userprofilename = $_GET['username'];
when some body post any thing to user I get username of profile by
<input type="hidden" name="userprofile" value="<? echo $userprofilename; ?>" />
but in google chrome any body can change userprofile value, how can I make it safe?
thanks
Then instead of storing it in a public form, store it inside a server session
Instead of
$userprofilename = $_GET['username'];
Do
session_start();
$userprofilename = $_SESSION['username'];
And when they login, add their value to the session
// on login
session_start();
$_SESSION['username']=$userprofilename;
The best would be to not pass the client at all but keep it on the server-side. This is what sessions are for: store the value in the server-side session then you can retrieve it on form submission.
However, if you don’t want to use sessions, you can at least detect whether the hidden values got tampered by signing the hidden values using a MAC like hash_hmac. Here’s a simple example:
function create_hmac($key, $uri, array $params)
return hash_hmac('sha256', json_encode(array($uri, $params)), $key);
}
$secret = '7wzvtNgAVCTLPZ27P4L52yzc';
# on form creation
$hidden = array(
'userprofile' => $_GET['username']
);
$hmac = create_hmac($secret, '/form/submit.php', $hidden);
echo '<input type="hidden" name="hidden" value="'.htmlspecialchars(json_encode($hidden)).'">';
echo '<input type="hidden" name="hmac" value="'.$hmac.'">';
# on form submission
$hidden = json_decode($_POST['hidden'], true);
if ($_POST['hmac'] !== create_hmac($secret, $_SERVER['REQUEST_URI'], $hidden)) {
// invalid HMAC
} else {
$_POST = $hidden + $_POST;
}
your form page
create a session variable like this
session_start();
$_SESSION['userprofilename'] = $userprofilename;
instead of this hidden
<input type="hidden" name="userprofile" valu="<? echo $userprofilename; ?>" />
on your submit page
you can retrieve it as follows
session_start();
$userprofilename = $_SESSION['userprofilename'];
// use it as $userprofilename and then unset it
unset($_SESSION['userprofilename']);
this would be safe because session resides on server and can't be seen by the client. by view html source or firebug etc.
You can try by encrypting the username and then decrypting it where ever needed, if you don't want to use sessions
Related
I want to make an PHP session after the visitor enters a valid password so I can display a few hidden links to the visitor, even on page reload.
<?php
if(isset($_POST['submit'])) {
$password = crypt('sumpasswurd', password_hash('rasmuslerdorf', PASSWORD_BCRYPT)); // password
if (hash_equals($password, crypt($_POST['password'], $password))) {
echo 'VALID!';
// CREATE SESSION HERE
} else {
echo 'INVALID';
}
}
if(isset($_SESSION)) echo 'YOU ARE LOGGED IN WITH A VALID PASSWORD!';
?>
<form method="POST" action="">
<input type="text" name="password">
<input type="submit" name="submit" value="OK">
</form>
How can I make this possible? And is the encryption of my form secure?
Manual session starts with session_start() function. Although you need to secure the session by some kind of user indetification logic. For instance, you have user's username and add it as a session variable and afterwards pass some kind of session id to verify that current session user is indeed loged in. Afterwards you have to check those variables in every pageload that is associated with user.
At: // CREATE SESSION HERE you might want to use something like this:
Session_start();
$_SESSION['username'] = $username;
// flollowed by session id logic
I am having an issue right now with sessions. I use a log in script to do initial authentication, and then i authenticate at the begining of each protected page, and finally i try to log out (code below).
The files exist on my server using PHP 5.6. I am using Win10 and Chrome on my pc.
SYMPTOMS:
Although session vars are destroyed, i can still use the 'back' button in my browser to view a page that does authentication. When i dump $_SESSION vars on that page (which i browsed back to using the back button of the browser) all $_SESSION var are non existent - but the page still loads.
COOKIES are still there. I have set cookie lifetime in my php ini to 1 (one second) for testing... they are still there after i supposedly delete them. Even when set to 0, they are still there after i restart the browser.
After reading symptom 1 above, i think many of you will guess, correctly, that the session is still alive and well - even after i close the browser, restart it and type the url of one of the protected pages directly in the address bar i am still able to view the page, even though the $_SESSION var that checks for authentication does not exist.
Would really appreciate advice.
LOG IN SCRIPT
//this page is called (using require_once) by the page
//that captures username and password
session_start();
//requirements
require_once "../php/path.php"; //sets the server search path
require_once "constants.php"; //does all the DEFINE stuff
require_once HTML_HEADER; //loads HTML code - doc type, head etc
require_once DATABASE; //does the dB connecting
//collect the POST
$uName = $_POST[uName];
$uPsswd = $_POST[uPsswd];
//build & execute sql query
**SQL to retreive uName and password here if match then...**
$_SESSION['approved'] = 'true';
require_once MAIN_CONTENTS; //main page after authentic log in
exit;
AUTHENTICATE CODE CALLED USING require_once BY EACH PROTECTED PAGE
if (session_status() == PHP_SESSION_NONE) {
session_start();
}//end if
//what's the time Mr Wolf?!!!
$now = time();
//although session exists, are we logged in and approved? If not kill session & eixt.
if (isset($_SESSION['approved']) && $_SESSION['approved'] != 'true'){
require_once "killSession.php";
require_once "notAuthorised.php";
exit;
}//end if
if (!isset($_SESSION['approved'])){
require_once "killSession.php";
require_once "notAuthorised.php";
exit;
}
//if session exists, how old is it? If older than 'discard_after' then kill session.
if (isset($_SESSION['discard_after']) && $now > $_SESSION['discard_after']) {
require_once "killSession.php";
require_once "notAuthorised.php";
exit;
}//end if
else {
//logged in and approved so set timeout for 15 mins
$_SESSION['discard_after'] = $now + 30;
}//end else
THE killSession FILE
//check to make sure session exists - start if not
if (session_status() == PHP_SESSION_NONE) {
session_start();
$_SESSION['approved']='false';
}//end if
//following code caused 'headers already sent...'
//if (isset($_COOKIE[session_name()])) {
//$params = session_get_cookie_params();
//setcookie(session_name(),'',time() - 172800, '/', $params['domain'], $params['secure'], isset($params['httponly']));
//}
session_unset();
session_destroy();
session_write_close();
setcookie(session_name(),'',0,'/');
session_regenerate_id(true);
?>
Your issue is most probably caused by the POST data still being stored in your browser. By clicking the back button, your user is authenticated again and a session is created.
To resolve this issue you can use the POST-Redirect-GET method.
<?php
// Has the session been set?
if (!isset($_SESSION)) {
session_start();
}
// If a form is submitted, add the POSt data to a session
// and redirect
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$_SESSION['login_data'] = $_POST;
unset($_POST);
header("Location: ".$_SERVER['PHP_SELF']);
exit;
}
// Check if user wants to login, authenticate and unset login data
if (isset($_SESSION['login_data'])) {
// Authenticate
unset($_SESSION['login_data']);
}
?>
<form action="" method="POST" role="form" action="<?= $_SERVER['PHP_SELF']; ?>">
<label for="username">Username</label>
<input type="text" class="form-control" id="username" placeholder="Username"
<label for="password">Password</label>
<input type="password" class="form-control" id="password" placeholder="Password">
<button type="submit" class="btn btn-primary">Authenticate</button>
</form>
I have seen several instances of this question but did not get a clear answer. Here is my scenario
I have a form on login.php - this should submit to loginController.php
Once loginController.php validates against the databse, it should either redirect to home.php or pass back to login.php with appropriate success / error messages
I know I can pass information back-forth between pages using SESSION but I would rather avoid using SESSION for just messages and objects that are page specific.
In JAVA we can embed objects into request object and then forward the control to the next page. Is there something equivalent in PHP?
The way I am doing it at present is as below -
1.loginController.php has the main page and it includes login.php
2.login.php resubmits the data back to loginController.php (sorta recursive submit)
3.Then there is if-then-else logic to determine whether next redirect needs to go to home.php or just include login.php once again with error messages
From our discussion, I think the following snippet may do what you want. You can use $_SESSION variable to store user data and $_POST variable to discriminate if user has submitted username and password data:
Login Controller
/* Already logged in */
if(isset($_SESSION['username'])
{
header('Location:home.html');
}
/* Not logged in */
else
{
/* Login submitted */
if(isset($_POST['submit']))
{
$user = new User(); // this is an instance of model class
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
$password = filter_input(INPUT_POST, 'password', FILTER_SANITIZE_STRING);
$login_result = $user->login($username, $password);
/* Login success */
if($login_result == true)
{
$_SESSION['username'] = $username;
header('Location:home.html');
}
/* Login error */
else
{
$view_data = "Login incorrect"; // here you can set some data to be shown on login view
showView('login.html'); // pseudo code, change with your code to show login view
}
}
/* Show login form */
else
{
showView('login.html'); // pseudo code, change with your code to show login view
}
}
Login view
<?php if(!empty($view_data)) echo $view_data; /* Here you show login result (i.e. errors) */ ?>
<form method="post" action="login.html">
<input type="text" id="username" name="username" placeholder="Username" />
<input type="password" id="password" name="password" placeholder="Password" />
<input type="submit" name="submit" value="Login" />
</form>
Of course, you must implement $user->login method on user model (I strongly suggest you to use PDO statements to query database). This method simply checks user data and returns true on login success and false on failure.
On logout, simply unset($_SESSION['username']) and you're done.
I also suggest you to have a look on something like this session security question, to protect your session against hijacks. Hope it helps.
You can use query strings.
when you redirect to login.php as a result of an error, your full url will be something like:
login.php?status=error&message=invalid_credentials
in your login.php,
you can access the extra information as follows
$_GET['status'];//will contain the status
$_GET['message'];//will contain the message
Cheers!
I'm looking at doing a very basic authentication script as follows:
<?php
// admin.php
session_start();
if($_GET['login'] == 'adminLoginWord')
{
$_SESSION['auth'] = true;
}
if($_SESSION['auth'])
{
// code to show Admin control panel
}
else
{
echo 'Please login.';
}
Therefore, to login, someone would need to know to navigate to the URL
admin.php?login=adminLoginWord
Is this a safe way of authentication?
It's not safe at all, you would leave the "password" in the computer's history, it would be very vulnerable to anyone sniffing... etc
This said, safe always depends on the application, but if you want a safer approach, use a POST variable and compare it like so:
if($_POST['pass'] == 'password123'){
echo 'Login OK';
}
(Which still isn't the best approach, but it's better than a GET variable)
In this case in particular, I was just being thick, and making it more complicated than needs be.
A .htaccess file was more than sufficient for this... woops!
No it's not safe. You can hash your special login with sha1 and test if that sha1 is equal to the sha1 of 'adminLoginWord'.
Furthemore, in your case, you should use a POST.
You have to be aware that, if you use this system, your password will be stored in any browser saving history. One can even add this as a bookmark...
No it's not safe.
You should instead use POST and also use HTTPS
I understand your wanting to do easy basic authentication and everyone here has had valid security suggestions. If you really don't mind security but want it more secure than having credentials passed in the URL, you could try something like this (of course you could add a lot more HTML in the form/page area):
/* admin.php */
<?php
$username = "adminLoginWord";
$password = "adminLoginWordPassword";
$msg = "";
if ($_POST['mySiteUsername'] == $username && $_POST['mySitePassword'] == $password){
$_SESSION['auth'] = true;
} else {
$msg = "Invalid Username/Password Combination";
}
if(!$_SESSION['auto']){
$html = "<html>
<body>
<div class='error'>$msg</div>
<form action='admin.php' method='POST'>
<label for='mySiteUsername'>Username:</label>
<input type='text' name='mySiteUsername' />
<label for='mySitePassword'>Password:</label>
<input type='password' name='mySitePassword' />
</form>
</body>
</html>";
} else {
// Authorized
}
?>
Encrypt your password and then send it over GET or use POST
session_start();
$token = md5(uniqid(rand(), TRUE));
$_SESSION['token'] = $token;
This is how I start my code.
I , then, pass taht $token variable to a hidden field in the form:
<input type="hidden" name="token" value="<?php echo $token; ?>" />
but that condition is never true:
if($_POST['token'] == $_SESSION['token'])
{
echo 'Session was valid<br/>';
}
why?
Because you regenerate your token BEFORE checking it. You have to change it AFTER you're sure it's not the same
On page submit, a new value will be assigned to the session.
Try,
session_start();
if(!isset($_SESSION['token']))
{
$token = md5(uniqid(rand(), TRUE));
$_SESSION['token'] = $token;
}
Try echoing $_SESSION['token'] into the form instead of $token, in case you accidentally re-assigned it between the creation of the token and the form output.
I once had a problem very similar to this when I was developing something that took me ages to find, and it turned out that it was because I had left an <img src=''> in, because I didn't yet have the image - this caused the page to be requested again, since an empty src means 'this page', so the token was re-generated after the page was loaded.
Another thing to check is if the form's action attribute is missing, or some value that points to itself, the token maybe regenerated when the form is submitted, before the if (...) statement.
You could do something like this in order to prevent resetting the token on every page load:
session_start();
if (!isset($_SESSION['token']))
{
$token = md5(uniqid(rand(), TRUE));
$_SESSION['token'] = $token;
}
But... you may be better off session.referer_check or using some open source Session class that incorporates finer grained security than tacking this on top of the procedural standard. (if done correctly your code won't have to change wherever you actually use the session.)
see php.net/session_set_save_handler for more information.
the Code you provide is in one file and you submitting it to itself.
that regenerate the token and assign to the session variable. As said by "AVD" is the code to prevent the reassigning it
session_start();
if(empty($_SESSION['token'])){
$token = md5(uniqid(rand(), TRUE));
$_SESSION['token'] = $token;
}
then you can compare your condition where you are going to check.