Question originally posted on Webmasters, was recommended to move it here.
I host a webservice, and provide my members with a Javascript bookmarklet, which loads a JS sript from my server. However, clients must be logged in, in order to receive the JS script. This works for almost everybody. However, some users on setups (i.e. browser/OS) that are known to work for other people have the following problem: when they request the script via the javascript bookmarklet from my server, their cookie from my server does not get included with the request, and as such they are always "not authenticated".
I'm making the request in the following way:
var myScript = eltCreate('script');
myScript.setAttribute('src','http://myserver.com/script');
document.body.appendChild(myScript);
In a fit of confused desperation, I changed the script page to simply output "My cookie has [x] elements" where [x] is count($_COOKIE) on http://myserver.example.com. If this subset of users requests the script using the above method encoded in the bookmarklet, the message reads "My cookie has 0 elements". When they access the URL directly in their browser, the message reads "My cookie has 7 elements".
What on earth could be going on?! And more importantly, how would I fix this?
I'm pretty sure this is a privacy setting issue. The affected browsers probably have increased their privacy settings refusing 3rd party scripts from setting cookies.
I've experience similar issues when placing an IFRAME pointing to domain B on a site hosted on domain A. Some browsers refused that my IFRAME set cookies for it's own domain because it triggered a privacy issue.
You might want to store a hash in the script src attribute and have it authenticate users that way.
Edit: This is sort of what I'm talking about: Setting cross-domain cookies in Safari
Related
I created a small application using Electron ( http://electron.atom.io ). I want to add a feature that automatically logs in people on specific websites, on any type of browser.
The way I though of this is if Electron automatically completes the username and password fields of the website OR it sends an ajax request using the website's window context ( inject himself somehow into the content ).
I know that is possible to achieve this if I create extensions for each browser but it will take too long.
Thank you
The problem you will face is all browsers are set to prevent what is known as cross-site scripting. Basically I can create a frame inside a page or within the same domain and manipulate the dom of this externally sourced frame but I can not do this with a source from another domain.
So scripting across to fill and submit the form won't work which leaves you to trying to send a HTTP GET or POST through AJAX. Which the problem we reach here is that the site you are logging into is likely to check the referring URL to ensure the referrer is from it's own domain. While technically jquery has a method of setting the referrer header, unfortunately the browser resets this header in any cross site transactions for security purposes.
So basically there is no way to accomplish this reliably from a browser side script as the browsers are very restrictive when it comes to security measures. You will be able to login via AJAX to any sites that don't check their referrer header, but other than that you would need an arrangement with the websites your logging into, or use a more unrestricted platform that will allow you to manipulate the DOM cross site or spoof the Referrer Headers.
I figured that I will use the following approach:
I've found where most browsers keep their cookies, so I will upload the cookies there. When the user accesses the browser, it will be automatically logged in.
I recently found an exploit in my router to basically give me root access. The catch? There is a nonce hidden form value that is randomly generated and must be sent in for it to work that makes it difficult to do "easily"
So basically I'm wanting to do something like this in javascript:
get http://192.168.1.254/blah
use a regex or similar to extract the nonce value
put the nonce value into a hidden field in the current page
submit the form by POST to http://192.168.1.254/blah complete with the nonce value and other form values I want to send in.
Is this at all possible using only HTML and Javascript? I'm open to things like "must save HTML file locally and then open", which I'm thinking is one way around the cross domain policy.
But anyway, is this at all possible? I'm hoping for this to be able to run from at least Firefox and Chrome. The audience for this is those with some technical know how.
EDIT: I've rewritten this since my original answer was not correct.
Since you can make an AJAX call to a local file, here is what you do.
"The AJAX page" is the page making the request.
"The requested page" is self explanatory.
You have your AJAX page on your computer. The AJAX pages calls the requested page from your computer, in the same folder as itself.
You instruct the user to fetch the requested page from their router and put it in the same folder as the AJAX page.
The cross-domain policy now no longer applies, since both files are in the same folder.
Your page can have a POST form where the action (target page) is cross-domain and there should be no restrictions.
If you can run PHP code on your page, try using cURL. This can make cross-domain requests.
This cannot be done from a regular HTML page. The Same-Origin policy will prevent you from connecting to the router. (Saving the page locally won't help; browsers started heavily restricting what a local page can do several years ago.)
If you're really bent on making this happen from a browser, you could write an extension. Origin restrictions do not apply to browser extensions.
Per cookie specification this is not allowed (same principle as Same Origin Policy for ajax calls). As far as SOP is concerned, it does not apply, when you are running your javascript from file:/// (for example inside of a UIWebView). This is well documented and working in my example too. What about cookies though?
I have an app that makes a request to a server via javascript running, for all intends and purposes, locally (file:///). The authentication request sets a cookie with name let's say 'alpha', path: '/' and domain 'serverdomain.com'. During logout I need to clear the aforementioned cookie but I get the feeling that my attempts fail because I don't have access to it because it is considered to be from a different domain. Does that sound familiar? Or am I way off here? Is there a way to accomplish such a feat?
EXAMPLE
I am running my javascript on Chrome (using file:/// as the URI). I initiate a login and soon enough I can see the following cookie in the cookie manager plugin (this is not the actual cookie but it looks the same except for the name which we can say it is 'alpha'). The cookie is not marked http only but it has the 'session' and 'secure' checkboxes checked (unlike the screenshot below).
Now keep in mind that if I use the 'inspect element' feature of Chrome and go to 'Cookies', I get a 'There are no cookies for this site'.
During logoff I need to delete that cookie. So I do this in javascript:
document.cookie="alpha=; expires=Thu, 10 May 2000 15:07:07 GMT"
The cookie does not go away. The only way I can make it go away is by deleting it from the cookie manager. Should I be able to delete this cookie (while running from file:///)? If so how?
If the cookie was created on a different domain, this cookie won't be sent by the client to the server on the second domain, so you cannot remove it. You can set a cookie with the same name on this domain but that won't be the same cookie as the one that exists on the first domain.
I'm iframing an external site. That site tries to call location from parent for analytics reasons and access is refused (for obvious default security reasons) .
Yet I would like to disable that security and answer, because that site is a 'friend' but not on the same domain.
Seems impossible to grant that access... any idea ?
I ran into a similar situation before. Allowing for cross domain javascript access through iframes is not possible since this would result in a cross-scripting-attack nightmare. Like the other poster said, you will have to post this data to them yourself. One way to fix this is to set a cookie that can be read by the other domain with whatever information they are looking for then they can read the data from the cookie. Javascript can set to the cookie when you load the other site in the iframe. For a function to do that, check http://phpjs.org/functions/setcookie:509
If the site is a 'friend' as you say - how about passing them the location data yourself?
Please, I would like to set cookies for my browser by my script running at my domain.. but I want to set cookies from another domain.
For example, I would like to set cookies that twitter.com sends me (when I would visit by browser), but I don't want to visit their page for the first time. Only when I visit their page after running my script, I want that their cookie is already set. Is it possible at all?
I thought, that changing the domain variable for document.cookie is doing the trick, but it doesn't work.. the twitter doesn't see any cookie being set.
No you can't obviously. Being able to control cookies from domains other than the one your website/webapplication runs on, would be a tremendous security risk. Because being able to set, would also mean being able to read.
You can, but it requires some hacks and can't be done in javascript alone.
Open up firefox and grab your "auth_token" cookie from twitter.com
If you have access to a web server and can config it to accept all host headers.
Makeup a fake subdomain and add it to your hosts file like:
127.0.0.1 xxxxxxx.twitter.com
from that server set a cookie named "auth_token" with *.twitter.com as the domain.
This would work for twitter because their auth_cookie is set to expire in 20 years.