Is there anyway with javascript/jQuery to check if a website is up?
You're limited by the single origin policy I don't think you can use a standard Ajax request, but is it possible to try and load a file (similar to wget) and get the status code of the reply another way?
This would be for a user side website checker, where they can check if multiple domains are "up" without having to use any code on a server.
e.g. I open a web page at checkmysite.org it sends an HTTP request to mysite.org to check whether it receives a response, and if so the domain is online
The single origin policy exists for a very good reason. What you're asking is effectively the same as "how can I defeat the single origin policy?".
You could always work around the policy with the co-operation of the server-end, for some specific known server. (e.g: CORS, cross-domain.xml in flash, <script> tag, etc).
Why is it so important that this not have help from the server at checkmysite.org? It could host an absolutely trivial php script which does the HEAD request for you. Your JavaScript code could just do a normal GET request to the PHP script.
Related
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 can simply call GET request for any page on the web using html tags from another origin:
<script src="http://example.com/user/post?txt=sample"></script>
XHR other origin is blocked because of security reason, as an instance, attacker can post behalf of a user using GET request(Consider the fact that it is not possible because of lack of cookies). However, the above script tag will do the same(Same, cookies are not available). So why XHR GET request is not allowed?
GET requests are not supposed to change anything on the server. From RFC 2616 section 9.1.1:
In particular, the convention has been established that the GET and HEAD methods SHOULD NOT have the significance of taking an action other than retrieval. These methods ought to be considered "safe".
In your example of posting to a site using a GET request, the site shouldn't even allow that, and the same-origin policy isn't really meant to prevent it.
The reason XHR is treated differently is that XHR returns the HTTP response to the JavaScript code that made the request, so it has the potential to leak information. For example, if cross-domain XHR GET requests were allowed, a malicious script could query your bank's website to find out how much money is in your account.
Other methods of performing GET requests don't leak information. In particular:
You can add a <script> tag to the document, but the browser will try to run the response as a script. Unless the response is a valid script that's specifically designed to provide data using the JSONP convention, your code can't "see" anything that was in the response.
You can add an <img> tag to the document and maybe load some of the user's personal photos from another site, but the image will only appear on the screen; you can't access the pixel data from JavaScript.
I'm trying to detect server information using only JS such as HTTP response code & content.
Because of Same-origin policy I'm not allowed to use normal ajax request and therefore i'm forced to following workarounds
Using JSONP is great but in case of error I can't know what HTTP code or content of response page
Using Image request is not really option cause, same as above, I can't know HTTP code or content. I can only know if I loaded image to DOM.
Using AJAX with CORS. This is best solution so far but in case it is not my server I can't detect HTTP code :(. Same applies for flash and crossdomain.xml policy.
Using iframe, as i know I can't detect HTTP code or content.
While writing this I've just notice that I'm dealing with XSS issues here but all I need from JS is HTTP code OR content of another domain.
All suggestions are welcome.
I fear that is not possible using client-side JavaScript, unless the server implements a mechanism allowing you to gather this information by either simply supporting CORS or include the information in the JSON response of the JSONP request.
However, if you have some server-side support you could put in place an API that allows you to do so. E.g. You call a service on your server which in turn performs the request on the remote server and returns the desired information.
For example: Server renders a page and then user makes an Ajax call using Javascript console to the same host using same protocol. Does it violate same-origin policy?
Follow up question - if the above scenario does not violate same-origin policy, is there any way to make sure that web browser is executing genuine, unmodified Javascript from my host?
Thank you.
No and No. It is not possible to know if the user changes the code. I do not even need a console. I can hijack the http responses and serve different files. That is why you need to validate everything on the server.
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.