Pass authentication between php and Ruby On Rails application - php

I have a simple Ruby on rails application that I want to integrate with an existing php website. I only want that users who's been authenticated by the php application would have access to my Ruby on Rails application (it should appear to the user as the same website, in the same domain, though it can be a different sub-domain if I chose to)
What's the best way to do that?
Thanks for the help,
Li

The most common way to keep a user logged in is to store something like current_user_id:777 in the user's session. Therefore, the easyest way is to share the session between the Rails app and the PHP app. Then, you must use the same convention to store the identity of a logged in user.
A way to do this is to use memcached as the session support.
Problems with this approach: you could set/read the same session variable in the same time from both apps (but it can be avoided).
References:
Storing your php sessions using memcached
Usind memcache as rails session store

The easiest way is to make use of cookies. In the PHP application, this cookie gets set, and the RoR application can read it's value.
But with cookies you'll have to watch out for security, because the contents of the cookie can be set manually, and cookies can also be copied, which allows for stealing another persons cookie.
Another option could be a session which is stored in a database both applications can make use of. The advantage of this option is that the contents of the session is stored on the server, and it can't be altered. The only thing you would have to handle is to identify the user belonging to the cookie.

Related

Session integration, is this approach secure?

A user logs in using default Laravel authentication, which puts an encrypted cookie in the browser, and saves the session in the database.
The user moves to a classic asp page, where I check the cookie value, get the hash, and call the laravel app back passing the session id hash.
Then I use that in laravel to see if there's an active session for that id, and if so I return true, so the user can be logged in, in classic asp.
On each page request in the classic app, I check the last_updated_time in the db and update it on each page. All logging in and out is done in laravel, and classic relies on the database to see if a session is active.
I would also call a public url to get sessions variables and add session variables using laravel, since it's all encrypted and using classic asp for this would be hard.
The only risk I see is session highjacking, but I don't think it's a higher risk than usual.
Is it important to lockdown the laravel URL I call to check if it's a valid session?
Am I missing a security hole here?
Is this method secure?
From what you've stated you probably haven't opened up any security holes. The session cookie is not itself encrypted on the users machine, but you are making sure it is encrypted between their machines and yours, as well as between each of your machines. You should make sure you've set the Secure Flag to help prevent the cookie being accidentally sent over traditional unencrypted transport (HTTP), but as stated, this doesn't effect storing the cookie itself.
That being said, you are essentially hijacking your own users sessions. While a hole might not be introduced now, you are potentially weakening the overall system, which could lead to hole in the future.
Is there a better way to do it?
This might well be a dumb question, but are you sure you need the session? If you're juggling credentials between servers, it sounds more like you want to use Access Tokens and scrap the session.
Using Access Tokens is similar to using sessions, but you need to make your services stateless. This means your no longer storing information about the logged in user any specific machine so you'll need to pull anything you need from the database every time they hit a server requiring that information.
This is a good thing in the long run as it's much easier to scale your services when you don't need to worry so much about where the session is and what's inside it.
OAuth 2.0 is widely used standard (Facebook, Twitter, Google), and was specifically designed to be easy to use. The RFC is complex, but there's a log of good guides out there don't worry.
The one slight down side (if you can call it that) to OAuth 2, is that it MUST happen over an encrypted connection. If your use case can not guarantee encryption over SSL or (preferably) TLS, then you should use OAuth 1.0 (WITH revision A) instead.
This is due to the fact that OAuth 2.0 exposes it's "secret" token in requests, where as OAuth 1.0 only ever uses it to provide a signature hash. If you take this route it's advisable to use someone else's library as the hash is very, specific.
Further Improvement
(Note: This section added after the answer was accepted)
One system I've been exploring recently is Json Web Tokens. These store information about the user to save each machine repeatedly looking it up in a database. Because the token is hashed with a secret, you can be sure that, so long as your secret isn't exposed, a valid token represents a successfully logged in user, without having to touch the database.
You should avoid putting anything too personal in the tokens if possible. If you must store private or secret information in the token, you can encrypt it, or you can use a reverse caching proxy to exchange the JWT for a traditional security token. This may initially seem to defeat the purpose, but it means some of your services may not need database access at all.
I'm no security expert but I don't see an issue with this. The packaged Laravel database session handler works the same way. The cookie contains a hash that references a record in the database. The session data is base64 encoded but that's neither here nor there. I think you could actually avoid rolling your own and just use Laravel's DatabaseSessionHandler.
Illuminate/Session/DatabaseSessionHandler
... I just read a little deeper into your question and noticed the part about the public URL to set and retrieve session data. I think this is a really bad idea. Mostly because it will provide an open door to the end user allowing them to read and write session data. This can only end badly.
Like I said above, the data is only base64 encoded so I believe you'll be able to parse, read and write that to your hearts content within asp.
Edit
Ok... I think this is the last edit. The data is php serialized and then base64 encoded. This question looks like it may help you to that end. If it doesn't and an API endpoint is the only way, find some way to block the end user from accessing it.
Aside from session-hijacking, no. This is the standard way applications interact on a internal basis. Of course there might be a better way to get at the data if you choose a different type of session store other than your database, Memcached for instance.
There are couple of things that can be done.
Make the channel HTTPS. It will make almost impossible to sniff on your transport layer.
Rather than making interactions with your cookie, you could use a JWT to get this task done. Which will help you to use the existing functionality in your system while connecting with ASP system as well. You can write a small REST web service which allows ASP to connect. You could use this lib. You can refer this article which will give you an idea how it should be done.
Please let me know if you need more information.

Can a user manipulate cookies?

I have a question regarding usage of cookies for standard login purposes. Say my php script saves a cookie into a users computer each time he logs in. The cookie value is say "Mike" after his username at the website. Can that user somehow manipulate that cookie in his browser to change the value to say "Admin" so suddenly he has access to administration of the website?
If this could happen how to solve such security risk?
--
Additionally... What if someone was to copy cookies from my browser, either he would stare at my computer screen and copy cookies and values into his computer or such intruder could steal cookies from my browser via JavaScript.
How is that taken care of?
Yes, that is a security problem, which extends to any information provided by the client.
Cookies are stored on the user's machine. They can be modified in any way. In fact, the cookies can just be created on the fly and sent via several utilities for making HTTP requests. It isn't even a browser problem.
Never trust any data that comes from the client.
Yes, a user can manipulate cookies if they're stored on their computer.
Use a session.
A 'session' is the server-side storage of connection-relative information that is linked to the user through a variable which is passed back and forth, most often a cookie, however logically, anywhere will do if both your client and server can handle it.
This 'session' is often represented by an integer which the client and server both know.
The problem is, if another client has a session open on the server, we (as a client) could 'hi-jack' this session by replacing our given id with a random id until one is found. The server would now believe we are in fact the other use and could give us access to their private informatin.
For this reason, we have 'keys'. A key is a unique, often alphanumeric, code which is changed on each request-response pair with the server, ensuring that only those who have the latest key are able to gain access.
YES
They can manipulate, edit, modify, create and delete cookies.
You should only store a hash key that you use on the server to look up in a database anything that should be secure.
Yes, users can manipulate cookies. The best way to handle it is to not store user credentials in such a manner that they can gain admin access by changing their user name.
The specifics on how to do this are pretty deep, but a good start would be to just store the users's session identifier instead. That has its own issues, but won't let people break things quite so easily.
Cookies are clientside which means that they can be read, write and delete by the client. A cookie manager plugin makes it easier to change the cookie value.
http://www.ehow.com/how_7149468_edit-cookies-computer.html
Yes a user can easily manipulate the cookies by just going to cooking option which all popular browser provide

PHP user authentication tutorial without sessions

I need to build my own system for part of a computer security project without using php sessions (just cookies) and im just lost. All the tutorials ive found use sessions (for good reason) so I was wondering if anyone knew of a roll your own php user authentication tutorial.
You could basically implement something session like yourself.
This would include the following tasks:
generate a random session id for new users (or on login - based on the exact use...)
save it into a cookie
do save additional session inforamtion somewhere on the server together with the session id (e.g. in a database table)
on subsequent page accesses check the session id in the cookie versus the data on the webserver to identify users and grant access
However it should be mentioned that a cookie only based solution is never that good. If a client for example doesn't have cookies enabled it won't work at all. A possible solution for this is to send the session id as GET parameter with every internal link if cookies are not enabled.
Sessions would make it much easier. That being said, where are you getting stuck mate?
To get started using Cookies in PHP, check this out: http://www.w3schools.com/php/php_cookies.asp
You could either
implement your own Session handling as s1lence suggests (which might be exactly what the professor wants you to do) or
implement your own Session handling through appending the session id to the QueryString (making it work for non-cookie browsers) or
you could store the user/password pair in cookies (which would force you to reauthenticate the user for every request)
I wouldn't recommend the latter, but if it's all about avoiding the Session Mechanism it's an option I guess. And a last remark, if this doesn't have something to do with understanding why Session is important you should really question your teachers task.. ;)
You should not use cookie for such system in cause cookie are stored on the client side. And any one can change it. Sessions are stored on the server side and only you can change it (also other system users can change it if they have directory access or db access if you store sessions in db). If you strongly need to use cookie you can encrypt login/password can write to cookie, but the using of sessions is more safely.

How to access session of one site from other site

I have website w1 written in rails using auhtlogic for authentication and w2 in PHP(say), I want w2 to access session information stored by w2 and login user into w2 and also retrieve user_id from session.
By default, Rack (which Rails uses to manage its sessions) stores session information in cookies by marshalling the session hash (see here), which results in a string that is specific to Ruby. It would be extremely difficult to use PHP to deserialize this information.
If you're dead set on doing this, you're going to have to handle the session serialization yourself. I think a full solution is outside the scope of a single question on SO, but a few pointers:
It would be wise to store only a session id in the cookie, and then keep the actual session data in a database that would be accessible from both the PHP and Rails apps. If you really want to keep the session information in a cookie (or in another place like memcached, where you'd also have to serialize it), look into serialization strategies that work across languages, like MessagePack.
You'll want to do something to ensure that the cookie is not tampered with by the user. Rack uses HMAC, which is a good solution. I've never used PHP, but I'm sure they also have a library for it.
You probably already know this, but just in case: This is all assuming that your two apps are sharing the same domain name. If they're not, then your users' browsers won't share the cookie between the two apps, and there's not really anything you can do. For example, you could share sessions between railsapp.yourdomain.com and phpapp.yourdomain.com, but not railsapp.com and phpapp.com.
Good luck!
i tried a solution sometime ago that was more a hack, but for my propose it worked.
after login, i used to write the user's cookie in a file in a public directory and when this user tried to access the other server where he had to access too, my application on this second server, just had to "know how to access" the remote file stored in the first server and load this content as cookie. I did used CURL at that time.
Note that it introduce some security breaches, and probably your security will rely on "obscurity" - for example, the algorithm to mount the file name where the cookie is stored and how to access it and any external webserver configuration.. Said that, i think we could think as well use a shared memcached to store the cookies..
Have you considered using Open ID?

Cookies/Sessions login system

When a user logins I get him/her's ID and save it in a session var. What I wonder is, is this the way to go? Or should I use cookies? so it automatically login and so on.
session_start();
ifcorrectlogin {
$_SESSION['id'] = mysql_result($loginQuery, 0, 'user_id');
}
how do you authenticate your users?
//Newbie
Yes, this is the way to go. The session itself is already backed by a cookie to remove you any programming efforts around that. The session (actually, the cookie) will live as long as the user has the browser instance open or until the session times out at the server side because the user didn't visit the site for a certain time (usually around 30 minutes).
On login, just put the obtained User in the $_SESSION. On every request on the restricted pages you just check if the logged-in User is available in the $_SESSION and handle the request accordingly, i.e. continue with it or redirect to a login or error page. On logout, just remove the User from the $_SESSION.
If you want to add a Remember me on this computer option, then you'll need to add another cookie yourself which lives longer than the session. You only need to ensure that you generate a long, unique and hard-to-guess value for the cookie, otherwise it's too easy to hack. Look how PHP did it by checking the cookie with the name phpsessionid in your webbrowser.
Cookies can be manipulated very easily. Manage login/logout with Sessions. If you want, you can store the users emailaddress/username in a cookie, and fill the username box for them the next time they visit after the present session has expired.
I would try to find a session engine so you don't have to deal with the misc. security issues that bite you in the ass if you do the slightest thing wrong. I use django which has a session engine built in. I'm not aware of the other offerings in the field although I would assume most frameworks would have one.
The way they did it in django was by placing a cryptographic hash in the user's cookies that gets updated every page view and saving all other session information in a database on your server to prevent user tampering and security issues.
As BalusC mentions, the session_-functions in php are the way to go, your basic idea is sound. But there are still many different realisations, some of them have their pitfalls.
For example, as Jonathan Samson explains, using cookies can result in security holes.
My PHP is a bit rusty, but I remember that the session_-functions can also use session IDs that are encoded in URLs. (There was also an option to have this automatically added to all local links (as GET) and form targets (as POST). But that was not without risks, either.) One way to prevent session hijacking by copying the SID is to remember the IP address and compare it for any request that comes with a valid session ID to to IP that sent this request.
As you can see, the underlying method is only the start, there are many more things to consider. The recommendation by SapphireSun is therefore something to be considered: By using a well tested library, you can gain a good level of security, without using valuable development time for developing your own session system. I would recommend this approach for any system that you want to deploy in the real world.
OTOH, if you want to learn about PHP sessions and security issues, you should definitely do it yourself, if only to understand how not to do it ;-)

Categories