I am working on a project which is written in javascript. I can see that for requesting, XMLHttpRequest object has been created.
It is working fine for "http" requests but fails for "https". Since I am debugging it in the Development environment, I just want to know how to ignore self-signed certificate in XmlHttpRequest objects?
While searching I have found this,
httpreq = new ActiveXObject("Msxml2.ServerXMLHTTP.3.0");
httpreq.setOption(2, 13056);
But the answer is not working for morden browsers like Microsoft edge, chorme...
I have also found this, and it clearly says the setOption() can be used for ignoring ssl certificates.
One difference I can see in my code is that I an creating the httpreq using:
httpreq = new xmlhttprequest();//This is for chorme and Firefox
So is there any way I can ignore self-signed certificates in XmlHttpRequest?
The Bad News:
There is no way to accomplish this with XmlHttpRequest directly. This is logical as SSL needs to be secure on the web as any ability to disable it would present a major security risk.
You are also right that setOption is not a standard/modern method under XmlHttpRequest.
The Good(ish) News:
What you can do is accomplish this via a trusted/properly configured proxy, with the example below as a Node/Express server configured to allow the insecure SSL connection:
$router.get("/", (oRequest, oResponse) => {
$nonStrictSSLRequest = require('request').defaults({strictSSL: false});
$nonStrictSSLRequest(
{ url: "https://192.168.1.2:8080/api/apiVer" },
function (err, oAPIResponse, sBody) {
oResponse.status(200).json(JSON.parse(sBody));
}
);
});
I had to do this to support RainMachine's (stupid HTTPS only) self signed certificates.
If you are developing on Chromium based browser, you can use flag --ignore-certificate-errors. Always pass also --user-data-dir to prevent affecting of your main secure profile. Use this only as last resort and only during local development, as this completely ignores all SSL errors. --ignore-certificate-errors is undocumented flag, which can be removed from chromium at any time.
Chromium Linux:
chromium-browser --ignore-certificate-errors --user-data-dir=~/chromium_dev_session
Chrome Windows:
"C:\Program Files\Google\Chrome\Application\chrome.exe" --ignore-certificate-errors --user-data-dir="c:/chrome_dev_session"
Related
i can add an event listener for clicks to blank but not to twitter in the code below.
const blank = window.open();
const twitter = window.open("https://twitter.com");
const PrintClick = function (name) {
return function (...args) {
console.log(name, ...args);
};
};
blank.addEventListener("click", PrintClick("blank"));
twitter.addEventListener("click", PrintClick("twitter"));
is it because twitter has done something to not let me do this? would there be a way to get around it?
The reason that you did not got any exception :
Most browsers don't support multiple popups so in order to accomplish it wou need to try using:
window.open(yoururl,"_blank",'PopUp',randomnumber,'scrollbars=1,menubar=0,resizable=1,width=850,height=500');
Or Give each window a new window name.
window.open(url, WindowName)
Security Risk
You can't add an event listner with different origin using JavaScript, it would be a huge security flaw if you could do it. For the same-origin policy browsers block scripts trying to access a frame with a different origin.
Origin is considered different if at least one of the following parts of the address isn't maintained:
<protocol>://<hostname>:<port>/...
Protocol, hostname and port must be the same of your domain, if you want to access a frame.
Examples
Here's what would happen trying to access the following URLs from http://www.example.com/home/index.html
URL RESULT
http://www.example.com/home/other.html -> Success
http://www.example.com/dir/inner/another.php -> Success
http://www.example.com:80 -> Success (default port for HTTP)
http://www.example.com:2251 -> Failure: different port
http://data.example.com/dir/other.html -> Failure: different hostname
https://www.example.com/home/index.html:80 -> Failure: different protocol
ftp://www.example.com:21 -> Failure: different protocol & port
https://google.com/search?q=james+bond -> Failure: different protocol, port & hostname
Not recommended
Disabling same-origin policy in your browser
I'll link the relative answer. However, please remember that disabling the same-origin policy will only affect your browser. Also, running a browser with same-origin security settings disabled grants any website access to cross-origin resources, so it's very unsafe and should NEVER be done if you do not know exactly what you are doing (e.g. development purposes).
Google Chrome
Mozilla Firefox
Safari
Opera
Microsoft Edge: not possible
Microsoft Internet Explorer
addEventListener can only listen to the dom object of the current page, you can consider selenium automation framework operations
For security reasons browsers disable any interaction across domains that you do not own. Imagine all the things one could do with that.
If I load a page using localhost:85 and try to fetch() a resource from localhost:8083 it gives me a ERR_SSL_PROTOCOL_ERROR error.
I do not have SSL enabled on either side. Clearly this is all in a development environment, how do I work around it?
So far, the only reasonable solution I've had was to edit both of the sites to operate out of the same port, but just have Nginx redirect the location. In other words:
localhost:85 => localhost:85
localhost:85/site2 => localhost:8083
In Firefox, how do I do the equivalent of --disable-web-security in Chrome. This has been posted a lot, but never a true answer. Most are links to add-ons (some of which don't work in the latest Firefox or don't work at all) and "you just need to enable support on the server".
This is temporary to test. I know the security implications.
I can't turn on CORS on the server and I especially would never be able to allow localhost or similar.
A flag, or setting, or something would be a lot better than a plugin. I also tried: http://www-jo.se/f.pfleger/forcecors, but something must be wrong since my requests come back as completely empty, but same requests in Chrome come back fine.
Again, this is only for testing before pushing to prod which, then, would be on an allowable domain.
Almost everywhere you look, people refer to the about:config and the security.fileuri.strict_origin_policy. Sometimes also the network.http.refere.XOriginPolicy.
For me, none of these seem to have any effect.
This comment implies there is no built-in way in Firefox to do this (as of 2/8/14).
From this answer I've known a CORS Everywhere Firefox extension and it works for me. It creates MITM proxy intercepting headers to disable CORS.
You can find the extension at addons.mozilla.org or here.
Check out my addon that works with the latest Firefox version, with beautiful UI and support JS regex: https://addons.mozilla.org/en-US/firefox/addon/cross-domain-cors
Update: I just add Chrome extension for this https://chrome.google.com/webstore/detail/cross-domain-cors/mjhpgnbimicffchbodmgfnemoghjakai
The Chrome setting you refer to is to disable the same origin policy.
This was covered in this thread also:
Disable firefox same origin policy
about:config -> security.fileuri.strict_origin_policy -> false
I have not been able to find a Firefox option equivalent of --disable-web-security or an addon that does that for me. I really needed it for some testing scenarios where modifying the web server was not possible.
What did help was to use Fiddler to auto-modify web responses so that they have the correct headers and CORS is no longer an issue.
The steps are:
Open fiddler.
If on https go to menu Tools -> Options -> Https and tick the Capture & Decrypt https options
Go to menu Rules -> Customize rules. Modify the OnBeforeResponseFunction so that it looks like the following, then save:
static function OnBeforeResponse(oSession: Session) {
//....
oSession.oResponse.headers.Remove("Access-Control-Allow-Origin");
oSession.oResponse.headers.Add("Access-Control-Allow-Origin", "*");
//...
}
This will make every web response to have the Access-Control-Allow-Origin: * header.
This still won't work as the OPTIONS preflight will pass through and cause the request to block before our above rule gets the chance to modify the headers.
So to fix this, in the fiddler main window, on the right hand side there's an AutoResponder tab.
Add a new rule and response:
METHOD:OPTIONS https://yoursite.com/ with auto response: *CORSPreflightAllow
and tick the boxes: "Enable Rules" and "Unmatched requests passthrough".
See picture below for reference:
Best Firefox Addon to disable CORS as of September 2016: https://github.com/fredericlb/Force-CORS/releases
You can even configure it by Referrers (Website).
As of June 2022, Mozilla Firefox does allow you to natively change the CORS configuration. No extra addons are required. As per Mozilla docs you can change the CORS setting by changing the value of the key content.cors.disable
To do so first go to your browser and type about:config in your address bar as shown in the
Click on accept risk and continue, since you are on this stack overflow page we assume you are aware of the risks you are undertaking.
You will see a page with your user variables. On this page just search for key content.cors.disable as
You do not have to type in true or false values, just hit the toggle button at the far right of you in the screen and it will change values.
While the question mentions Chrome and Firefox, there are other software without cross domain security. I mention it for people who ignore that such software exists.
For example, PhantomJS is an engine for browser automation, it supports cross domain security deactivation.
phantomjs.exe --web-security=no script.js
See this other comment of mine: Userscript to bypass same-origin policy for accessing nested iframes
For anyone finding this question while using Nightwatch.js (1.3.4), there's an acceptInsecureCerts: true setting in the config file:
firefox: {
desiredCapabilities: {
browserName: 'firefox',
alwaysMatch: {
// Enable this if you encounter unexpected SSL certificate errors in Firefox
acceptInsecureCerts: true,
'moz:firefoxOptions': {
args: [
// '-headless',
// '-verbose'
],
}
}
}
},
I think we are all familiar with the cross-site problem, but just in case:
I am using OpenLayers3, GeoServer on port 8080 and Apache on port 80. I render some features on map, and on click I would like to get feature info from WMS. I found the code in OpenLayers3 examples:
var viewResolution = v.getResolution();
var url = wmsSource.getGetFeatureInfoUrl(
evt.coordinate, viewResolution, viewProjection,
{'INFO_FORMAT': 'application/json'});
if (url)
$.get(url, null, function(data)
{
});
Of course I get: XMLHttpRequest cannot load localhost:8080/geoserver/Re... . No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'localhost' is therefore not allowed access.
I was searching the net and found different approaches how to handle this matter. I am asking witch way should I choose. The known facts are: hosting server will be owned, linux or windows unknown (for now). This also means that I don't know if apache or IIS will be used so lets stay opened.
The options I found are:
CORS
JSONP
proxy on apache
URL rewriting IIS 7
What should I choose if hosting web site on apache or IIS? I am not looking the easy way, I am looking for the right way.
Ciao,
I think you have two main options:
Using JSONP OutputFormat for GetFeatureInfo
Using a proxy (with some protection)
I believe 1 as a solution is clean and actually preferrable IMHO if you are developing a specific application and you know that you always be hitting GeoServer or something that supports JSONP. It avoids having to fiddle with proxies and eventual admins.
In the general case 2 is more flexible, although I would recommend to somehow limit what people can do with such a proxy to avoid having a black-hole in your infrastructure.
In our webgis MapStore (based on OL) we use this very lean http-proxy we developed that can be configured to let pass only certain requests (e.g. getfeatureinfo) and only to certain servers if needed.
My 0.02€.
I've posted before on this subject, but after a year of getting on with other things, I've managed to get into a pickle once again. I'll try and give a brief overview of the scenario and the current attempts to make things work:
IIS web server hosting HTML, JS etc. on host: iis.mycompany.com (referred to as foo)
WCF RESTful web services hosted via a Windows Service on host: wcf.mycompany.com (referred to as bar)
The Javascript served from foo works by making RESTful ajax calls (GET or POST depending on the action) to the WCF services on bar, obviously these are cross domain calls as they aren't on the same host.
The Javascript uses the jQuery (1.7.2) framework to manipulate the DOM and perform ajax calls to bar, the expected content type for POSTS is JSON, and the response from GETS is expected to be JSON too (application/json).
Bar has it's WCF services configured using TransportCredentialOnly as the security mode and the transport client credentail type is NTLM, so only authed users to contact the services.
CORS Support has been added to bar's WCF services using an extension to WCF:
http://blogs.msdn.com/b/carlosfigueira/archive/2012/05/15/implementing-cors-support-in-wcf.aspx
We have added additional headers and modfied some that the post already contained based on numerous internet articles:
property.Headers.Add("Access-Control-Allow-Headers", "Accept, Content-Type");
property.Headers.Add("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
property.Headers.Add("Access-Control-Max-Age", "172800");
property.Headers.Add("Access-Control-Allow-Origin", "http://iis.mycompany.com");
property.Headers.Add("Access-Control-Allow-Credentials", "true");
property.Headers.Add("Content-type", "application/json");
Sites giving information on enabling CORS suggest that the Access-Control-Allow-Origin response header should be set to "*" however, this is not possible in our case as we make jQuery ajax calls using the following setup:
$.ajaxSetup({
cache: "false",
crossDomain: true,
xhrFields: {
withCredentials: true
}
});
As it turns out you cannot use "*" for the accepted origin when you are using "withCredentials" in the ajax call:
https://developer.mozilla.org/en/http_access_control
"Important note: when responding to a credentialed request, server
must specify a domain, and cannot use wild carding."
Currently in our development lab, this doesn't matter as we can hard code the requests to the IIS (foo) server URL.
The main problem now appears to be attempting POST requests (GET is working using the above configuration). When the browser attempts the POST process, it first sends an OPTIONS header to the server requesting allowed OPTIONS for the subsequent post. This is where we would like to see the headers we've configured in the CORS Support WCF extension being passed back, however we aren't getting that far; before the response comes back as "401 Unauthorized", I believe this is to do with the transport security binding configuration requesting NTLM, but I'm not sure.
Also, I'm not very experienced with this, but I haven't seen much information about POST using application/json content type as opposed to text/plain when performing cross domain requests.
I know that people will probably suggest JSONP as the one true solution, I'm not against different approaches, indeed I encourage anyone to suggest best practices as it would help others reading this question later. However, please attempt to answer the question before suggestion alternatives to it.
Many thanks in advance for anyone who contributes.
peteski
:)
UPDATE:
It appears that Chrome (20.x.x) doesn't suffer the problem of not negotiating NTLM to retrieve the OPTIONS header response from the server, but Firefox (13.0.1) does.
We've also noticed that someone has already posted a bug up on the Firefox forum, which we've added information to:
http://bugzilla.mozilla.org/show_bug.cgi?id=751552
Please vote for this bug to be fixed on the bugzilla site!
Using the following code, we can watch the network trace to see Firefox failing and Chrome working fine:
var url = "http://myWebServiceServer/InstantMessagingService/chat/message/send";
var data = '{ "remoteUserUri" : "sip:foo.bar#mydomain.com", "message" : "This is my message" }';
var request = new XMLHttpRequest();
request.open("POST", url, true);
request.withCredentials = true;
request.setRequestHeader("Content-Type", "application/json");
request.send(data);
console.log(request);
On a separate note, IE8 doesn't support the XMLHttpRequest for cross domain calls, favouring it's own magical XDomainRequest object, so we've got some work to do in changing the client side code to handle IE8 vs the world cases. (Thanks IE8).
/me crosses fingers that Mozilla fix the Firefox bug.
UPDATE 2:
After some digging it appears that IE8's XDomainRequest cannot be used to make cross domain requests where NTLM must be negotiated, this basically means that the security on our WCF binding can't be used thanks to limitations in a web browser.
http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx
"No authentication or cookies will be sent with the request"
So, I guess we've taken this as far as it is going to go for now.. It looks like we're going to have to create our own custom token authentication and pass it across to the WCF service in a cookie, or in IE8's case, POST it with the JSON. The WCF service will then have to handle decrypting the data and using that instead of the ServiceSecurityContext.Current.WindowsIdentity we previously had access to with NTLM auth.
I know you said you would rather have the problem itself addressed, but you may consider using a "reverse proxy."
I don't know what technologies you are using, but we use Apache web server and have a Java RESTful API running on a different server that required authentication. For a while, we messed with JSONP and CORS, but were not satisfied.
In the end, we setup an Apache Reverse Proxy and it worked miracles. The web browser believes it is communicating with its own domain and acts appropriately. The RESTful API doesn't know it is being used via a proxy. Therefore, everything just works. And Apache does all the magic.
Hopefully, all web servers have a feature like Apache's reverse proxy.
Here is some documentation on the feature: http://httpd.apache.org/docs/2.2/mod/mod_proxy.html
All we had to do is ensure the mod_proxy module was installed, then add the following lines to our Apache config file:
ProxyPass /restapi http://restfulserver.com/restapi
ProxyPassReverse /restapi http://restfulserver.com/restapi
Then restart the web server and voila!