I can't believe that I'm asking this right now, but I have no idea how solve the following problem:
I have a web app that logs every visited page in a browser for better browser history search. The extension is a chrome extension that needs to make a POST request to my API. Obviously, I need to avoid CSRF issues, i.e. other sites using the user's session to post arbitrary data to his browser history. However, since the extension runs in a different origin as a content-script, I cannot retrieve CSRF tokens, hence I cannot make authenticated POST requests.
EDIT:
So I now know that I can use chrome.storage (and equivalents in other browsers) to store a token that only my content_script can read. However, I still haven't solved the issue of how getting that token into chrome.storage in the first place
I seem to miss something really obvious ...
I suspect a content script isn't necessary, and you should just be using the chrome.webNavigation API from your event page to get the user's browsing activity.
You'll still need the user to log into your service somewhere in the browser. If you take your service's origin as a host permission, your extension will be able to make XHRs as the user, which may be enough to solve your XSRF problem, at least as long as nobody else can intercept the user's login cookies.
FYI, I realized that chrome.storage provides a means to sync/pass confidential data like your token that is only accessible to your scripts.
Hence, the solution is to visit a webpage of yours, and have a content script extract the token and store it in chrome.storage.
Related
I've made a web app that stores persistent user data in localStorage. I've enabled HTTPS on my site, and I'd really like to flip the switch on HSTS. However, as far as I can tell, localStorage considers http://example.com and https://example.com to be different, so if existing users are redirected to the HTTPS version of my site, they can no longer access their data (though it still exists).
Long term, I want to build a new version of this app that offers more options for data storage. But in the short term, all I can think of is having a transition period where users at the http version are asked to migrate their data via some other (unknown) mechanism that both versions can access.
Is this a fair assessment of my options? Is there a way for https://example.com to access the localStorage of http://example.com? If not, is there anywhere I can put user data such that both versions can access it but other sites can't? Or should I ask them to download their data and re-upload it? That doesn't see ideal from a UX or (user) security standpoint.
Note that this web app doesn't interact with a server at all; everything happens with localStorage and the client.
Unfortunately there does not seem to be any way to directly retrieve localStorage contents for the less secure http copy of the site from the https site. reference
The workaround I have seen is to use an iframe loading a special page on the insecure site similar to this answer. The general theory is to have code in the iframe that sends messages using postMessage with localStorage data back to the secure page.
Unfortunately this approach does not allow you to disable http entirely, because otherwise your iframed http copy would not load.
I am trying to embed facebook auth into my application.
My initial effort was to login in browser and obtain code. I pass this code back to my api and obtain access token (that stays with the server) and route all my requests to FB Api through my server. Seemed totally secure to me as my client has no information to be able to make authorized calls to FB as my app.
I however have been looking at FB Javascript SDK to avoid writing code for dialog opening and closing and noticed that it allows me to getLoginStatus and returns me the access token. Also, I went over FB auth flows in their documentation and they say that client-server hybrid flow is okay to do where server actually gives "Long lived access token" back to the client and advises me to use HTTPS (fair).
Now all this gets me thinking if this is a security concern. Can't I as a potential hacker inject some javascript into the user's webpage that could either a) make a getLoginStatus and get the access token or b) just get the access token by making a request to my api server and get the access token and then use that to post (assuming that user authorized my app to do so) to facebook as if my app was doing it?
I am a security newbie and maybe overlooking a bunch of stuff here but could someone help me understand what I'm missing?
Thanks in advance!
PS: I do know I can enable further security to ensure that I need the app secret every time I want to make a request which the client can't do as that information will never be available on client side.
I am not a security expert, just some thoughts: in your question, you are assuming that the hacker somehow injects the script into the webpage in the user browser using malware and that script then interacts with the data you have client-side.
Now, if we imagine this actually happened and the evil script has full access to the web-page data, even if you don't have the access token on the client, what prevents the evil script to make requests to your server and interact with facebook through your server?
Moreover, if the user opens facebook itself and authorizes there, the evil script could be injected into facebook page and do any actions on behalf of the user, just sending the requests to facebook server.
This way, it looks for me that if the situation you describe happened, it would not really matter if you storing the access token client side or not - anyway the evil script will be able to do it's job.
Practically, if you are worried about security - first carefully check all the facebook docs related to authentication and security and follow their recommendations. Second - search for common known attack vectors and recommendations of how to avoid security risks in your application.
If the user already has malware on his computer which is able to alter browser behavior (like inject additional scripts into pages), you probably can't do much about it.
You can only get your access token if you have a valid redirect URI which equivalent to your Site URL on your facebook application settings..
also, it needs permissions before you can post using the facebook access_token.
You can check the API calls at https://developers.facebook.com/tools/explorer/
Let's say, I'm a logged-in user in google.
Now I'd like to send one ajax request there WITHOUT sending any cookies.
(But naturally, I want to keep those cookies for the future).
How is that possible?
i'm interested in solution for ajaxing INSIDE chrome extension
important edit: I'm talking about intercepting requests sent FROM the extension itself! There the beforeHeadersSend don't work...
I have been working on a Authentication and authorization module similar to how stackexchange is in place. Now I am sure they use a certain model of oAuth or a token generation server that authorizes uses to their various sites. I tried a little experiment.
Once I am logged into Stackoverflow, I delete all my cookies from the developer console.
I leave my localstorage object intact which contains a key se:fkey xxxxxxxxxxxxxxxxxxxxxxxxx for stackoverflow domain.
there is another key for stackauth domain GlobalLogin: xxxxxxxxxxxxxxxxxxxxxxx
the se.fkey if I used for a session hijack, nothing happened. but the GlobalLogin, I was able to copy and hijack my session. So, my query would be, how does S/O deal with the authorization post authentication for each one of the sites. Also, is there a way to invalidate the globalLogin for them after it is used once?
{EDIT1}
So, just the globalLogin alone is enough. If you can get that key, just open a private browsing instance. In the Localstorage for stackauth when you are in the login page, create the key-value mapping and refresh the page. You will be logged in.
{EDIT2}
The globalLogin key seems to be consistent across multiple sessions. It has been a day and no refresh of my globalLogin key. Safe to assume if you key is hijacked, the attacker will have access to your profile indefinitely.
{EDIT3}
For everyone who is voting and will vote for this question as not a programming related question. Let me put it this way, how do we store SSO's on the web browser with localstorage safely and since they are prone to get compromised, what do we need to do prevent it from happening? One of my colleagues was considerate enough to give me his GlobalLogin key, I was able to hijack his session from a different computer albeit it was on the same network.
PS: This is purely for theoretical understanding that I did this.
Well, rather than looking at the vulnerability, let's look at the possible attack vectors. I'll add a table here as a TL/DR
Attacker | Vulnerable?
Eavesdropper | Yes
MITM | Yes
Local Attack | Yes
Server Attack | Yes
So yes, it is an issue.
Remote Attacker, can observe traffic, but cannot modify traffic
Consider this a passive attacker in a coffee shop. They can see all of the TCP level traffic.
The requests back and forth to SO are -by-default- not encrypted. You can browse via HTTPS, but by default it's HTTP only.
So an attacker can see any request go by, and inspect/steal the data.
So let's see if the GlobalLogin token is ever sent in a request...
As a matter of fact, it is. On the login page, a request is sent via an iframe to the following URL:
https://stackauth.com/auth/global/read?request=//snip//
That URL returns a script:
var data = {
"ReadSession":"https://stackauth.com/auth/global/read-session",
"Request":"//snip//",
"Nonce":"//snip//",
"Referrer":"//snip//",
"StorageName":"GlobalLogin"
};
var toMsg = window.parent;
var obj = localStorage.getItem(data.StorageName);
if(obj != null) {
var req = new XMLHttpRequest();
req.open(
'POST',
data.ReadSession+
'request='+encodeURIComponent(data.Request)+
'&nonce='+encodeURIComponent(data.Nonce)+
'&seriesAndToken='+encodeURIComponent(obj),
false
);
req.send(null);
if(req.status == 200){
toMsg.postMessage(req.responseText, data.Referrer);
}else{
toMsg.postMessage('No Session', data.Referrer);
}
}else{
toMsg.postMessage('No Local Storage', data.Referrer);
}
Now, notice that the GlobalLogin is sent over HTTPS to the server. So a remote attacker, who can read traffic will not be able to get the GlobalLogin token.
So the GlobalLogin portion is safe from eavesdroppers.
However, note that it's still quite vulnerable to sniffing the session cookie, since it's sent over HTTP.
Remote Attacker, can modify traffic (MITM)
Well, here's where things get interesting.
If you can modify traffic, you can do something really fun.
The initial page creates an iframe bringing in the above stackauth.com URL via HTTPS. Well, if you can modify the initial page (also possible via XSS), you can downgrade the request to HTTP.
And StackAuth.com will be just fine with that. When it makes the request to stackauth.com, you would need to intercept that as well, and change its ReadSession URL to be HTTP as well.
But then, all you need to do is watch the call to the ReadSession URL, and boom, you've stolen the GlobalLogin token.
But the traffic is HTTP anyway, so it doesn't matter since you don't need to go through that trouble to steal the cookie. So why bother?
Local Attacker
If the person has access to the computer to read the local storage file, they can do FAR worse than just steal your login token.
There's a class of attack called "Browser In The Middle", where a compromise in the browser allows an attacker to do whatever they want.
And there's no real effective protection against it other than to try to keep the browser secure (there's nothing you can do from your end).
So if an attacker can get local access to the computer, it's game over.
Server-Based Attacker
If an attacker can get access to StackOverflow's servers, it's game over anyway...
Conclusion
As long as HTTP is allowed (since a MITM can always downgrade the connection to HTTP), there's nothing to protect as session secrets always be stealable via eavesdropping.
The only way of protecting this information is to use HSTS and force HTTPS everywhere.
It's worth noting that you could protect GlobalLogin by forcing HSTS on stackauth.com, leaving the main site accessible over HTTP. This wouldn't prevent the effect of the attack (session hijacking). But it would protect the one vector.
But going HTTPS only via HSTS everywhere would be the best and really only way to prevent these kinds of problems. Anything else would be a bandaid on a gunshot wound.
Note: I did talk to SO about this prior to posting this.
Note - It is not a duplicate of that question. The concerns are different. I don't want to disable that firebug let it be open let the user to use all functionality provided by firebug, I only want firebug not to show service calls.
I may be wrong but I want to ask when browser developer tools like firebug displays service calls and their request response Is it not a security threat? If not why so?
IF it is, Is there any way by which we can hide the display of service calls after build deployment in firebug or developer tools?
You can see a get request shown by firebug in Mozilla firefox.
I have searched for this but not getting anything fruitful and I am also not able to find any post related to this concern on stackoverflow. If any one has any information please share it.
No, this is not a security issue on any properly designed web site / service. The browser, and requests performed by the browser, should all be considered to be under the user's control. (Indeed, from a security perspective, the browser should be considered an extension of the user, rather than something separate from them.) As such, the user viewing something that's under the user's control is not a risk at all.
If your web site is sending data that the user shouldn't be allowed to see in HTTP(S) requests, you've done something wrong. That data should never leave the server at all if it's that sensitive - move the logic that needs it off of the client (e.g, Javascript) and back onto the server side.
If your web application follows security through obscurity then it would be harmful.
But as long as you make your web application secure with common vulnerabilities like CSRF, XSS taken care of then anyone seeing the request made / response received doesn't matter.