8

I've implemented async pluggable protocol in a .net 2.0 application using C# which loads html files stored on the local machine into a MemoryStream.

when I load the html files normally in the webbrowser control using their local file paths, xmlhttprequest works fine but loading the files through the protocol and an attempt to use xmlhttprequest returns an access denied error.

I presume that this behavior is due to the webbrowser control no longer knowing that the html files are stored on the local machine, and is loading them in an untrusted internet zone.

Even though I'm returning S_OK for URLACTION_CROSS_DOMAIN_DATA inside IInternetSecurityManager's ProcessUrlAction which I checked with a break point to make sure it was fired, my IInternetSecurityManager's return value for this action is being ignored.

I've tried setting pdwZone to tagURLZONE.URLZONE_LOCAL_MACHINE in IInternetSecurityManager's MapUrlToZone for my protocol URLs and played around a little with GetSecurityId although I'm not sure exactly what I'm doing with and broke other things like allowing scripts to load etc... Nothing seems to work to allow cross-domain xmlhttprequest.

Anyone any idea how I can get this to work.

John Earnshaw
  • 331
  • 3
  • 14
  • You may try playing with [feature control](http://msdn.microsoft.com/en-us/library/ie/ee330733(v=vs.85).aspx), but I would not have high hopes for that. You may be better off with a small in-app `HttpListener`-based web server and user `http://localhost` rather than your custom APP handler. – noseratio Mar 17 '14 at 23:48
  • @Noseratio thanks for the comment. The project I'm working on is not single instance and could be running up to 20 times on one machine so I didn't fancy the http listener method, originally I didn't like the idea of potential firewall issues. I'm sure APP is the way it should be done. the implementation of GetSecurityId here doesn't work for me:[link](http://stackoverflow.com/questions/6827940/override-ie-privacy-settings-using-iinternetsecuritymanager-in-webbrowser-contro) – John Earnshaw Mar 21 '14 at 03:16
  • cEXWB2 at [link](https://code.google.com/p/csexwb2/) has a different signature and doesn't work for me either: `//private const string m_strSecurity = "None:localhost+My Computer"; int IInternetSecurityManager.GetSecurityId(string pwszUrl, IntPtr pbSecurityId, ref uint pcbSecurityId, ref uint dwReserved) { //pbSecurityId = Marshal.StringToCoTaskMemAnsi(m_strSecurity); //pcbSecurityId = (uint)m_strSecurity.Length; //return Hresults.S_OK; return (int)WinInetErrors.INET_E_DEFAULT_ACTION; }` I've can't find much about it. – John Earnshaw Mar 21 '14 at 03:20
  • JasperS, you're probably doing it the way it should be. It's just I have a feeling that the APP stuff has been silently deprecated by Microsoft since IE9, and hasn't been tested and maintained very well since then. Have you tried playing with `FEATURE_PROTOCOL_LOCKDOWN` and `FEATURE_LOCALMACHINE_LOCKDOWN`? – noseratio Mar 21 '14 at 03:52
  • @Noseratio I looked at `FEATURE_PROTOCOL_LOCKDOWN` and `FEATURE_LOCALMACHINE_LOCKDOWN` but don't really know how to implement them and if they will even work from reading the documentation. I really wanted a per instance solution too as I want each running instance to have it's own security settings. perhaps you could take a look at my solution? Although it's a bit messy at the mo, it's currently private on bit bucket as I'm planning to open source it once I get this bit working :) I'm having trouble with `IProfferService` too. `QueryService` on `ActiveXInstance` for proffer is `IntPtr.Zero` – John Earnshaw Mar 21 '14 at 22:30
  • `IProfferService` has worked for me: http://stackoverflow.com/a/19395092/1768303 – noseratio Mar 21 '14 at 22:35
  • 1
    @Noseratio doh, I just reviewed my proffer code and realized I was missing the `ref` on my `IntPtr`. It didn't make any difference to my weird `IHostBehaviorInit` issue though :( – John Earnshaw Mar 21 '14 at 23:06
  • You want to fire request to other domain from different domain right. Try to access cross-domain data? – Ashwin Parmar Jun 10 '14 at 12:53

2 Answers2

4

Not really an answer, but it may help to isolate the problem. I'd first implement this APP handler in C++ and test it with some robust unmanaged WebBrowser ActiveX host sample, like Lician Wishick's Webform:

http://www.wischik.com/lu/programmer/webform.html

If I could get it working reliably with the unmanaged host, I'd proceed with C# implementation.

I'd also try setting FEATURE_BROWSER_EMULATION to 8000 or less, to impose emulation of legacy IE behavior, just to check if it works that way.

That said, I wouldn't hold my hopes high. I've done my share of WebBrowser/MSHTML integration in the past, and I have a feeling that the APP support hasn't been regression-tested since IE9, in favor for new IE stuff aimed to embrace open web standards.

Updated, MSDN vaguely mentions this:

Upon successful completion, pbSecurityId contains the scheme, domain, and zone information, as well as whether the specified pwszUrl was derived from a Mark of the Web.

Here's the format which worked for me long ago (perhaps, way before "Mark of the Web" was introduced):

static const char security[] = "https:www.mysite.com\2\0\0"; // C++ puts the termination \0 for us

I believe, 2 stands here for the "Trusted Sites" zone. Other zones can be found here:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Lockdown_Zones

Hope this helps.

Community
  • 1
  • 1
noseratio
  • 59,932
  • 34
  • 208
  • 486
  • 1
    `FEATURE_BROWSER_EMULATION` is set to `7000`, so that isn't the problem. I think John is working on the other suggestions in your answer. In the meantime, we've had to settle with overriding `XMLHttpRequest` and `ActiveXObject` with .NET supplied equivalents, a solution that I'm not really happy with but works "for now". It doesn't solve the problem for x-domain iframes, however. – Andy E Jun 10 '14 at 07:39
1

Maybe I'm wrong but, have you tried to send in your protocol headers Access-Control-Allow-Origin: *?

ZeroWorks
  • 1,618
  • 1
  • 18
  • 22
  • 2
    `Access-Control-Allow-Origin` isn't relevant for several reasons. Mostly because the majority of pages run in IE 7 mode (so XHR doesn't support CORS), but also because the host page is on the custom protocol and it's trying to communicate over `http://`. – Andy E Jun 10 '14 at 07:41