Create image objects from password-protected urls in gwt - javascript

I want to present some images in my GWT application. These images are stored in a password protected url, external to my site in the general case. I can use the Image(java.lang.String url) constructor, with the user name and the password inside the url. So I can call:
Image img = new Image("http://user:pass#mydomain.com/image.png")
But then the user name and the password will be visible to anyone that views the source code of the page. I want to establish an authenticated connection with that url, and then use the plain url in the constructor:
Image img = new Image("http://mydomain.com/image.png")
I don't want to ask the user for a username and password through a popup, because in the general case he will be different than the one to whom the images belong so he won't have the credentials. The owner of the images gives to me their url, username and password when he registers.
Is this at all possible?

If your user does not have the credentials to view the images, then you will not be able to load them from your user's client. There is no good way to provide the password for them without also letting them see the password.
You could refactor this by sending the image request to your own server. Your own server could then send the request to the external server, password supplied, and pass the response back to your user. This is an extra hop, but you can keep the password completely secret.
If you're asking your users for their passwords to another site, you need to be extremely careful with them. In general, this sounds like a risky endeavor - you're exposing a lot of different ways to gain access to someone else's files. The fewer of those you can create, the better. If the external site supports some indirect authorization method like oauth, you should definitely prefer that over requesting the user's password.

You need to popup a window to that domain, and have the user fill in their username and password. For all subsequent requests to the same domain, you should not get a new popup. One way to do this, would be to create a hidden iframe to mydomain.com. That should trigger the auth popup.

Related

Is there a way to share a link with only a spefic mail recipient?

Not sure if this question should come to SO, but here it goes.
I have the following scenario:
A Flask app with typical users that can login using username / password. Users can share some resources among them, but now we want to let them share those with anyone, not users of the app basically.
Because the resources content is important, only the person that received the email should be able to access the resource. Not everyone with the link, in other words.
What I've thought so far:
Create a one-time link -> This could work, but I'd prefer if the link is permanent
Add some Javascript in the HTML email message sent and add a parameter to the request sent so I can make sure the email address that opened the link was the correct one. This assuming that I can do that with Javascript...which is not clear to me. This will make the link permanent though.
Any toughts? Thanks
The first time someone accesses the URL, you could send them a random cookie, and save that cookie with the document. On future accesses, check if the cookie matches the saved cookie. If they share the URL with someone, that person won't have the cookie.
Caveats:
If they share the URL with someone else, and the other person goes to the URL first, they will be the one who can access it, not the original recipient.
If the recipient clears cookies, they'll lose access to the document. You'll need a recovery procedure. This could send a new URL to the original email address.

javascript window redirect pass parameters securely (post)

I have a scenario where page navigation is done from one domain to another.
For example, navigation is done from
http://www.foo.com to
http://www.bar.com on button click in javascript
While redirecting, I need to send username and password securely from the first domain to the second domain.
How do I send these parameters?
I do not want to use GET and send it across the URL as it is not secure to send password in that manner.
Broswer's localStorage and SessionStorage did not work as the domains are different.
Window.open does opens the second domain in the same page ('_self') but the parameters are lost. On top of that window.open has the drawback of popup blockers blocking it
Cookie did not work.
I want to redirect from Site A to Site B and pass the username and password the user entered on Site A to Site B
You are not clear what your security implications are here:
While redirecting, I need to send username and password securely from the first domain to the second domain.
I do not want to use GET and send it across the URL as it is not secure to send password in that manner.
Is it site B should not know the password or is it you are concerned about someone listening on the request and replaying it?
At any rate, the only secure way is
Site A hands you a token (could be a JSON Web Token)
you send this token with the request to site B.
Site B takes this token and asks site A to validate it.
After positive validation, Site B creates a session for you.
Everything else (using POST instead of GET) is insecure as well, it is trivial to listen in to a POST request.
There are few ways:
1) Use a POST: Create a <form/> in your webpage and place some hidden variables on the fly using javascript and then post it to another website.
2) Use Headers: Can you see if you can set header?
3) Use Token: You can try using Token, which you can use instead of user+pwd combination. So what happens is you redirect from website A to B using a token embedded in the URL and website B validates the token to an API available on website A before it authenticates the user. You can make these token self-expiring after X seconds.

Storing information in cookies, and cookie manipulation of some other domain

We have a public facing website, in which the user can login using an email address.
After the user logs in, we populate the cookies of that domain with a uniquely generated session id, and the user details, like emailAddress, Name etc, based on which other calls are made to the server like getUserProfile etc.
However the problem, is any user can make changes to his hosts file, and write a simple Servlet to create the cookies of my domain, and can accordingly set any random session id and user details in the cookies, and then can get automatically logged in.
On the client side, how do I maintain that the appropriate session id is correct. If I maintain the session ids on the backend in some caching framework like memcache, then each hit on website every page will hit the server, which is not what i would want.
What is the way to get around this problem and ensure that the fraud user is not able to set my cookies after making changes in his hosts file.
On the client side, how do i maintain that the appropriate session id is correct.
You can't. The browser is controlled by the user. You control the server. You can only perform authentication on the server.

SINGLE SIGN ON SECURITY THREAT! FACEBOOK access_token broadcast in the open/clear

02/20/2011:
It was confirmed by Facebook today that indeed there is one call in which the access_token is broadcast in the open . . . it just happens to be one call I use to make sure that the USER is still logged in before saving to my application database. Their recommendation was to use the SSL option provided as of last month for canvase and facebook as a whole. For the most part the Auth and Auth are secure.
Findings:
Subsequent to my posting there was a remark made that this was not really a question but I thought I did indeed postulate one. So that there is no ambiquity here is the question with a lead in:
Since there is no data sent from Facebook during the Canvas Load process that is not at some point divulged, including the access_token, session and other data that could uniquely identify a user, does any one see any other way other than adding one more layer, i.e., a password, sent over the wire via HTTPS along with the access_toekn, that will insure unique untampered with security by the user?
Using Wireshark I captured the local broadcast while loading my Canvas Application page. I was hugely surprised to see the access_token broadcast in the open, viewable for any one to see. This access_token is appended to any https call to the Facebook OpenGraph API.
Using facebook as a single click log on has now raised huge concerns for me. It is stored in a session object in memory and the cookie is cleared upon app termination and after reviewing the FB.Init calls I saw a lot of HTTPS calls so I assumed the access_token was always encrypted.
But last night I saw in the status bar a call from what was simply an http call that included the App ID so I felt I should sniff the Application Canvas load sequence.
Today I did sniff the broadcast and in the attached image you can see that there are http calls with the access_token being broadcast in the open and clear for anyone to gain access to.
Am I missing something, is what I am seeing and my interpretation really correct. If any one can sniff and get the access_token they can theorically make calls to the Graph API via https, even though the call back would still need to be the site established in Facebook's application set up.
But what is truly a security threat is anyone using the access_token for access to their own site. I do not see the value of a single sign on via Facebook if the only thing that was established as secure was the access_token - becuase for what I can see it clearly is not secure. Access tokens that never have an expire date do not change. Access_tokens are different for every user, to access to another site could be held tight to just a single user, but compromising even a single user's data is unacceptable.
http://www.creatingstory.com/images/InTheOpen.png
Went back and did more research on this:
FINDINGS:
Went back an re ran the canvas application to verify that it was not any of my code that was not broadcasting.
In this call: HTTP GET /connect.php/en_US/js/CacheData HTTP/1.1
The USER ID is clearly visible in the cookie. So USER_ID's are fully visible, but they are already. Anyone can go to pretty much any ones page and hover over the image and see the USER ID. So no big threat. APP_ID are also easily obtainable - but . . .
http://www.creatingstory.com/images/InTheOpen2.png
The above file clearly shows the FULL ACCESS TOKEN clearly in the OPEN via a Facebook initiated call.
Am I wrong. TELL ME I AM WRONG because I want to be wrong about this.
I have since reset my app secret so I am showing the real sniff of the Canvas Page being loaded.
Additional data 02/20/2011:
#ifaour - I appreciate the time you took to compile your response.
I am pretty familiar with the OAuth process and have a pretty solid understanding of the signed_request unpacking and utilization of the access_token. I perform a substantial amount of my processing on the server and my Facebook server side flows are all complete and function without any flaw that I know of. The application secret is secure and never passed to the front end application and is also changed regularly. I am being as fanatical about security as I can be, knowing there is so much I don’t know that could come back and bite me.
Two huge access_token issues:
The issues concern the possible utilization of the access_token from the USER AGENT (browser). During the FB.INIT() process of the Facebook JavaScript SDK, a cookie is created as well as an object in memory called a session object. This object, along with the cookie contain the access_token, session, a secret, and uid and status of the connection. The session object is structured such that is supports both the new OAuth and the legacy flows. With OAuth, the access_token and status are pretty much al that is used in the session object.
The first issue is that the access_token is used to make HTTPS calls to the GRAPH API. If you had the access_token, you could do this from any browser:
https://graph.facebook.com/220439?access_token=...
and it will return a ton of information about the user. So any one with the access token can gain access to a Facebook account. You can also make additional calls to any info the user has granted access to the application tied to the access_token. At first I thought that a call into the GRAPH had to have a Callback to the URL established in the App Setup, but I tested it as mentioned below and it will return info back right into the browser. Adding that callback feature would be a good idea I think, tightens things up a bit.
The second issue is utilization of some unique private secured data that identifies the user to the third party data base, i.e., like in my case, I would use a single sign on to populate user information into my database using this unique secured data item (i.e., access_token which contains the APP ID, the USER ID, and a hashed with secret sequence). None of this is a problem on the server side. You get a signed_request, you unpack it with secret, make HTTPS calls, get HTTPS responses back. When a user has information entered via the USER AGENT(browser) that must be stored via a POST, this unique secured data element would be sent via HTTPS such that they are validated prior to data base insertion.
However, If there is NO secured piece of unique data that is supplied via the single sign on process, then there is no way to guarantee unauthorized access. The access_token is the one piece of data that is utilized by Facebook to make the HTTPS calls into the GRAPH API. it is considered unique in regards to BOTH the USER and the APPLICATION and is initially secure via the signed_request packaging. If however, it is subsequently transmitted in the clear and if I can sniff the wire and obtain the access_token, then I can pretend to be the application and gain the information they have authorized the application to see. I tried the above example from a Safari and IE browser and it returned all of my information to me in the browser.
In conclusion, the access_token is part of the signed_request and that is how the application initially obtains it. After OAuth authentication and authorization, i.e., the USER has logged into Facebook and then runs your app, the access_token is stored as mentioned above and I have sniffed it such that I see it stored in a Cookie that is transmitted over the wire, resulting in there being NO UNIQUE SECURED IDENTIFIABLE piece of information that can be used to support interaction with the database, or in other words, unless there were one more piece of secure data sent along with the access_token to my database, i.e., a password, I would not be able to discern if it is a legitimate call. Luckily I utilized secure AJAX via POST and the call has to come from the same domain, but I am sure there is a way to hijack that.
I am totally open to any ideas on this topic on how to uniquely identify my USERS other than adding another layer (password) via this single sign on process or if someone would just share with me that I read and analyzed my data incorrectly and that the access_token is always secure over the wire.
Mahalo nui loa in advance.
I am not terribly familiar with Facebook's authentication/authorization methods, but I do believe that they implement oauth (or something close to it) for delegation, distributed authorization, and "single sign-on".
OAuth is described by RFC-5849
EDIT: Facebook Uses OAuth 2.0 which is still in working draft.
In OAuth, and similar systems, the "access_token" is only part of the picture. There is also typically a secret key, which is known only by the service provider (facebook) and the client application (your app). The secret key is the only part that is expected to stay secret - and that part is never sent over the wire (after it's initial issuance).
In the case of Facebook, I think the secret key is assigned to you when you register your application to use their API, and the 'access_token' is returned to you for a given user, whenever the user agrees to allow your app to access their info.
Messages are sent in the clear, including the user's username, and the relevant "access_token"; However, each message must also include a valid signature in order to be accepted by the server. The signature is a cryptographically computed string, that is created using a technique called HMAC.
Computing the HMAC signature requires both the token and the secret, and includes other key parts of the message as well. Each signature is unique for the given message contents; and each message uses a nonce to ensure that no two messages can ever be exactly identical.
When the server receives a signed message, it starts by extracting the access_token (clear-text), and determining which app the token was issued for. It then retrieves the matching secret from its own local database (the secret is not contained in the message). Finally, the server uses the clear-text message, the clear-text access_token, and the secret to compute the expected HMAC signature for the message. If the computed signature matches the signature on the received message, then the message must have been sent by someone who knows the same secret (i.e. your application).
Have a look at Section 3.1 of RFC-5849 for an OAuth specific example, and further elaboration on the details.
Incidentally, the same approach is used by Amazon to control access to S3 and EC2, as well as most other service providers that offer API access with long-term authorization. Suffice it to say - this approach is secure. It might be a little counter-intuitive at first, but it makes sense once you think it through.
Adding a few links and quotes from Facebook Documentation:
Facebook is indeed using the HMAC-SHA256 algorithm. Registration document (PHP Example reading signed_request section).
Always verify the signed_request:
If you are unable to validate the
signed_request because you can't embed
your application secret (e.g. in
javascript or a desktop application)
then you MUST only use one piece of
information from the payload, the
oauth_token.
The Authentication Document contains a lot of useful info about the different flows you may use to authenticate a user. Also read the Security Considerations section at the bottom of the page:
Cross site request forgery is an
attack in which an trusted
(authenticated and authorized) user
unknowingly performs an action on
website. To prevent this attack, you
should pass an identifier in the state
parameter, and then validate the state
parameter matches on the response. We
strongly recommend that any app
implementing Facebook user login
implement CSRF protection using this
mechanism.
It was confirmed by Facebook that indeed there is one call in which the access_token is broadcast in the open - it just happens to be one call I use to make sure that the user is still logged in before saving to my application database. Their recommendation was to use the SSL option provided as of last month for canvas and Facebook as a whole. For the most part the Auth and Auth are secure.
To ensure a secure interface between a third party application and a Facebook application or even any website that uses Facebook Single Sign on, an identity question would provide the extra layer when used in conjunction with the access_token.
Either that or require your users to use Facebook with the new SSL feature of Facebook and Facebook Canvas Applications. If the access_token is broadcast in the open it cannot be used to uniquely identify anyone in your third party database when needing to have a confirmed identity before database interactions.

passing directly username and password to external site in iframe

I want to have a form on our main member page that they can submit on, and then I want to pass the username and password to the service which will be embedded in an iframe on our site to allow a seamless login.
Sorry, this won't work with the browser's security model for iframes. Methods for getting around this (i.e. pushing data into the name of a window) exist, but would be terrible for passing secret information like a password.
A real solution here will require something like the embedded site authenticating the user independently. OpenID could help you, here.
Passing secret information this way is really dangerous, do consider other options as this one will harm your users a lot.

Categories