I have a script loaded from a 3rd party domain (3p.com) into a webpage (page.com)
The goal is to capture error and unhandledrejection occurring in the 3p script and ping this back to a server for logging.
Whilst there are event handlers available in the browser for this, it seems they do not allow any meaningful collection of information, from the MDN site:
When an error occurs in a script, loaded from a different origin, the details of the error are not reported to prevent leaking information (see bug 363897).
Is there a way to do this? Ideal solution is global and hooks into these events, then allows filtering to only errors from the concerned script. However if would be happy to also wrap the script execution into a try / catch if this would capture all possible errors.
One option would be to set up your server so that requests to that third-party domain get bounced off your server, so that your clients have the ability to programatically examine possible errors that get thrown. For example, instead of serving to your clients
<script src="https://3p.com/script.js"></script>
serve
<script src="https://yoursite.com/get3pscript"></script>
where the get3pscript route on your site makes a request to https://3p.com/script.js, then sends the response to the client, making sure the MIME type is correct. Then the client will be able to do whatever it wants with the script element without cross-domain issues.
Related
Python has a module called httplib which allows for the retrieval of an html resource from a URL. With this code:
httpServ = httplib.HTTPConnection("www.google.com")
httpServ.connect()
httpServ.request('GET',"/search?q=python")
...
httpServ.close()
I am trying to do the same thing in my angular app, but using $http get doesn't allow me to retrieve the html document due to the same origin policy.
Is there anything similar to the python method available in JavaScript?
So, the Same-Origin Policy has nothing to do with JavaScript. It basically says "don't allow scripts on a page to talk to scripts being run by another host."
This is an extremely important security feature. It means that if you put jQuery on your page, and somehow a jQuery CDN got hacked and they changed jQuery to send your passwords to another page, it wouldn't work (so long as the browser properly enforces the Same-Origin Policy).
You don't have this problem when working with Python because Python exclusively runs on the server (from a web-app perspective). Your server can talk to any machine it wants to, but browsers do not (and should not as seen above) give that freedom to webpages.
So, how to solve your problem? Make your GET request to a script running on your server. Have your server do a curl or wget or w/e of google.com, then have your server send the data back to the client.
I have some HTML/PHP pages that include javascript calls.
Those calls points on JS/PHP methods included into a library (PIWIK) stored onto a distant server.
They are triggered using an http://www.domainname.com/ prefix to point the correct files.
I cannot modify the source code of the library.
When my own HTML/PHP pages are locally previewed within a browser, I mean using a c:\xxxx kind path, not a localhost://xxxx one, the distant script are called and do their process.
I don't want this to happen, only allowing those scripts to execute if they are called from a www.domainname.com page.
Can you help me to secure this ?
One can for sure directly bypass this security modifying the web pages on-the-fly with some browser add-on while browsing the real web site, but it's a little bit harder to achieve.
I've opened an issue onto the PIWIK issue tracker, but I would like to secure and protect my web site and the according statistics as soon as possible from this issue, waiting for a further Piwik update.
EDIT
The process I'd like to put in place would be :
Someone opens a page from anywhere than www.domainname.com
> this page calls a JS method on a distant server (or not, may be copied locally),
> this script calls a php script on the distant server
> the PHP script says "hey, from where damn do yo call me, go to hell !". Or the PHP script just do not execute....
I've tried to play with .htaccess for that, but as any JS script must be on a client, it blocks also the legitimate calls from www.domainname.com
Untested, but I think you can use php_sapi_name() or the PHP_SAPI constant to detect the interface PHP is using, and do logic accordingly.
Not wanting to sound cheeky, but your situation sounds rather scary and I would advise searching for some PHP configuration best practices regarding security ;)
Edit after the question has been amended twice:
Now the problem is more clear. But you will struggle to secure this if the JavaScript and PHP are not on the same server.
If they are not on the same server, you will be reliant on HTTP headers (like the Referer or Origin header) which are fakeable.
But PIWIK already tracks the referer ("Piwik uses first-party cookies to keep track some information (number of visits, original referrer, and unique visitor ID)" so you can discount hits from invalid referrers.
If that is not enough, the standard way of being sure that the request to a web service comes from a verified source is to use a standard Cross-Site Request Forgery prevention technique -- a CSRF "token", sometimes also called "crumb" or "nonce", and as this is analytics software I would be surprised if PIWIK does not do this already, if it is possible with their architecture. I would ask them.
Most web frameworks these days have CSRF token generators & API's you should be able to make use of, it's not hard to make your own, but if you cannot amend the JS you will have problems passing the token around. Again PIWIK JS API may have methods for passing session ID's & similar data around.
Original answer
This can be accomplished with a Content Security Policy to restrict the domains that scripts can be called from:
CSP defines the Content-Security-Policy HTTP header that allows you to create a whitelist of sources of trusted content, and instructs the browser to only execute or render resources from those sources.
Therefore, you can set the script policy to self to only allow scripts from your current domain (the filing system) to be executed. Any remote ones will not be allowed.
Normally this would only be available from a source where you get set HTTP headers, but as you are running from the local filing system this is not possible. However, you may be able to get around this with the http-equiv <meta> tag:
Authors who are unable to support signaling via HTTP headers can use tags with http-equiv="X-Content-Security-Policy" to define their policies. HTTP header-based policy will take precedence over tag-based policy if both are present.
Answer after question edit
Look into the Referer or Origin HTTP headers. Referer is available for most requests, however it is not sent from HTTPS resources in the browser and if the user has a proxy or privacy plugin installed it may block this header.
Origin is available for XHR requests only made cross domain, or even same domain for some browsers.
You will be able to check that these headers contain your domain where you will want the scripts to be called from. See here for how to do this with htaccess.
At the end of the day this doesn't make it secure, but as in your own words will make it a little bit harder to achieve.
We're developing a Dynamics CRM 2011 product that has a button in the ribbon that calls an external API. Currently, for this button to work, the following settings need to be changed in the browser (IE):
We would like to avoid this, because many of the target customers for this product are very security conscious. Is there a way to write the code so that it will not require these permissions to be changed, but still be able to communicate with the external API? The code running when the button is pressed in CRM is HTML and Javascript.
Thanks!
Are you in control of the API? If so, look into CORS. With CORS, all you do is basically add a few extra headers to your request response. If you use an AJAX library (like jQuerys $.ajax), you should be able to continue writing code as is. If not, a good article on how to implement cors in Javascript can be found here: http://eriwen.com/javascript/how-to-cors/
To enable cors, read up on http://enable-cors.org/
I don't know anything about this CRM, but other than JSONP, your best bet is to have a server side script act as a proxy.
So, you would create a script within the same domain as the user interface code. That script will then use a server side language (such as PHP) to perform the request to the cross domain script on your behalf. The server side connection has no restriction on which domain it can access, and all the browser knows is that it is sending a request to a page within the calling domain, which is presumably safe.
How you will do this depends on the exact language of choice, but in general you would just need to send the remote API URL as well as any arguments needed to your server side script, which then rebuilds the request to that URL and passes the result back to the client.
I am trying to accomplish some specific test requirement.
One of the requirement now is to redirect some nonexistent url to specific ip, which is what the dns is doing. I think firefox is using internal dns cache. But I cannot find a proper service that I can use to change such kind of dns cache. On the other hand, i have no idea if firefox support some kind of service to customize the dns process, I mean give a customized result instead of really getting from DNS Server.
As I need to start many firefox process to do the work concurrently, so I cannot do this simply by changing the system hosts file, cause it will affect other process.
Any idea?
No, modifying DNS responses isn't possible in Firefox, the DNS service merely allows triggering a DNS request. What you could do is recognizing NS_ERROR_UNKNOWN_HOST response and somehow redirecting it to your server. While recognizing isn't particularly hard, redirecting is complicated. You could add a progress listener and check whether a request finished in onStateChange method (if (aFlag & STATE_STOP)). The parameter aStatus gives you the status of the request, you would be looking for status Components.results.NS_ERROR_UNKNOWN_HOST. And for top-level requests (aFlag & STATE_WINDOW) you could change window location to make a request to a different server instead. For other requests - don't know how one would "redirect" there.
Is it possible through jQuery (or plain javascript) to test if a webpage on another domain is available?
I tried getting the response headers with an ajax-call but I get an error no matter what site outside my own domain I test.
So do I really need a proxy script on my server or would I be able to skip that request?
Is it possible through jQuery (or plain javascript) to test if a webpage on another domain is available?
Due to same origin policy restriction you need a proxy/bridge on your server unless the remote server implements JSONP which obviously we cannot assume for the general case.
You can create an <img> tag that points to an existing image on the external domain.
If the onerror event fires, image, and perhaps the entire site, is down.
If it fires after 5 seconds or so, it probably timed out, so the entire site is likely to be down.
Yes, you need to use a proxy script on your server. JavaScript cannot be used in a browser to request resources across domains, as per the same-origin policy.