Is it secure to use
If ($_SESSION['authenticated'] == true) {
/////Show secure page
}
Can someone just go and change where the session variable is stored to make their $_SESSION['autheticated'] = to true?
Same thing with a user having $_SESSION['id'] = to their index id. How would I be able to make this securer?
Could someone just go and change the id value and impersonate another user?
Would the below method be the right way to make something securer?
$_SESSION['random_check'] = (random number)
and also store this in a column in my database and each time I would
If ($_SESSION['authenticated'] == true && $_SESSION['random_check'] == random_number ) {
/////Then show secure page
}
Thanks,
I'm pretty sure Session in most hosting is just an interface to your filesystem, i.e. all Session data is stored in the server's hard disk, if you look at phpinfo() output, you can have a look at where the actual path of Session data is.
With that said, unless you chmod your session path to 777 and the attacker happens to know where you are hosting your app and has the login, then I don't think it's much of an issue.
The bigger issue here is securing your cookie as it's the piece of information that's going back and forth through your server and client, which attackers can use to impersonate legit users.
Yes,Is it secure to use. I use this.
I do this:
-check login,if is an valid login , set $_SESSION['logged'] = 'yes' and generate um token $_SESSION['token'] = 'the token'
this token, I save in an input html element and check in each action.
something like:
<?php
class token {
public function generateToken() {
return $_SESSION['token'] = md5( microtime() );
}
function generateField($name = "token"){
return "<input type='hidden' value='{$_SESSION['token']}' name='{$name}'>";
}
public function getToken() {
return $_SESSION['token'];
}
public function getTokenFromFields($method = "GET") {
return strtoupper($method) == "GET" ? $_GET['token'] : $_POST['token'];
}
public function checkToken() {
return $this -> getToken() == $this -> getTokenFromFields();
}
public function updateToken() {
$_SESSION['token'] = md5( microtime() );
}
}
?>
<?php
//orther file
require 'class.token.php';
$token = new token();
$Atoken = $token -> generateToken();
echo "<script>
var data = {};
data['token'] = '{$Atoken}';
data['foo'] = 'baa';
</script>";
$token -> generateField();
?>
<script>
$.ajax({type:"GET", url:"process.php", "data=foo=baa&token=" + data.token, success:function(response) { } })
</script>
In process.php:
<?php
if($_SESSION['token'] == $_GET['token']) {
//do something
} else die('bad token');
?>
Related
I created a system that sends the user id by Unity3D and on the server creates a session and sends the session back to the client (on Unity3D), so it all works! But when I send back from Unity3D to the server the session is simply gone! I already checked the browser and it works, it just does not work on Unity3D!
Does anyone have any idea what it is?
C# on Unity3d
void Start () {
WWW w = new WWW (url+ "?id=" + userId);
StartCoroutine (SessionWWW (w));
}
private IEnumerator SessionWWW (WWW _w){
yield return _w;
PlayerPrefs.SetString("cookie", _w.text);
Debug.Log (PlayerPrefs.GetString("cookie"));
Debug.Log (_w.text);
}
void Update(){
if (Input.GetKeyDown (KeyCode.P)) {
string session= PlayerPrefs.GetString("cookie");
WWW w = new WWW (url "?sessionid=" + session);
StartCoroutine (GetSessionWWW (w));
}
}
private IEnumerator GetSessionWWW (WWW _w){
yield return _w;
if (_w.text == "ok") {
Debug.Log ("received!");
} else {
Debug.Log (_w.text);
}
}
PHP script:
<?PHP
session_start();
if(isset($_GET['id'])){
$id = $_GET['id'];
$_SESSION['session'] = $id;
echo $_SESSION['session'];
}
if(isset($_GET['sessionid'])){
if(isset($_SESSION['session'])){
echo $_SESSION['session'];
}
}
?>
If your wanting to set the session id of the current session in PHP use the function session_id($id) BEFORE session_start.
https://www.php.net/manual/en/function.session-id.php
<?php
//do you need both of these?
if(isset($_GET['id'])){
$id = $_GET['id'];
session_id($id);
}
if(isset($_GET['sessionid'])){
$sessionid = $_GET['sessionid'];
session_id($sessionid);
}
session_start();
print_r($_SESSION)
?>
session_id ([ string $id ] ) : string
If id is specified, it will
replace the current session id. session_id() needs to be called before
session_start() for that purpose. Depending on the session handler,
not all characters are allowed within the session id. For example, the
file session handler only allows characters in the range a-z A-Z 0-9 ,
(comma) and - (minus)
you might also want to validate before setting the session id to prevent mistakes from your code and if this is on the internet other people can find it too.
(from the link above)
function session_valid_id($session_id)
{
return preg_match('/^[-,a-zA-Z0-9]{1,128}$/', $session_id) > 0;
}
$id = $_GET['id'];
if (session_valid_id($id)) {
session_id($id);
}
I am struggling with PHP login and user validation after they log on to the system. I know the basics but I'm not sure if I'm doing it right. I will try to explain it step by step.
I have a form for user name and password.
After users enter they login and password i'm using LDAP authentication to authorize them. And if authentication pass then i need to start new session.
New session (and this is where i'm struggling).
if ($validation->ldap_authentication())
{
$session = new session();
$session -> login($validation->getUsername(), $validation->logedAs(), $validation->getSID());
if($session->validate_login())
{
exit(header('Location:index2.php'));
}
else
{
echo 'error';
}
}
And my session class:
class session
{
public function __construct()
{
if(!isset($_SESSION))
{
session_name(SESSIONNAME);
ob_start();
session_start();
} else {
session_regenerate_id(true) ;
}
}
public function login($sessionUserName, $logedAs, $sid)
{
$_SESSION['logedUserName'] = isset($sessionUserName) ? $sessionUserName : null;
$_SESSION['logedAs'] = isset($logedAs) ? $logedAs : null;
$_SESSION['sid'] = isset($sid) ? $sid : null;
}
public function validate_login()
{
if (!isset($_SESSION['logedUserName']) || (trim($_SESSION['logedUserName']) == '') ||
!isset($_SESSION['logedAs']) || (trim($_SESSION['logedAs']) == '') ||
!isset($_SESSION['sid']) || (trim($_SESSION['sid']) == '')
)
{
return false;
} else {
return true;
}
}
}
So in the another pages i need to start a class session (again) and validate validate_login()?
For me it looks really poor authentication.
What do I need to add and improve?
I already searched online but couldn't find an answer and don't know what exactly I need to improve.
I'm a beginer in PHP, so my answer might be worthless.
I think you can trust the variable stored in $_SESSION as only the server can access them. So you could have a boolean $_SESSION['loggedIn'] that let you know that the user have gone through the login process successfully, and this variable would be accessible from any page.
I had to do a basic login system to protect a page, and I have no access to database so i store the username and password hard coded in php page.
My question is, can this login system hold againts an attack? I need it to hold about 1 month.
Any sugestions to improve will be helpefull.
The code is not in laravel, even if it might look like.
The username and password, will be changed to something stronger of course.
Thank you in advance.
<?php
class UserController {
private $username;
private $password;
private $isLoggedIn = false;
// Credentials
public function credentials() {
$credentials = array(
array(
"username" => "telekom",
"password" => "1234"
),
array(
"username" => "telekom2",
"password" => "1234"
)
);
return $credentials;
}
// Basic login
public function login() {
foreach ($this->credentials() as $credential) {
if ($this->username == $credential['username'] && $this->password == $credential['password']) {
Session::put('username', $this->username);
Session::put('password', $this->password);
$this->isLoggedIn = true;
}
}
}
// Get login status
public function isLoggedIn() {
return $this->isLoggedIn;
}
// Logout
public function logout() {
// Delete all sessions
Session::all();
redirect('/telekom/');
}
// Telekom
public function telekom() {
$form = new Form();
if (Input::get('logout') == 1) {
$this->logout();
}
// Post Data from login form
if (Input::has('username') || Input::has('password')) {
if (!$form->isCsrfValid()) {
$form->errors['CSRF'] = "CSRF Token";
} // CSRF protection is on, comment to disable
if (empty($form->errors)) {
$this->username = Input::get('username');
$this->password = Input::get('password');
// Check Login
$this->login();
if (!$this->isLoggedIn()) {
Session::put('login', 'Username and password do not match.');
} else {
redirect('/telekom/');
}
} else {
Session::put('login', '<p class="color-dark-red"><strong>Errors:</strong></p>
<p>' . $form->displayErrors($form->errors) . '</p>');
}
// Check if session has username and password
} elseif (Session::has('username') && Session::has('password')) {
$this->username = Session::get('username', false);
$this->password = Session::get('password', false);
// Check Login
$this->login();
}
}
}// EOF Class User
// Outside class
$user = new UserController();
// Outside class
if (!$user->isLoggedIn()) {
// display login form
} else {
// display protected content
}
?>
My comments are getting lengthy, so I'll just move them here. I would not recommend you put the username and password in the same file. If PHP ever fails to process the page, it will be dumped as plain text to the user. Even for database connections (where the un/pwd almost have to be stored plain text), most people don't put the information in the same file.
You have a couple options:
Make a separate PHP file that sets your UN/PWD variables, put it somewhere that isn't accessible from outside your server, and include it in index.php. In this case, I wouldn't include the file until right when you're going to compare the variables and let the local scope dump it as soon as possible.
Since this is such basic authentication, you could use Apache's built in password authentication module.
in my opinion, this solution is safe enough when you don't plan to use it forever.
What would I check is setting of your web server - some text editors makes backup copies of edited files, like index.php~, index.php.bkp or so. Make sure whether your web server do not serve those files, if any.
The problem with temporary solutions is that they've never temporary.
Never hard code passwords. Some of the reasons are:
It is harder to keep source code secret than it is a key.
Any vulnerabilities in your site that allow reading of source code may reveal the password.
Passwords from development will end up in production.
It is impossible to change passwords without redeploying.
I have read a lot about it but i still don't completely get it.
I may use a library of an existing solution in the future but i want to understand and implement my own system right now.
In order to be stateless and scalable I think i mustn't store user context on server.
The main problem is a conception one, if i understand the system i will succeed to code it
I have tested code found on Internet which i have modified (french website ref : http://blog.nalis.fr/index.php?post/2009/09/28/Securisation-stateless-PHP-avec-un-jeton-de-session-(token)-protection-CSRF-en-PHP).
Can you tell me if it's correct or if i don't get it?
So to create a token i use this function which takes as parameters, the user's data
define('SECRET_KEY', "fakesecretkey");
function createToken($data)
{
/* Create a part of token using secretKey and other stuff */
$tokenGeneric = SECRET_KEY.$_SERVER["SERVER_NAME"]; // It can be 'stronger' of course
/* Encoding token */
$token = hash('sha256', $tokenGeneric.$data);
return array('token' => $token, 'userData' => $data);
}
So a user can authentified himself and receive an array which contains a token (genericPart + his data, encoded), and hisData not encoded :
function auth($login, $password)
{
// we check user. For instance, it's ok, and we get his ID and his role.
$userID = 1;
$userRole = "admin";
// Concatenating data with TIME
$data = time()."_".$userID."-".$userRole;
$token = createToken($data);
echo json_encode($token);
}
Then the user can send me his token + his un-encoded data in order to check :
define('VALIDITY_TIME', 3600);
function checkToken($receivedToken, $receivedData)
{
/* Recreate the generic part of token using secretKey and other stuff */
$tokenGeneric = SECRET_KEY.$_SERVER["SERVER_NAME"];
// We create a token which should match
$token = hash('sha256', $tokenGeneric.$receivedData);
// We check if token is ok !
if ($receivedToken != $token)
{
echo 'wrong Token !';
return false;
}
list($tokenDate, $userData) = explode("_", $receivedData);
// here we compare tokenDate with current time using VALIDITY_TIME to check if the token is expired
// if token expired we return false
// otherwise it's ok and we return a new token
return createToken(time()."#".$userData);
}
$check = checkToken($_GET['token'], $_GET['data']);
if ($check !== false)
echo json_encode(array("secureData" => "Oo")); // And we add the new token for the next request
Am I right?
Sorry for this long message and sorry for my english.
Thanks in advance for your help!
The problem in your code is: You are basing your entire system on $_GET in the original post is based on Cookies.. You should store the token in cookies (based on your original post, instead of using $_GET
By the way; a few tweaks:
list($tokenDate, $userData) = array_pad(explode("_", $receivedData));
In the next code I don't see how you use $login,$password
function auth($login, $password)
{
// we check user. For instance, it's ok, and we get his ID and his role.
$userID = 1;
$userRole = "admin";
// Concatenating data with TIME
$data = time()."_".$userID."-".$userRole;
$token = createToken($data);
echo json_encode($token);
}
Can anyone see a problem with this line: $emailtoken = md5($user['User']['password'].CAKE_SESSION_STRING);
As it gives the following error: Use of undefined constant CAKE_SESSION_STRING - assumed 'CAKE_SESSION_STRING'
It still creates a token but gives that error and then when using the token it says that it is invalid :/
Here is the full function:
function admin_resetpassword ( $token = null )
{
// User submits their email address
if (!empty($this->data['User']['email']))
{
// user submitted initial form
$user = $this->User->findByEmail($this->data['User']['email']);
if (empty($user))
{
$this->Session->setFlash('Unknown email.');
return;
}
else
{
$emailtoken = md5($user['User']['password'].CAKE_SESSION_STRING);
// send email (temp flash to test code)
$this->Session->setFlash($emailtoken);
return;
}
}
// If the token is not empty on the url
if (!empty($token))
{
$user = $this->User->find(array("MD5(User.password + '".CAKE_SESSION_STRING."')"=>$token));
if (empty($user))
{
$this->Session->setFlash('Invalid token.');
return;
}
if (!empty($this->data['User']['password']))
{
$user['User']['password'] = $this->data['User']['password'];
$this->user->save($user);
$this->Session->setFlash('New password set.');
$this->redirect('/');
}
$this->set('token', $token);
$this->render('newpassword2');
}
}
the problem is CAKE_SESSION_STRING is not defined (as stated in the error).
If you want to get the salt or cipherSeed, use Configure::read('Security.salt'); or $this-Session->id; But you know this session id is lost after certain inactivity period, right? You won't be able to get that session id back later on (unless you save it somewhere).