Bypass blocking of subresource requests whose URLs contain embedded credentials - html

I have been automatically authenticating users visiting our internal wiki via a link with a token in the URL like this:
href="https://user:pass#host/"
In Chrome 59, this is being prevented.
[Deprecation] Subresource requests whose URLs contain embedded credentials (e.g. https://user:pass#host/) are blocked.
I read and I bypassed it in an ajax request like this:
how to replace embedded credentials in subresource requests
========================================================================
My Question is:
Does anyone know how to do it directly in the link, or can you provide some kind of workaround? Is this even possible?

Passing the command line option '--disable-blink-features=BlockCredentialedSubresources' restores the expected behavior. If you're using Selneium, you can pass it as an args option in the Browser Capabilities to restore the expected behavior.
PHP:
'chromeOptions' => array('args' => ['--disable-blink-features=BlockCredentialedSubresources']);
Python:
capabilities['chromeOptions'] = {'args': ['--headless']}
According to the Chromium ticket (https://bugs.chromium.org/p/chromium/issues/detail?id=731618) this behavior may not be restored in future versions despite it being in 'Deprecation'. In this case, it might be best to look at ssh conduits for testing or whitelist the IP if possible to prevent the HTTP Auth interaction.
Anthony

If your page includes css, javascript or other stuff with relative ("folder/file") or base-relative ("/folder/file") locations, then the problem is that these included files would be fetched from a URL relative to the base URL of the page, which includes a user:pass component.
It is that user:pass componenent (which you possibly never meant to imply anyway...) which makes the URL of the subresources illegal, following this change to Chrome.
If that is your problem, you can fix it by adding a <base href="https://host/"> tag to your page (i.e. the same base address, but without the user:pass component). (If your page is in a subdirectory, you need to include the subdirectory in the base href as well, for fully relative URLs to work.)
To be clear, links like Link still work (as long as the user:pass URL is in a link which opens in a new page, and is not a URL for an iframe, say - that is now banned). But even when the link works, the problem I've described above applies to elements included with relative paths in the newly opened page.
UPDATE:
This has been accepted as a bug in Chrome, directly related to the new changes banning user:pass in subresource URLs. Unfortunately, following through the links in that discussion, it seems that one proposed and quite likely solution is to remove support for user:pass URLs entirely. Any informed comments added to that discussion and arguing in favour of keeping this feature would presumably help.

To handle this, we have to pass chrome options : "--disable-blink-features=BlockCredentialedSubresources");
Complete code is mentioned below :
ChromeOptions options = new ChromeOptions();
options.addArguments("--start-maximized");
options.addArguments("--disable-blink-features=BlockCredentialedSubresources");
Map<String, Object> prefs = new HashMap<String, Object>();
prefs.put("credentials_enable_service", false);
prefs.put("profile.password_manager_enabled", false);
options.setExperimentalOption("prefs", prefs);
DesiredCapabilities capabilities = DesiredCapabilities.chrome();
capabilities.setCapability(ChromeOptions.CAPABILITY, options);
driver = new ChromeDriver(capabilities);

Related

Href without http(s) prefix

I just have created primitive html page. Here it is: example
And here is its markup:
www.google.com
<br/>
http://www.google.com
As you can see it contains two links. The first one's href doesn't have 'http'-prefix and when I click this link browser redirects me to non-existing page https://fiddle.jshell.net/_display/www.google.com. The second one's href has this prefix and browser produces correct url http://www.google.com/. Is it possible to use hrefs such as www.something.com, without http(s) prefixes?
It's possible, and indeed you're doing it right now. It just doesn't do what you think it does.
Consider what the browser does when you link to this:
href="index.html"
What then would it do when you link to this?:
href="index.com"
Or this?:
href="www.html"
Or?:
href="www.index.com.html"
The browser doesn't know what you meant, it only knows what you told it. Without the prefix, it's going to follow the standard for the current HTTP address. The prefix is what tells it that it needs to start at a new root address entirely.
Note that you don't need the http: part, you can do this:
href="//www.google.com"
The browser will use whatever the current protocol is (http, https, etc.) but the // tells it that this is a new root address.
You can omit the protocol by using // in front of the path. Here is an example:
Google
By using //, you can tell the browser that this is actually a new (full) link, and not a relative one (relative to your current link).
I've created a little function in React project that could help you:
const getClickableLink = link => {
return link.startsWith("http://") || link.startsWith("https://") ?
link
: `http://${link}`;
};
And you can implement it like this:
const link = "google.com";
<a href={getClickableLink(link)}>{link}</a>
Omitting the the protocol by just using // in front of the path is a very bad idea in term of SEO.
Ok, most of the modern browsers will work fine. On the other hand, most of the robots will get in trouble scanning your site. Masjestic will not count the flow from those links. Audit tools, like SEMrush, will not be able to perform their jobs

Does Postmessage work between individual web pages under the same domain? If so, how?

In my code, I have this:
<script>
var iframe = document.getElementById("some_iframe").contentWindow; //sending part
iframe.postMessage("X", 'http?://example.com');
</script>
On the receiving page, I have
<script>
window.addEventListener("message", receiveMessage, false);
function receiveMessage(event) { alert(e.data); } // no security concerns here, just the message is needed
</script>
When I look into the console of the sending page, I get this error:
Unable to post message to http?://example.com. Recipient has origin http?://www.example.com
Can't post more than two links, whatever so I put a ? just after http. Not actually in the code.
Actually, I think I found the answer. It's subtle, but www is what's interfering, right? But just to be sure, you can use postMessage for communication between two documents on the same server?
Some example code would be great as well. Thanks!
You can look in detail about how postMessage works and the quirks when dealing with same-or-cross-domain and sandboxing in this tutorial. For basic reference see this article.
In short, you can do postMessage between any two windows, no matter the domain.
Now that I think of it, just to be clear, both windows have to be open under the same document tree, meaning they must have a common parent document (as in the same browser tab on the same device). I am not sure if you think you can achieve this on different browsers or tabs or devices, which is not the case, and you must look at web-sockets and webRTC for that, as this is a completely different feature.

I have a public URL for an iCloud file, how can I get the DIRECT link to download in iOS?

I am able to generate public URLs for iCloud files. e.g. https://www.icloud.com/documents/dl/?p=3&t=BAKsXkcDP-p8sdTS8NgBLWRQxE281oe4hogA
Accessing such a URL from a browser, I see a landing page, and shorty afterwards the file downloads automatically. Fine.
However, I want to be able to download this file from my iOS app (with NSURLConnection). How can I do this? Maybe...
a) process the html headers to somehow determine the direct URL?
b) intercept the redirect/refresh that triggers the download on a browser?
c) somehow imitate a browser in order to trigger a download?
Thanks
PS. please give me the idiot's answer- I'm clueless about html etc.
Here is the html response I'm getting for the indirect URL above:
var SC_benchmarkPreloadEvents={headStart:new Date().getTime()}; -->iCloud - Loading ...window.SC=window.SC||{MODULE_INFO:{},LAZY_INSTANTIATION:{}};SC.buildMode="production";
SC.buildNumber="1FCS22.32292";SC.buildLocale="en-us";String.preferredLanguage="en-us";window.SC=window.SC||{MODULE_INFO:{},LAZY_INSTANTIATION:{}};SC._detectBrowser=function(userAgent,language){var version,webkitVersion,browser={};
userAgent=(userAgent||navigator.userAgent).toLowerCase();language=language||navigator.language||navigator.browserLanguage;
version=browser.version=(userAgent.match(/.*(?:rv|chrome|webkit|opera|ie)/: ([ );]|$)/)||[])[1];
webkitVersion=(userAgent.match(/webkit/(.+?) /)||[])[1];browser.windows=browser.isWindows=!!/windows/.test(userAgent);
browser.mac=browser.isMac=!!/macintosh/.test(userAgent)||(/mac os x/.test(userAgent)&&!/like mac os x/.test(userAgent));
browser.lion=browser.isLion=!!(/mac os x 10_7/.test(userAgent)&&!/like mac os x 10_7/.test(userAgent));
browser.iPhone=browser.isiPhone=!!/iphone/.test(userAgent);browser.iPod=browser.isiPod=!!/ipod/.test(userAgent);
browser.iPad=browser.isiPad=!!/ipad/.test(userAgent);browser.iOS=browser.isiOS=browser.iPhone||browser.iPod||browser.iPad;
browser.android=browser.isAndroid=!!/android/.test(userAgent);browser.opera=/opera/.test(userAgent)?version:0;
browser.isOpera=!!browser.opera;browser.msie=/msie/.test(userAgent)&&!browser.opera?version:0;
browser.isIE=!!browser.msie;browser.isIE8OrLower=!!(browser.msie&&parseInt(browser.msie,10)<=8);
browser.mozilla=/mozilla/.test(userAgent)&&!/(compatible|webkit|msie)/.test(userAgent)?version:0;
browser.isMozilla=!!browser.mozilla;browser.webkit=/webkit/.test(userAgent)?webkitVersion:0;
browser.isWebkit=!!browser.webkit;browser.chrome=/chrome/.test(userAgent)?version:0;
browser.isChrome=!!browser.chrome;browser.mobileSafari=/apple.*mobile/.test(userAgent)&&browser.iOS?webkitVersion:0;
browser.isMobileSafari=!!browser.mobileSafari;browser.iPadSafari=browser.iPad&&browser.isMobileSafari?webkitVersion:0;
browser.isiPadSafari=!!browser.iPadSafari;browser.iPhoneSafari=browser.iPhone&&browser.isMobileSafari?webkitVersion:0;
browser.isiPhoneSafari=!!browser.iphoneSafari;browser.iPodSafari=browser.iPod&&browser.isMobileSafari?webkitVersion:0;
browser.isiPodSafari=!!browser.iPodSafari;browser.isiOSHomeScreen=browser.isMobileSafari&&!/apple.*mobile.*safari/.test(userAgent);
browser.safari=browser.webkit&&!browser.chrome&&!browser.iOS&&!browser.android?webkitVersion:0;
browser.isSafari=!!browser.safari;browser.language=language.split("-",1)[0];browser.current=browser.msie?"msie":browser.mozilla?"mozilla":browser.chrome?"chrome":browser.safari?"safari":browser.opera?"opera":browser.mobileSafari?"mobile-safari":browser.android?"android":"unknown";
return browser};SC.browser=SC._detectBrowser();if(typeof SC_benchmarkPreloadEvents!=="undefined"){SC.benchmarkPreloadEvents=SC_benchmarkPreloadEvents;
SC_benchmarkPreloadEvents=undefined}else{SC.benchmarkPreloadEvents={headStart:new Date().getTime()}
}SC.setupBodyClassNames=function(){var el=document.body;if(!el){return}var browser,platform,shadows,borderRad,classNames,style;
browser=SC.browser.current;platform=SC.browser.windows?"windows":SC.browser.mac?"mac":"other-platform";
style=document.documentElement.style;shadows=(style.MozBoxShadow!==undefined)||(style.webkitBoxShadow!==undefined)||(style.oBoxShadow!==undefined)||(style.boxShadow!==undefined);
borderRad=(style.MozBorderRadius!==undefined)||(style.webkitBorderRadius!==undefined)||(style.oBorderRadius!==undefined)||(style.borderRadius!==undefined);
classNames=el.className?el.className.split(" "):[];if(shadows){classNames.push("box-shadow")
}if(borderRad){classNames.push("border-rad")}classNames.push(browser);if(browser==="chrome"){classNames.push("safari")
}classNames.push(platform);var ieVersion=parseInt(SC.browser.msie,10);if(ieVersion){if(ieVersion===7){classNames.push("ie7")
}else{if(ieVersion===8){classNames.push("ie8")}else{if(ieVersion===9){classNames.push("ie9")
}}}}if(SC.browser.mobileSafari){classNames.push("mobile-safari")}if("createTouch" in document){classNames.push("touch")
}el.className=classNames.join(" ")};(function(){var styles=[];if(window.devicePixelRatio==2||window.location.search.indexOf("2x")>-1){styles=["/applications/documents/download/en-us/1FCS22.32292/stylesheet#2x-packed.css"];
SC.APP_IMAGE_ASSETS=["/applications/documents/sproutcore/desktop/en-us/1FCS22.32292/stylesheet-no-repeat#2x.png","/applications/documents/coreweb/views/en-us/1FCS22.32292/stylesheet-no-repeat#2x.png","/applications/documents/sproutcore/ace/en-us/1FCS22.32292/stylesheet-no-repeat#2x.png","/applications/documents/sproutcore/ace/en-us/1FCS22.32292/stylesheet-repeat-x#2x.png","/applications/documents/sproutcore/ace/en-us/1FCS22.32292/stylesheet-repeat-y#2x.png","/applications/documents/download/en-us/1FCS22.32292/stylesheet-no-repeat#2x.png","/applications/documents/download/en-us/1FCS22.32292/stylesheet-repeat-x#2x.png"]
}else{styles=["/applications/documents/download/en-us/1FCS22.32292/stylesheet-packed.css"];
SC.APP_IMAGE_ASSETS=["/applications/documents/sproutcore/desktop/en-us/1FCS22.32292/stylesheet-no-repeat.png","/applications/documents/coreweb/views/en-us/1FCS22.32292/stylesheet-no-repeat.png","/applications/documents/sproutcore/ace/en-us/1FCS22.32292/stylesheet-no-repeat.png","/applications/documents/sproutcore/ace/en-us/1FCS22.32292/stylesheet-repeat-x.png","/applications/documents/sproutcore/ace/en-us/1FCS22.32292/stylesheet-repeat-y.png","/applications/documents/download/en-us/1FCS22.32292/stylesheet-no-repeat.png","/applications/documents/download/en-us/1FCS22.32292/stylesheet-repeat-x.png"]
}var head=document.getElementsByTagName("head")[0],len=styles.length,idx,css;for(idx=0;
idxSC.benchmarkPreloadEvents.headEnd=new Date().getTime();SC.benchmarkPreloadEvents.bodyStart=new Date().getTime();if(SC.setupBodyClassNames){SC.setupBodyClassNames()};SC.benchmarkPreloadEvents.bodyEnd=new Date().getTime();
As of July 2012, the following seems to work. But there's no guarantee that apple won't change their scheme for generating these, and it's possible that they would regard this as a private API and reject your app. So use at your own risk.
The URL has two important parameters, p and t. The first seems to identify a server, while the second identifies the actual file. The direct download link is made by plugging these values into this URL:
https://p[p]-ubiquityws.icloud.com/ws/file/[t]
Looking at your example:
https://www.icloud.com/documents/dl/?p=3&t=BAKsXkcDP-p8sdTS8NgBLWRQxE281oe4hogA
p is 3, and t is BAKsXkcDP-p8sdTS8NgBLWRQxE281oe4hogA. So your direct download link would be
https://p3-ubiquityws.icloud.com/ws/file/BAKsXkcDP-p8sdTS8NgBLWRQxE281oe4hogA
Whenever I've published a link to iCloud, p has been 01; so it's possible that you might need to zero-pad your value in which case your URL would be
https://p03-ubiquityws.icloud.com/ws/file/BAKsXkcDP-p8sdTS8NgBLWRQxE281oe4hogA
It would be great to know whether that's necessary.
In iCloud Drive / iOS8 the links are different, but you can still get a direct link to the files.
Original link:
https://www.icloud.com/attachment?u=https%3A%2F%2Fms-eu-ams-103-prod.digitalhub.com%2FB%2FATmkKK8ju8SRwQqDoEFKJzbRsxiuAXQ3PBcJBXw1Qot9jz68TkqjiiNu%2F%24%7Bf%7D%3Fo%3DAtenENR8OcvlNq6JMa331mr-8gCreXxwcfgQ26B5gFKo%26v%3D1%26x%3D3%26a%3DBclucinSeKmFAy2GJg%26e%3D1413787013%26k%3D%24%7Buk%7D%26r%3D567CC38A-FD1B-4DE6-B11B-4166A5669E1B-1%26z%3Dhttps%253A%252F%252Fp03-content.icloud.com%253A443%26s%3DlO5SolOouS9qhYz1oIxKDoGtMpo%26hs%3DovfPXj3b9XXz9lWKChBmyNq_cug&uk=OXDCcLTETbvUcOKdJ-vTdQ&f=Testdatei.vrphoto&sz=1212622
URL decoded to be more readable:
https://www.icloud.com/attachment?u=https://ms-eu-ams-103-prod.digitalhub.com/B/ATmkKK8ju8SRwQqDoEFKJzbRsxiuAXQ3PBcJBXw1Qot9jz68TkqjiiNu/${f}?o=AtenENR8OcvlNq6JMa331mr-8gCreXxwcfgQ26B5gFKo&v=1&x=3&a=BclucinSeKmFAy2GJg&e=1413787013&k=${uk}&r=567CC38A-FD1B-4DE6-B11B-4166A5669E1B-1&z=https%3A%2F%2Fp03-content.icloud.com%3A443&s=lO5SolOouS9qhYz1oIxKDoGtMpo&hs=ovfPXj3b9XXz9lWKChBmyNq_cug&uk=OXDCcLTETbvUcOKdJ-vTdQ&f=Testdatei.vrphoto&sz=1212622
Save the text between '?u=' and '&uk=' as a NSMutableString
Save the information after 'uk=' and 'f=' as NSStrings
In the first string replace the text '${f}' with the 'f=' string and replace the text '${uk}' whith the 'uk=' string
If you need the files size for any reason, it's the number after 'sz=', but this is not needed for the final link
Voila, here is your direct link to the file:
https://ms-eu-ams-103-prod.digitalhub.com/B/ATmkKK8ju8SRwQqDoEFKJzbRsxiuAXQ3PBcJBXw1Qot9jz68TkqjiiNu/Testdatei.vrphoto?o=AtenENR8OcvlNq6JMa331mr-8gCreXxwcfgQ26B5gFKo&v=1&x=3&a=BclucinSeKmFAy2GJg&e=1413787013&k=OXDCcLTETbvUcOKdJ-vTdQ&r=567CC38A-FD1B-4DE6-B11B-4166A5669E1B-1&z=https%3A%2F%2Fp03-content.icloud.com%3A443&s=lO5SolOouS9qhYz1oIxKDoGtMpo&hs=ovfPXj3b9XXz9lWKChBmyNq_cug
It looks like the heavy lifting is done by the file referenced there:
https://www.icloud.com/applications/documents/download/en-us/1FCS22.32292/javascript-packed.js
I'd start there looking for the file name etc.

Chrome extension, replace HTML in response code before browser displays it

i wonder if there is some way to do something like that:
If im on a specific site i want that some of javascript files to be loaded directly from my computer (f.e. file:///c:/test.js), not from the server.
For that i was thinking if there is a possibility to make an extension which could change HTML code in a response which browser gets right before displaying it. So whole process should look like that:
request is made
browser gets response from server
#response is changed# - this is the part when extension comes in
browser parse changed response and display page with that new response.
It doesnt even have to be a Chrome extension anyway. It should just do the job described above. It can block original file and serve another one (DNS/proxy?) or filter whole HTTP traffic in my computer and replace specific code to another one of matched response.
You can use the WebRequest API to achieve that. For example, you can add a onBeforeRequest listener and redirect some requests:
chrome.webRequest.onBeforeRequest.addListener(function(details)
{
var responseData = "<div>Some text</div>"
return {redirectUrl: "data:text/html," + encodeURIComponent(responseData)};
}, {urls: ["https://www.google.com/"]}, ["blocking"]);
This will display a <div> element with the text "some text" instead of the Google homepage. Note that you can only redirect to URLs that the web server itself is allowed to redirect to. This means that redirecting to file:/// URLs is not possible, and you can only redirect to files inside your extension if these are web accessible. data: and http: URLs work fine however.
In Windows you can use the Proxomitron (proxomitron.info) which is a local proxy that can intercept any page or file being loading into your browser and change it using regular expressions (no DOM parsing) however you want, before it is rendered by the browser.

How to set the <img> tag with basic authentication

I would like to display the image from a network camera on my web page, but the image is behind a HTTP basic authentication server.
In Firefox and Chrome I can do this:
<img width="320" height="200" src="http://username:password#server/Path" />
But in Internet Explorer 8, I get an empty image box. If I use JQuery to set the src attribute, IE8 displays a blank src. It looks like IE8 is checking the string and rejecting it.
Is there a way to put the basic authentication credentials in the img tag?
Bottom line: Not all browsers allow this. It may work in some but not others.
But as someone else has said already, it's not very safe -- you're effectively giving the login and password details to anyone who browses the page. Not good.
A better option would be proxy it through the same server that you're providing the html code from, then the href in the <img> tag could just be a local URL, and no-one need know where the image is actually coming from.
You can load your img with AJAX, using XMLHttpRequest. As you might know, XMLHttpRequest has a setRequestHeaders method, so you will be able to manipulate headers for your request, hence, you will be able to do basic HTTP authentication.
Best way is to create a login page, then setup port forwarding on your router to display the camera. Does the camera come with web software?
See http://support.microsoft.com/kb/834489 and http://msdn.microsoft.com/en-us/library/ie/ee330735(v=vs.85).aspx#login_creds_urls
Long story short, usernames/passwords are not formally supported under the HTTP/HTTPS protocol schemes and due to their use in phishing attacks, they were disabled in IE6 on XPSP2. Support can be manually re-enabled by the user using a registry override (FEATURE_HTTP_USERNAME_PASSWORD_DISABLE) but this is not recommended.
Try http proxy.
On server side, enable tinyProxy, create ReversePath to
basic authentication server in configuration like:
AddHeader "Authorization" "Basic dXNlcjpwYXNz"
ReversePath "/foo/" "http://somewhere:3480/foo/"
dXNlcjpwYXNz is base64 encoded string from user:pass
Enable reverse proxy in Apache or NGINX to tinyProxy path http://localhot:8888/foo/
Img Source accessable from local server instead of old way deprecated, without http auth pop-up or CORS error.
http://user:pass#somewhere:3480/foo/DEST.jpg
ajax add http header works!
pictureUrl = "https://somewhere/file.jpg";
var oReq = new XMLHttpRequest();
oReq.open("GET", pictureUrl, true);
oReq.setRequestHeader("Authorization", "Basic " + btoa("UserName"+":"+"Password"));
// use multiple setRequestHeader calls to set multiple values
oReq.responseType = "arraybuffer";
oReq.onload = function (oEvent) {
var arrayBuffer = oReq.response; // Note: not oReq.responseText
if (arrayBuffer) {
var u8 = new Uint8Array(arrayBuffer);
var b64encoded = btoa(String.fromCharCode.apply(null, u8));
var mimetype="image/jpeg"; // or whatever your image mime type is
document.getElementById("iOdata").src="data:"+mimetype+";base64,"+b64encoded;
}
};
oReq.send(null);