PHP: is it safe to deserialize a file directly into an object? - php

In my PHP code, I create a 'session' object that stores user type, auth etc. (although no password in any form). Then I serialize this object into the $_SESSION var:
$_SESSION['sess_data'] = serialize($session);
when I need to authenticate the user, I do this:
$session = unserialize($_SESSION['sess_data']);
It looks very unsafe to me though. How can I improve it? Would some method as get_class() suffice? Thanks

Related

Object to Cookie in PHP

I am starting my studies in PHP and I'm having problems with an application:
I need to put information of an object in PHP for a cookie and then receive a cookie to object again on another page.
anyone has any solution to this problem?
The information I want to store in cookie is just some information preferably Customer as background color, size of windows.
<?php
class Client {
private $id;
private $pSize;
private $color;
function __construct($id) {
$this->id = $id;
}
public function getPSize() {
return $this->pSize;
}
public function setPSize($pSize) {
$this->pSize = $pSize;
}
public function getColor() {
return $this->color;
}
public function setColor($color) {
$this->color = $color;
}
}
?>
In a page index.php i have:
<?php
include_once 'Client.class.php';
//Test Preference Client
$client = new Client(1);
$client->setColor("#000000");
$client->setPSize(200);
//using Serialize to put to Cookie
$StringClient = serialize($client);
//Store to Cookie
$_COOKIE['PreferenceClient'] = $StringClient;
?>
In a another page i get the inrofmation:
if(isset($_COOKIE['PreferenceClient'])){
// Unsing Unserialize to Object
$objClient = unserialize($_COOKIE['PreferenceClient']);
//Test data:
echo $objClient->getColor();
//Continue with Performing changes to the client if the information exists...
}
I solved the problem. Thanks to everyone who helped.
before i had tried only get the cookie information without serialize
Guys, this is my first post, I apologize if I did something wrong.
I have to make something up for you?
You could store objects in string (like cookie does) via serialize, unserialize.
setcookie ($name, serialize($object)); // set object
$object = unserialize($_COOKIE[$name]); // get object
But remember that using this approach could be dangerous. PHP Object Injection
You could use json instead of serialization to store stdClass, it would be safe enough.
setcookie ($name, json_encode($object)); // set object stdClass
$object = json_decode($_COOKIE[$name]); // get object stdClass
But it's prefer to use session to store your data. You could even store object without calling serialize, unserialize. But __sleep, __wakeup magic still works.
setcookie, $_COOKIE, serialize, magic with serialization.
The answer is: You don't.
Whenever you take data from the client and use it in your code,
you have to implement security that prevents the case when the user changes his client data and injects something unexpected into your server. The client is easily able to fake and change cookie data, and thus to change your object.
Example:
If we serialize the object from Alma Do's answer and store the values in a cookie, the client/user could see our database auth settings from
public function __sleep() {
return array('server', 'username', 'password', 'db');
}
The client now can change his cookie to use a fake server instead of your server, fake your login / user table and pretend to be admin.
I think this is a case of XY Problem, please let us know what exactly is your goal.
This sounds more then a session function. You shouldn't transfer data over a Cookie. In Cookies you only save short information like a session token or a hash or some settings. To transfer and hold data the PHP session function is much better.
http://www.php.net/manual/de/book.session.php
In your session you can serialize some data if you want or save only an array or a value.
session_start(); // on every page
$_SESSION['test'] = "123123";
echo $_SESSION['test'];
to send serialized object you must use a specified thing like time() to bypass SPAM and control the timeOut!
session_start();
setcookie('myobject',serialize("Myvalue"),(time()+(3600*24*30)));
be sure to get stored on the session :
unset($_SESSION['myobject']);
Store your object
$_SESSION['myobject'] = unserialize($_COOKIE['myobject']);
Restore your Obecjt :
$mySeriaLizedObject = $_SESSION['myobject'];

php saving object in session

I'm trying to save an object in $_SESSION, but the following:
<?php
$user = db->load( $username, $pass ) ;
$_SESSION[ 'user' ] = $user ;
# on subsequent page loads:
$user = $_SESSION[ 'user' ] ; #retrieve the user from session
Unfortunately this doesn't work.
The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "User" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition
Unless you use serialize():
<?php
$user = db->load( $username, $pass ) ;
$_SESSION[ 'user' ] = serialize( $user ) ;
# on subsequent page loads:
$user = unserialize( $_SESSION[ 'user' ] ) ; #retrieve the user from session
I'm assuming a serialize is required because Session info is saved out to disk. But shouldn't PHP be smart enough to serialize stuff on its own?
And with the use of serialize/_unserialize_, is this going to work now reliably? Or do I need a __serialize() method in my PHP class?
You would need the __serialize() in your class if your object needs to perform some action before being serialized. For instance if it had a reference to an open file and that file needed to be properly closed before serializing.
Could you maybe use var_export? I only just learned about it today, so maybe it's not really that relevant.
As far as the php compiler is concerned all you are doing is writing an object (serialised) to an Array its a different process that ensures $_SESSION is available on the next page. Serialisation is nothing to do with being written to disk more to do with memory as the memory allocated to various methods on your object will not be available on the next page. Serialisation is how PHP holds onto objects accross pages, and you have to do it yourself.
Better Use
json_encode() json_decode()
Probably the best approach this days is to implement Serializable interface with your class.

How to store the object data in mysql db using php class function?

I have created a table in DB with name "member" having field "name", "college", "email", "zid" now I have created a class(in php) like
class member
{
private $name,$college,$email,$zid;
private function adduser
{
//function definition
}
public function autherise($id)
{
//function definition
}
}
now at index page I am taking these value as input from user using html form(validated by JS) now at action page of form I want to create object as obj=new member(); then calling the class function as obj->autherise($_post['zid']);
I want the defintion of autherise and adduser function like autherise check the uniqueness of zid and the calls adduser with remaining post variables and store them to object then add whole object in one query to DB.
I dont wan
insert into member(name,email,college,zid) values('$name,$email,$college,$zid')
I want to enter obj directly to the db
You can modify anything in functions
Thanks in Advance!!!
An "easy" solution to store a whole object somewhere, like in a database, is to serialize it – i.e. transform it to a string ; and, then, store that string in a single field in the database.
This can be done, in PHP, using the serialize function – and to de-serialize the string to an object, you'll use the unserialize function.
Another solution would be to serialize your object to the JSON format – nice thing with that is that JSON can be used directly from Javascript, and from lots of different programming languages, using the right libraries.
For JSON, see json_encode and json_decode
As a sidenote : note that if you store your data as serialized strings, it will be much harder to manipulate them in SQL : you will not be able to update them using a simple SQL query, for instance; and searching will be hard too.
This means you'll always have to fetch your data from the database, manipulate them with PHP, and send them back to the database – which might not always be such a good idea, depending on your needs.
I'm not sure what you're asking for. But maybe...just maybe you're looking for an object relational mapper (orm) , like e.g. doctrine.
If you were looking to store an object in a database you could serialize() or json_encode() the object into a String and then store it in a field in the table.
When you are ready to use it again you can unserialize() or json_decode() the String again.

Storing objects in PHP session

The PHP documentation says "You can't use references in session variables as there is no feasible way to restore a reference to another variable."
Does this mean I can't have things like:
session_start();
$user = new User;
$user->name = 'blah';
$_SESSION['user'] = $user;
I have tried to store a simple string and a User object in session, the string always persists between pages to pages, or after page refresh. However the User variable is lost in $_SESSION(becomes empty).
any idea?
Edit:
I have confirmed that session_id is the same in all of these pages/subpages,before & after page refresh.
Edit:
Strangely, after I tried serialize and unserialize approach below, the serialized user object(or string) in session still still disappears!
Edit:
finally I figured out what the bug was, looks like somehow $_SESSION['user'] gets overwritten by some mysterious force, if I use any variable other than 'user', then everything's fine. PHP(at least 5.3 which is the version I'm using) does serialize and unserialize automatically when you put object in the $_SESSION.
session_start();
$user = new User();
$user->name = 'blah'
$_SESSION['myuser'] = $user;
You need to use the magic __sleep and __wakeup methods for PHP 5 Objects.
For example in the following code block:
$obj = new Object();
$_SESSION['obj'] = serialize($obj);
$obj = unserialize($_SESSION['obj']);
__sleep is called by serialize(). A sleep method will return an array of the values from the object that you want to persist.
__wakeup is called by unserialize(). A wakeup method should take the unserialized values and initialize them in them in the object.
Your code example isn't using references as the documentation was referring to. This is what php means by references:
$var =& $GLOBALS["var"];
As to putting objects into the session, PHP can store objects in $_SESSION. See http://example.preinheimer.com/sessobj.php.
What you are seeing is a bug in the order of calls to __sleep and __destruct (__destruct is being called before __sleep) and the session module fails to serialize the object at shutdown. This bug was opened on Sep 1, 2009.
For safe serialization and unserialization encode and decode with base64_encode() and base64_decode() respectively. Below I pass a serialized Object to a session and unserialize it on the other page to regain the variable to an object state.
Page 1
<?php
require $_SERVER['DOCUMENT_ROOT'] .'/classes/RegistrationClass.php';
$registrationData= new RegistrationClass();
$registrationData->setUserRegData();
$reg_serlizer = base64_encode(serialize($registrationData)); //serilize the object to create a string representation
$_SESSION['regSession'] = $reg_serlizer;
?>
Page 2
<?php
session_start();
require $_SERVER['DOCUMENT_ROOT'] .'/classes/RegistrationClass.php';
$reg_unserilizeObj =
unserialize((base64_decode($_SESSION['regSession'])));
$reg_unserilizeObj->firstName;
?>
This article describes issues that may be faced by not doing so.
issuses with php serialization/unserialization
You were right saying you can not store references in sessions variables
assigning an object in PHP 5 and above is doing just that assigning the reference not the obj
That its why you would need to serialize the object (implementing also __sleep in the Class) and assigning the string to a session variable
and deserializing it later (implementing also __wake in the Class) from the session variable later on.
That's the expected behavior. Storing a reference to an object would only work if the memory location for the object didn't change. In a stateless protocol like HTTP, application state is not persisted between requests. The next request may be handled on another thread, process, or another server.
Given the inherent stateless nature of a web application, holding a pointer to a memory location is useless. Therefore the object's state must be broken down into a storage format, saved or transmitted, and then reconstituted when needed. This process is known as Serialization.
You can choose to serialize the entire object into session (which maybe dangerous depending on the depth of your object graph, since your object may hold references to other objects and those would need to be serialized as well), or if the object can be reconstituted by querying the database on the next request you may just stash an ID in the session.
[EDIT]
JPot pointed out that objects are automatically serialized to $_SESSION, so explicit serialization isn't necessary. I'll leave the answer for posterity, but obviously it doesn't help your problem.

Using objects in Ajax calls PHP files

I have instantiated a class in my index.php file. But then I use jQuery Ajax to call some PHP files, but they can't use my object that I created in the index.php file.
How can I make it work? Because I don´t want to create new objects, because the one I created holds all the property values I want to use.
Use the session to save the object for the next page load.
// Create a new object
$object = new stdClass();
$object->value = 'something';
$object->other_value = 'something else';
// Start the session
session_start();
// Save the object in the user's session
$_SESSION['object'] = $object;
Then in the next page that loads from AJAX
// Start the session saved from last time
session_start();
// Get the object out
$object = $_SESSION['object'];
// Prints "something"
print $object->value;
By using the PHP sessions you can save data across many pages for a certain user. For example, maybe each user has a shopping cart object that contains a list of items they want to buy. Since you are storing that data in THAT USERS session only - each user can have their own shopping cart object that is saved on each page!
Another option if you dont want to use sessions is to serialize your object and send it through a $_POST value in your AJAX call. Not the most elegant way to do it, but a good alternative if you don't want to use sessions.
See Object Serialization in the documentation for more informations.
mm, you should store in session, $_SESSION["someobj"] = $myobj;, and ensure that when you call the Ajax PHP file this includes the class necessary files which defines the class of $myobj and any contained object in it.
Could you be more specific? I can try.
This is how I create an object then assign it to a session variable:
include(whateverfilethathastheclassorincludeit.php)
$theObject = new TheObjectClass();
//do something with the object or not
$_SESSION['myobject'] = $theObject;
This is how I access the object's members in my Ajax call PHP file:
include(whateverfilethathastheclassorincludeit.php)
$theObject = $_SESSION['myobject'];
//do something with the object
If you don't want to move your object that is in your index.php, have your ajax make a request to index.php but add some extra parameters (post/get) that let your index.php know to process it as an ajax request and not return your normal web page html output.
You have not provided code, but what I guess is that you need to make your instantiated object global for other scripts to see it, example:
$myobject = new myobject();
Now I want to use this object elsewhere, probably under some function or class, or any place where it is not getting recognized, so I will make this global with the global keyword and it will be available there as well:
global $myobject;
Once you have the object, you can put it into the session and then utilize it in the Ajax script file.
As others have suggested, $_SESSION is the standard way to do it, in fact, that was one of the reasons, that sessions where invented to solve. Other options, i.e. serializing the object rely on the client side to hold the object and then return it untampered. Depending on the data in the object, it is not a good solution, as a) the object may include information that should not be available on the client side for security reasons and b) you will have to verify the object after receiving it.
That said, and if you still want to use the object on the client side, then JSON is an option for serializing object data, see JSON functions in PHP.
Based on most of the answers here, referring to storing the object in $_SESSION, is it more efficient to store only the individual properties that need to be accessed in AJAX as opposed to the whole object, or does it not matter?
E.g.
$_SESSION['object'] = $object;
vs
$_SESSION['property1'] = $object->property1;
$_SESSION['property2'] = $object->property2;
I know the OP is asking about accessing the entire object, but I guess my question pertains to if it's just a matter of only accessing certain properties of an object, and not needing to access methods of a class to alter the object once it's in AJAX.

Categories