How to start a valid user session inside an iframe - javascript

I need to setup a Master Site that would embed Site 1 and Site 2 in iframes, login and start user sessions within them.
Site 1 (RoR) and Site 2 (unknown framework) has got their own authentication (username, pass, cookies, usual framework security).
Master Site (PHP) server has direct access to Site 1 database and I know the password hashing algorithm so I can validate Master Site's login password against Site 1. Site 2 can get their passwords to be changed accordingly if needed, but no access to db nor framework.
I cannot change anything in either Site 1 or Site 2, unfortunately. I can only build around it though full read access to Site 1 is present.
I've sketched a quick diagram to better show what I mean/need:
a busy cat http://gettaxi.me/public_img/help.png
I need to start a user session inside an iframe. The login credentials of Site 1 are identical to Master Site's as they come from the same db, credentials for Site 2 will be assumed same (might just show login failed if they're not).
Idea list so far:
I could record the login credentials into Master Site cookie and use it to populate the iframe fields. Maybe store an encrypted version and decrypt when needed? But still, storing a password in cookies (even encrypted) seems absurd.
Same as above but store it in Master Site session variable.
The idea of cross-domain cookies seem useless here because every site has to set it's own session cookies, one website can't set it for another...
I've never dealt with anything cross-domain like this so before. So before I go and start coding things like a mad man that might or might not work - I turn to you for help and advice! How would you go about accomplishing this? Is this possible at all?
Additional questions:
Do cookies set by Site 1 and 2 from within iframes behave the same? Are they persistent and if I'd open the same website NOT in an iframe later, would they be accepted?
If storing credentials (cookies/session) is the only way to go: how would I then populate the login fields in an iframe and submit the form? Javascipt? Some neat GET/POST/redirection trick?
Thanks in advance!

Ok, it turned out to be quite simple. And to stick it to the downvoters ... face - I'll post my own solution here, who knows, maybe someone will find it useful.
User logs in to Master Site
Validate credentials
Generate a random client token
Encrypt the password with that token and store the crypto in a session variable
Set a cookie and store that token in users browser
jQuery actions when Link to Site 1 or 2 is clicked:
Send an ajax request to server with that token
Validate user session and decrypt stored password on success
Send the password back to client and pre-fill username and password fields of a hidden form that mimics the iframed website's login form
Submit that form with target="iframe"
Clear those form pre-filled form fields
Vuala, a working cross-domain iframe auto-login...
Of course there's more going on like hiding, unhiding divs on button clicks, session timeouts, token expiry renew upon any user action and so on, but the main thing is that it works! Yes, the password is sent in plain 3 times but none of those websites have HTTPS in place anyway. The password is not stored in plain either.
Update:
Spoke too soon. There are issues with IE and Safari when iframe content returns Access-Control-Allow-Origin headers. Their stronger security policies treat iframe content with caution and do not allow session cookies to be saved. It can either be fixed by dropping privacy setting by a notch in IE, allowing 3rd party cookies in Safari or simply detecting the browser and if it's one of the above - open it in a new tab/window.
Otherwise, works fine in: Chrome, Firefox, Opera and Maxthon

Related

How to log in remotely with AJAX?

I'm making a google-chrome-extension for a certain website, and want the browser_action to display the number of notifications a user has received on said website.
Currently, I am using an ajax request to retrieve the HTML from the website/messages page, and then I am using jQuery to count the number of "#unread > li" elements in that HTML (each one representing a new message.)
Now, I take this number and display it on the browser_action icon.
All works perfectly, the correct amount of messages are notified, BUT the user must be logged in on the site (not my site) for it to work properly, otherwise they will think that they have no messages.
I was thinking that I could detect if the user is logged in, and if not display a red ! exclamation mark on the icon. Then, when the user clicks to show the pop-up, it asks them to log in.
However, I have no idea how to actually log the user in to the website using this method: how do I send the credentials across? Or does the website have to support a request like this?
TL;DR
How can I log a user into a website I don't own remotely?
Disclaimer: I've never done a google chrome extension, but based on the rest of your question, it sounds like it's just working with JavaScript like any other web page, so I'll go ahead and answer it.
In any case, working with cookies in JavaScript can be somewhat of a pain:
https://developer.mozilla.org/en-US/docs/Web/API/document.cookie
http://www.perlscriptsjavascripts.com/js/cookies.html
I'm assuming that your server side already works with and expects cookies, so I won't try to suggest any alternatives. That being the case, your server is what needs to validate the cookie, so, IMHO, might as well set the cookie on the server side. If the server handles it, on the JS side, you simply post the username/password to a server-side page, e.g.
$.post("/user/login",{"Username":"foo","Password":"bar"},callback);
That server-side page validates the username/password and then, if successful, generates the cookie and sends a response back to the JavaScript (e.g. {"IsSuccess":true}). Upon receiving a successful response rather than an error, you just start calling the other web services to retrieve your data assuming you are logged in and build out the page.
Assuming that your web services will return HTTP error codes that help you determine a problem with the session, if you get a 401 error code, you take the user back to the login page. If you get a 403 error code, you let the user know they can't access that data...etc., all depending on your app.
Ultimately, JavaScript doesn't know whether a user is actually logged in, so you have to rely on the server to send you information in a way that is understandable so that you can direct/prompt the user as necessary.
[Edit: 2014-11-21]
You didn't answer my other question: what do you get back? If they don't set the cookie themselves at the login, then you need to get back the session token from the response they send...if they don't send you a session ID, you're SOL. If they do send you an session token/session ID, then you need to know what to name it (e.g. PHP uses something like PHPSESSID as the cookie name, but it can be whatever the coders of that domain decided on). Beyond that, you have to be able to set the cookie for THAT domain name (3rd party cookie). This may have mixed results depending on the user's settings--if they block 3rd party cookies--however, since this is a google extension and not a website, maybe it's able to bypass that kind of restriction. I know that FireFox's developer toolbar is able to manipulate cookies for all domains, so it would be a reasonable assumption you would be able to as well.

access cookies from email?

Is it possible to access cookies from an email? My fear is that one can for instance steal facebook login cookies simply by sending an email.
I know it's possible to redirect a user to an url without him to be aware of it. For instance, I used to display a 1x1 gif to redirect the user to a url (I used that to make email opening stats). What if on the target url I create a malicious js script: will I be able to access the user's cookies?
Or to put it differently, if there is a link in the email and the user clicks the link, is the target website able to access user's cookies?
I read this; does anyone have more details on the subject?
#user3345621
Thanks for your answer, it seems correct to me.
But to take on the facebook example again, I have a couple more questions:
I may be wrong, but I think the cookie encryption does not help in this case.
The cookie encryption will help to hide the password in case for instance I access
your local machine and look in the cookies directly.
However, if I steel the encrypted cookie, I will be able to use them,
and let facebook do the uncryption work.
So in other words, I think it does not matter whether or not cookies are encrypted,
as long as the application (facebook in this example) will decode them for you.
Now, same remark about the fact that the cookie is recreated.
I think this is a direct consequence of using session_regenerate_id function.
But anyway, my understanding (which may be wrong) is that even if the cookie is recreated,
if the hacker send you a malicious email, he will get the newest version of the cookies
anyway since in the technique I'm describing, you're redirected to a malicious website,
so that website, when opening would have access to the current cookies (if possible).
?
I might be incorrect, since I'm fairly new to application security.
Here goes my best shot, concerning cookies now:
Cookies are domain specific (FACT), when you have a facebook cookie storing your user ID and your email (perhaps?) only the facebook domain has access to that cookie. Also, in most cases, the information in your cookie, especially in enterprise systems such as facebook, is encrypted, in other cases a hash is used to mask the information (Sort of fact).
So let's take facebook as an example, since they use a strong encryption format (FACT). If for instance you were able to get hold of a users facebook cookie, you would need to de-crypt the information to start off with, for it to be of any use to you. By that time a new cookie would have been generated (darn facebook adddicts).
Onto the security issue, if by some means you were able to get hold of a users cookie that does NOT belong to your domain, it would be a hack (do'h!), and you would need to check for any browser (Yes you should be exploiting the browser), that has such an exploit, or look for one yourself..
So here they are:
Browser Exploit, hack a specific browser.
De-crypt (or de-hash) the cookie, if it's encrypted.
And do this all be for the cookie has expired.
And the world is yours.
I tried to send me an email with the following image:
<img src="http://localwebsite/js.php" />
On my local machine, I created a page at this url:
http://localwebsite/js.php
Which would alert("something") using javascript.
Sending the email to myself,
I expected that the mail client would open a web browser page and open the js popup,
but that's not the case at all.
What happened is that since it's not really an image,
my mail client (using mail on mac) did display a blue square exclamation mark,
indicating that he could not display that image.
Even if I click on "load images".
Then nothing more happens:
I presume the mail client goes to the url and tries to display the expected image in the message,
but since there is no image, nothing changes.
The url wasn't open in the browser at all, everything was done in the background.
Reading more about javascript in emails, it seems that generally, javascript is not interpreted at all
in emails.
I tested that too: sending an email containing:
<script type="application/javascript">alert("pou")</script>
Mail (mac) does not execute the script.
So to answer the question,
I believe that the only thing a hacker can do with mail is:
sending a link, then if you click on that link, anything can happen
create an image that he can use to track whether or not you've opened the mail
So if you're cautious enough, mail are'nt a big threat.
I was paranoid…

Make users logged in another site (which is of a different domain)

I am working on internal website, which is used only within the company. The requirement for one of its pages is to log-in to our vendor sites (which are all on different domains).
For this I open these vendor sites within an iframe of the internal website.
Say,
Internal site: us.com
Vendor sites: foo.com, bar.com
On us.com/openvendor , there are two options: foo and bar. When a user clicks on foo, the iframe within the page opens foo.com in signed in state.
To achieve this, I replicate the login form of foo.com and post all the required parameters like username, password etc. to foo.com's page. I have all the usernames and passwords of different vendors stored in database.
Why do I do this? Because we don't want the users of this site(mostly our CRM team) to know the passwords (lest they use it to do unwanted and untracked transactions) and the activities done through us.com is recorded and saved.
So essentially, we enable users to login to any vendor site, just by clicking on a link.
This was working perfectly fine until one day, when I had to add a new vendor site which doesn't post an html form for authentication. This site (say whattodo.com) makes an ajax call to a url with login credentials, which returns back an authentication cookie. This cookie is then set by the site to make the user logged in.
Now how can I make my end users login to whattodo.com on a click?
I cannot make the ajax call to whattodo.com
Even if I overcome the above problem by storing the auth cookie value in my database and updating it monthly(ya that's when the cookie expires), I cannot set this cookie under whattodo.com domain in the user's browsers.
Please suggest a possible solution.
And please feel free to edit the title. I'm sure there's a better one to summarize the question.

CSRF vulnerability / cookies question

Just want to get input from people who know. I was considering CSRF vulnerabilities, and the seemingly the most popular method I know to fight against it. That method is to create a token in the returned html and adding a cookie with the same value. So if a script tries to do a post they would have to guess the token thats embedded in the web page for it to be successful.
But if they're targeting a specific website why can't they just use a script that
Calls a get on the page (the cookie will be returned even though the script can't access it)
Parses the html and gets the token
Calls a post with that token in it (the cookie that came back will be sent back)
They've successfully submitted a form without the users knowledge
The script doesn't need to know the contents of the cookie, it's just using the fact that cookies get sent back and forth all the time.
What am I missing here? Is this not possible? I think this is pretty scary if you think about it.
Below this line is not required reading to answer the question :)
This vulnerability banks on the fact that authentication is done based on cookies, which I think is the main way authentication is currently occurring.
Another solution I can think of is making authentication be on the page level. So
when they log in the returned html will have that token in it. every link that they click contains that token so when the web server gets a request it has a way to identify the user/session. The problem with it is that if they use any navigation other than that they will be 'unauthenticated'(e.g. type in a url) , also it doesn't look nice in the url because it would probably look something like this:
https://www.example.com/SuperSecretPage/1/123j4123jh12pf12g3g4j2h3g4b2k3jh4h5g55j3h3
But I do understand that if safety is more important, then a pretty URL is second place.
I don't know everything about cookies but what if user agents were a little more careful with their cookies?
For example, what if the cookies sent depended on the tab? We all surf using tabs by now, right? so what if the scope of the cookie was the tab? so if i have my banking site open on tab 1 and i'm surfing on tab 2, any scripts calling gets/posts on
tab 2 will only send the cookies accrued in tab 2.
Or what if cookies were stored / domain. So while I'm on example.com any cookies that come back go into the example.com cookie collection. and then when i'm on www.mybankingsite.com all the cookies get put into the mybankingsite.com collection. So if I go to example.com and it runs a script that calls a get/post the user agent will only send example.com cookies. This is different than sending the cookies of the requested domain. E.g. if a script calls a get of mybankingsite.com within a web page of example.com the user agent will not send the mybankingsite.com cookies.
I know i have no control over what user agents do, but I'm just exploring possibilities
So I think the problem here becomes the attacker's attempt to get the page's contents. To get the authenticated user's page, the attacker needs to be able to send a request on their behalf and read the contents. AJAX won't send cross-domain requests, iframes won't let you read the response. I am struggling to think of other ways in which an attacker would get the contents first.
A more likely hack is using clickjacking to have the user just submit the form. This technique doesn't seem too likely. (caveat: it's security, we can always be wrong.)
Does anyone care to share some code on this issue as I just hacked my own site (Not in production) with CSRF. All I had to do was the following
At: www.badguy.com/ write the following html
img src="www.goodguy.com/secure/user/delete/5">
What this does
So the admin goes to to www.badguy.com/ and the the image makes a request to
www.goodguy.com/secure/user/delete/5 from the users browser so the admin unknowingly just deleted a user. If you create a loop your in some trouble. Expect I never delete data just change its status :) but still I don't like the looks of this.
The CSRF token has to be unique per session. If a malicious server requests the same page, they will get a different token. If they try to request the contents of the page via JavaScript on the client's machine, the same-origin policy will prevent them.

How can I automatically answer a password prompt from an embedded item in an (X)HTML page?

I wrote a web page that displays images from several servers on my network via simple img tags with appropriate href values. The servers require authentication before they will send the images.
It works alright, except on first load the page presents the user with a series of password prompts (one for each server). The user can select the "Remember my password" checkbox, and then subsequent refreshes of the page work without prompting, with correctly updated images. That is, until someone closes out the browser, after which a new set of prompts awaits anyone who opens the page again.
All of the credentials needed are known beforehand, and I don't care if someone could read them in the page source, since this page is in a protected part of an internal intranet site. Everyone with access to this page knows the passwords anyway.
The only browser we're allowed to use is IE 7, so I don't care about compatibility with other browsers at the moment.
Is there any way I can use JavaScript (or some other client-side code) to automatically answer those prompts so the user never sees them?
Thanks very much, in advance.
You can include the authentication in the URL:
<img src="http://paulfisher:tastybacon#internalwebs/path/to/image.png">
Where, of course, paulfisher is my username and my password is tastybacon.
No, javascript can't do this. Here are a couple of options that I've used before to solve this problem:
Change the authentication on the other servers to be either anonymous or integrated.
Proxy in the images: On the server serving the page, add another page that takes in the URL of the remote server. This new page makes a webrequest to the other server and streams the image back. The webrequest can plug in the correct credentials.
Depending on the servers' DNS names, it might be possible to share an authentication cookie across all of the servers. Then you could set up some kind of module on all of the servers to allow the shared authentication.

Categories

Resources