How to overcome Ajax Content Security Policy directive? - javascript

I am injecting some JS code on various websites (using Selenium and Python) to send POST requests to my local web server. On some websites it works fine. But mostly, I don't get the requests. Figured it's because of the Content Security Policy.
For example, when I try to run the code using Console in Chrome on github.com, I get a following error:
Refused to connect to 'http://10.50.50.127:7777/' because it violates
the following Content Security Policy directive: "connect-src 'self'
uploads.github.com status.github.com collector.githubapp.com
api.github.com www.google-analytics.com ...".
My code looks like this:
function sendData() {
var request = new XMLHttpRequest();
request.open('POST', 'http://10.50.50.127:7777', false);
request.send("test");
}
I did some research on my own, and found a possible solution - to use a local proxy server and send data to a relative path like "/test". But it's pretty complicated to write a proxy server from scratch.
So, what can I do to overcome this Content Security Policy?

If your using Chrome and you want to disable Content Security Policy you can also use a plugin called Disable Content-Security-Policy from Chrome Web Store. This is the plugin for Chrome to disable headers.
I inject JS via Tampermonkey (Chrome) and this works fine.

If you controlled over both of sides then you can use.
https://easyxdm.net/wp/
Regards

I figured it! Turns out you can just disable all of the security checks:
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--disable-web-security')
chrome_options.add_argument('--allow-running-insecure-content')
browser = webdriver.Chrome(chrome_options=chrome_options)

Related

Cordova InAppBrowser executeScript callback

I try to parse some site and execute script in Cordova InAppBrowser's method executeScript on iOS and return some result in callback function, but get this error:
Refused to load gap-iab://InAppBrowser1249228873/%5Bnull%5D because it does not appear in the frame-src directive of the Content Security Policy.
I understand, that gap-iab:// scheme should be included to Content Security Policy in <meta> tag, but code is executing not on my site and I don't have access to it.
Can anyone suggest a decision to resolve this problem?
P.S. On Android executeScript works perfectly.
You could use nginx to proxy the HTML page you are trying to load. You'd set up nginx to proxy the site you are loading in the InAppBrowser, and use the add-header to add a Content-Security-Policy in the response with "'default-src' gap: gap-iab:"
The one issue you may have is if the original server already includes a strict Content-Security-Policy, because the strictest content-security-policy will get applied.

Why can't load js file in my local apache2 server?

In my local domain's webpage , both
jq.src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js";
jq.src = http://127.0.0.1/js/jquery-3.3.1.min.js
can be loaded.
In the stackoverflow's webpage,right click to enter into chrome's inspect--console.
const jq = document.createElement('script');
jq.src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js";
document.head.appendChild(jq);
jq.addEventListener('load', () => {
console.log("hello world");
console.log($ === jQuery);
});
The remote jquery.js file can be loaded,now to replace it with local js file--http://127.0.0.1/js/jquery-3.3.1.min.js .
Why can't load the js file in my local apache2?
Sites you are visiting can apply security policy for javascript - which includes the debugger. I think what you are seeing is the application of the content security policy associated with the web page you are visiting.
You can see this in the page headers. In Chrome (as explained here), you can view the html headers sent with the page:
Open the developer panel, select the "network" tab, and reload the page.
For stackoverflow, look under the "name" column for "stackoverflow.com" - there may be two if you originally loaded it via http, so find the one which is https - probably the second one. Click that one, and select the "headers" tab on the right. You will see in amongst the response headers:
content-security-policy: upgrade-insecure-requests
This is explained here.
Basically, it tells the browser that all http requests should be "upgraded" to https. So when you try to access http://127.0.0.1/..., your browser upgrades the request to https://127.0.0.1/..., which your local server probably isn't set up to handle.
This is not limited to Chrome - all modern browsers should do this.
I browsed, for example, a few sites with Safari, and, in some cases, got an error message, such as on GitHub:
Refused to load https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js because
it does not appear in the script-src directive of the Content Security Policy.
That is another variety of content security policies you can read about here.
try
jq.setAttribute('src',"https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js");
jq.setAttribute('crossOrigin',"Anonymos")
jq.onload=onFinish;

External file fail to load on 'load' function

I want to load content of external text file (demo.txt) in my div on button click.
Text file containes text 'Demo text.'
But it shows error
XMLHttpRequest cannot load file:///C:/Users/Tom/Desktop/jQuery%20thenewboston/76.)%20Load%20function/demo.txt. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.
on my browser console.
$(document).ready(function(){
$('#button_file').on('click',function(){
$('#load_html').load('demo.txt');
});
});
<button type="button" id="button_file">Load file</button>
<br />
<div id="load_html" >
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I am a beginner in jquery , please comment below for any query.
You cannot get the result because the remote site doesn't have CORS enabled: If you look at the console, you'll see:
(Reason: CORS header 'Access-Control-Allow-Origin' missing).
You can bypass CORS by using something like anyorigin.com, i.e.:
$.getJSON('http://anyorigin.com/get/?url=http%3A//thenewboston....&callback=?', function(data){
$('#div-data').html(data.contents);
});
PS: If it's a local file, make sure you load it on the same address as the script, (localhost, 127.0.0.1, 192.168.1.1, etc...)
You are being restricted by HTTP access control (CORS). The file you are requesting asynchronously needs to be from the same domain or the domain you are accessing it from needs to allow your domain to access it. As you are using the file:/// protocol you need to allow it, so check out this if that's the way you wish to go.
Alternatively you can create a local web server to host your site an allow access to the file on the same domain.
In order to make this work you need to use a web server instead of using just clicking on the html file.
Check XAMPP
Unfortunately, Google Chrome doesn't allow cross-origin request although Firefox does.
Alternatively, if the text file is short you can store it in an object and place it wherever you like.
text_file = {
contents = 'content';
}
$('.button_class').on('click',function(){
$('.div').html(text_file.contents);
});
I would never suggest you use this but if it's a small project, a one page application that nobody will see the code to - desperate times call for desperate measures.
The best thing to do is to use XAMPP and PHP.
Load in from your database the content you would like to show.
You can read the PHP documentation or watch online tutorials , I personally suggest TheNewBoston PHP Tutorials with Alex Garrett

How to tackle same origin policy in Mozilla

I am implementing YUI autocomplete in my project. I have created a web service which provides autocomplete suggestions. All things are working fine when I deploy my application and web service on same machine. But when I deploy the web service on different machine then it do not work in Firefox (But it do work in IE). I think because of same origin policy its not working in Mozilla.
Here is my autocomplete code
<script type="text/javascript">
YAHOO.example.BasicRemote = function() {
// Using an XHRDataSource to connect to web service
var oDS = new YAHOO.util.XHRDataSource("http://host_other_than_my_machine/i2b2/services/AutocompleteService/getCodes");
// Set the responseType as XML
oDS.responseType = YAHOO.util.XHRDataSource.TYPE_XML;
// Define the schema of the delimited results
oDS.responseSchema = {
resultNode: 'code',
fields: ['value']
};
// Enable caching
oDS.maxCacheEntries = 0;
// Instantiate the AutoComplete
var oAC = new YAHOO.widget.AutoComplete("myInput", "myContainer", oDS);
return {
oDS: oDS,
oAC: oAC
};
}();
</script>
My questions are
1) Is same origin policy is actual problem ? If yes then Is IE not bound to same policy as my code is working in IE ?
2) How to get rid of it ? I know some php code can be used to redirect request but how I can use it here ?
~Ajinkya.
Your problem is probably with the origin of the AJAX request, you should look into this: Cross Origin Request Security.
Basically, for apache you will need to add the following to the "host_other_than_my_machine" .htaccess file:
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "http://trusted.site"
</IfModule>
Of course, replacing "http://trusted.site" with the domain you will be making the requests from.
Edit: If you need to allow access for multiple remote domains you could simply use:
Header set Access-Control-Allow-Origin "*"
This should usually not be a security concern, but be sure to thoroughly consider your specific case, ie if you are making sensitive information available through AJAX responses.
Used PHP proxy provided by Yahoo and redirected all requests to it.
http://developer.yahoo.com/javascript/howto-proxy.html

secure xmlhttprequest from nonsecure page

I want to make an XMLHttpRequest to a secure uri (https://site.com/ajaxservice/) from javascript running inside a nonsecure page (http://site.com/page.htm). I've tried all kinds of nutty stuff like iframes and dynamic script elements, so far no go. I know I am violating 'same origin policy' but there must be some way to make this work.
I will take any kind of wacky solution short of having the SSL protocol written in javascript.
That won't work by default due to the same origin policy, as you mentioned. Modern browsers are implementing CORS (Cross-Origin Resource Sharing) which you could use to get around this problem. However this will only work in Internet Explorer 8+, Firefox 3.5+, Safari 4+, and Chrome, and requires some server-side work. You may want to check out the following article for further reading on this topic:
Cross-domain Ajax with Cross-Origin Resource Sharing by Nicholas C. Zakas
You can also use JSONP as Dan Beam suggested in another answer. It requires some extra JavaScript work, and you may need to "pad" your web service response, but it's another option which works in all current browsers.
You can't circumvent cross-domain origin with XHR (well, only in Firefox 3.5 with user's permission, not a good solution). Technically, moving from port 80 (http) to 443 (https) is breaking that policy (must be same domain and port). This is the example the specification itself sites here - http://www.w3.org/Security/wiki/Same_Origin_Policy#General_Principles.
Have you looked into JSONP (http://en.wikipedia.org/wiki/JSON#JSONP) or CSSHttpRequests (http://nb.io/hacks/csshttprequest)?
JSONP is a way to add a <script> tag to a page with a pre-defined global callback across domains (as you can put the <script>s src to anywhere on the web). Example:
<script>
function globalCallback (a) { /* do stuff with a */ }
And then you insert a <script> tag to your other domain, like so:
var jsonp = document.createElement('script');
json.setAttribute('src','http://path.to/my/script');
document.body.appendChild(jsonp);
</script>
And in the source of the external script, you must call the globalCallback function with the data you want to pass to it, like this:
globalCallback({"big":{"phat":"object"}});
And you'll get the data you want after that script executes!
CSSHttpRequests is a bit more of a hack, so I've never had the need to use it, though feel free to give it a try if you don't like JSONP, :).
You said you would take anything short of having the SSL protocol written in JavaScript... but I assume you meant if you had to write it yourself.
The opensource Forge project provides a JavaScript TLS implementation, along with some Flash to handle cross-domain requests:
http://github.com/digitalbazaar/forge/blob/master/README
Check out the blog posts at the end of the README to get a more in-depth explanation of how it works.

Categories