old - Dave's Blog

Search
My timeline on Mastodon

Changing the User Agent string in UWP WebView

2018 Oct 23, 9:32

There's no perfect way to change the user agent string for the UWP WebView (x-ms-webview in HTML, Windows.UI.Xaml.Controls.WebView in XAML, and Windows.Web.UI.Interop.WebViewControl in Win32) but there are two imperfect methods folks end up using.

The first is to call UrlMkSetSessionOption. This is an old public API that allows you to configure various arcane options including one that is the default user agent string for requests running through urlmon. This API is allowed by the Microsoft Store for UWP apps. The change it applies is process wide which has two potential drawbacks. If you want to be able to have different UA strings set for different requests from a WebView that's not really possible with this solution. The other drawback is if you're using out of process WebView, you need to ensure you're calling into UrlMkSetSessionOption in the WebView's process. You'll need to write third party WinRT that calls UrlMkSetSessionOption, create the out of proc WebView, navigate it to some trusted local page, use AddWebAllowedObject or provide that URI WinRT access, and call into your third party WinRT. You'll need to do that for any new WebView process you create.

The second less generally applicable solution is to use NavigateWithHttpRequestMessage and set the User-Agent HTTP header. In this case you get to control the scope of the user agent string changes but has the limitations that not all sub resource downloads will use this user agent string and for navigations you don't initiate you have to manually intercept and re-request being careful to transfer over all POST body state and HTTP headers correctly. That last part is not actually possible for iframes.

PermalinkCommentsuser-agent uwp webview

Tiny browser features: JSBrowser crash resistance

2018 May 13, 4:59

JSBrowser is a basic browser built as a Win10 JavaScript UWP app around the WebView HTML element. Its fun and relatively simple to implement tiny browser features in JavaScript and in this post I'm implementing crash resistance.

The normal DOM mechanisms for creating an HTML WebView create an in-process WebView, in which the WebView runs on a unique UI thread. But we can use the MSWebView constructor instead to create an out-of-process WebView in which the WebView runs in its own distinct WebView process. Unlike an in-process WebView, Web content running in an out-of-process WebView can only crash the WebView process and not the app process.

        this.replaceWebView = () => {
let webview = document.querySelector("#WebView");
// Cannot access webview.src - anything that would need to communicate with the webview process may fail
let oldSrc = browser.currentUrl;
const webviewParent = webview.parentElement;
webviewParent.removeChild(webview);
webview = new MSWebView();
Object.assign(this, {
"webview": webview
});
webview.setAttribute("id", "WebView");

// During startup our currentUrl field is blank. If the WebView has crashed
// and we were on a URI then we may obtain it from this property.
if (browser.currentUrl && browser.currentUrl != "") {
this.trigger("newWebview");
this.navigateTo(browser.currentUrl);
}
webviewParent.appendChild(webview);

I run replaceWebView during startup to replace the in-process WebView created via HTML markup with an out-of-process WebView. I could be doing more to dynamically copy styles, attributes, etc but I know what I need to set on the WebView and just do that.

When a WebView process crashes the corresponding WebView object is no longer useful and a new WebView element must be created. In fact if the old WebView object is used it may throw and will no longer have valid state. Accordingly when the WebView crashes I run replaceWebView again. Additionally, I need to store the last URI we've navigated to (browser.currentUrl in the above) since the crashed WebView object won't know what URI it is on after it crashes.

            webview.addEventListener("MSWebViewProcessExited", () => { 
if (browser.currentUrl === browser.lastCrashUrl) { ++browser.lastCrashUrlCrashCount;
}
else {
browser.lastCrashUrl = browser.currentUrl;
browser.lastCrashUrlCrashCount = 1;
}
// If we crash again and again on the same URI, maybe stop trying to load that URI.
if (browser.lastCrashUrlCrashCount >= 3) {
browser.lastCrashUrl = "";
browser.lastCrashUrlCrashCount = 0;
browser.currentUrl = browser.startPage;
}
this.replaceWebView();
});

I also keep track of the last URI that we recovered and how many times we've recovered that same URI. If the same URI crashes more than 3 times in a row then I assume that it will keep happening and I navigate to the start URI instead.

PermalinkCommentsbrowser javascript jsbrowser uwp webview win10

Tweet from David Risney

2016 Dec 4, 9:30
@AGoldmund Its my morning two minute hate. And then again around lunch time. And also just whenever.
PermalinkComments

Tweet from Casey Kolderup

2016 Oct 19, 5:18
Github is down, which gave me the opportunity to share this incredible moment with all of you
PermalinkComments

Tweet from Eric Lawrence

2016 Jun 2, 10:32
Chrome relaxes IDN display of Punycode (old restrictions were like IE) to match Firefox instead: https://bugs.chromium.org/p/chromium/issues/detail?id=336973#c34 β€¦
PermalinkComments

Cdb/Windbg Commands for Runtime Patching

2016 Feb 8, 1:47

You can use conditional breakpoints and debugging commands in windbg and cdb that together can amount to effectively patching a binary at runtime. This can be useful if you have symbols but you can't easily rebuild the binary. Or if the patch is small and the binary requires a great deal of time to rebuild.

Skipping code

If you want to skip a chunk of code you can set a breakpoint at the start address of the code to skip and set the breakpoint's command to change the instruction pointer register to point to the address at the end of the code to skip and go. Voila you're skipping over that code now. For example:

bp 0x6dd6879b "r @eip=0x6dd687c3 ; g"

Changing parameters

You may want to modify parameters or variables and this is simple of course. In the following example a conditional breakpoint ANDs out a bit from dwFlags. Now when we run its as if no one is passing in that flag.

bp wiwi!RelativeCrack "?? dwFlags &= 0xFDFFFFFF;g"

Slightly more difficult is to modify string values. If the new string length is the same size or smaller than the previous, you may be able to modify the string value in place. But if the string is longer or the string memory isn't writable, you'll need a new chunk of memory into which to write your new string. You can use .dvalloc to allocate some memory and ezu to write a string into the newly allocated memory. In the following example I then overwrite the register containing the parameter I want to modify:

.dvalloc 100
ezu 000002a9`d4eb0000 "mfcore.dll"
r rcx = 000002a9`d4eb0000

Calling functions

You can also use .call to actually make new calls to methods or functions. Read more about that on the Old New Thing: Stupid debugger tricks: Calling functions and methods. Again, all of this can be used in a breakpoint command to effectively patch a binary.

PermalinkCommentscdb debug technical windbg

Let's Encrypt NearlyFreeSpeech.net Setup

2016 Feb 4, 2:48

2016-Nov-5: Updated post on using Let's Encrypt with NearlyFreeSpeech.net

I use NearlyFreeSpeech.net for my webhosting for my personal website and I've just finished setting up TLS via Let's Encrypt. The process was slightly more complicated than what you'd like from Let's Encrypt. So for those interested in doing the same on NearlyFreeSpeech.net, I've taken the following notes.

The standard Let's Encrypt client requires su/sudo access which is not available on NearlyFreeSpeech.net's servers. Additionally NFSN's webserver doesn't have any Let's Encrypt plugins installed. So I used the Let's Encrypt Without Sudo client. I followed the instructions listed on the tool's page with the addition of providing the "--file-based" parameter to sign_csr.py.

One thing the script doesn't produce is the chain file. But this topic "Let's Encrypt - Quick HOWTO for NSFN" covers how to obtain that:

curl -o domain.chn https://letsencrypt.org/certs/lets-encrypt-x1-cross-signed.pem

Now that you have all the required files, on your NFSN server make the directory /home/protected/ssl and copy your files into it. This is described in the NFSN topic provide certificates to NFSN. After copying the files and setting their permissions as described in the previous link you submit an assistance request. For me it was only 15 minutes later that everything was setup.

After enabling HTTPS I wanted to have all HTTP requests redirect to HTTPS. The normal Apache documentation on how to do this doesn't work on NFSN servers. Instead the NFSN FAQ describes it in "redirect http to https and HSTS". You use the X-Forwarded-Proto instead of the HTTPS variable because of how NFSN's virtual hosting is setup.

RewriteEngine on
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R=301]

Turning on HSTS is as simple as adding the HSTS HTTP header. However, the description in the above link didn't work because my site's NFSN realm isn't on the latest Apache yet. Instead I added the following to my .htaccess. After I'm comfortable with everything working well for a few days I'll start turning up the max-age to the recommended minimum value of 180 days.

Header set Strict-Transport-Security "max-age=3600;" 

Finally, to turn on CSP I started up Fiddler with my CSP Fiddler extension. It allows me to determine the most restrictive CSP rules I could apply and still have all resources on my page load. From there I found and removed inline script and some content loaded via http and otherwise continued tweaking my site and CSP rules.

After I was done I checked out my site on SSL Lab's SSL Test to see what I might have done wrong or needed improving. The first time I went through these steps I hadn't included the chain file which the SSL Test told me about. I was able to add that file to the same files I had already previously generated from the Let's Encrypt client and do another NFSN assistance request and 15 minutes later the SSL Test had upgraded me from 'B' to 'A'.

PermalinkCommentscertificate csp hsts https lets-encrypt nearlyfreespeech.net

Unicode Clock

2016 Jan 24, 2:00

I've made a Unicode Clock in JavaScript.

Unicode has code points for all 30 minute increments of clock faces. This is a simple project to display the one closest to the current time written in JavaScript.

Because the code points are all above 0xFFFF, I make use of some ES6 additions. I use the \u{XXXXXX} style escape sequence since the old style JavaScript escape sequence \uXXXX only supports code points up to 0xFFFF. I also use the method String.codePointAt rather than String.charCodeAt because the code points larger than 0xFFFF are represented in JavaScript strings using surrogate pairs and charCodeAt gives the surrogate value rather than codePointAt which gives the code point represented by the pair of surrogates.

"πŸ•›".codePointAt(0)
128347
"πŸ•›".charCodeAt(0)
55357

πŸ•πŸ•‘πŸ•’πŸ•“πŸ•”πŸ••πŸ•–πŸ•—πŸ•˜πŸ•™πŸ•šπŸ•›πŸ•œπŸ•πŸ•žπŸ•ŸπŸ• πŸ•‘πŸ•’πŸ•£πŸ•€πŸ•₯πŸ•¦πŸ•§

The ordering of the code points does not make it simple to do this. I initially guessed the first code point in the range would be 12:00 followed by 12:30, 1:00 and so on. But actually 1:00 is first followed by all the on the hour times then all the half hour times.

PermalinkCommentsjavascript Unicode

Retweet of JustRogDigiTec

2015 Nov 29, 2:58
@JustRogDigiTec A fiddle as well http://jsfiddle.net/xb3gheqb/  in case it clarifies. Note: An older browser may not demo properly
PermalinkComments

Tweet from David_Risney

2015 Nov 18, 2:53
Old time tintype photograph of Adam Savage looks really good. Photographer Michael Shindler explains & demos process https://www.youtube.com/watch?v=T_gQgkCfj7w β€¦
PermalinkComments

Retweet of stevesi

2015 Oct 25, 8:38
πŸ™ https://twitter.com/HuzefaMotiwala/status/658495033541283840 β€¦
PermalinkComments

Retweet of slightlylate

2015 Aug 19, 1:54
The thing where you remember old versions of the spec and, despite being the "expert" in the room, can't recall what was eventually decided.
PermalinkComments

Retweet of jacobrossi

2015 Aug 10, 6:52
Rocking out with @macklemore and @jdalton celebrating Windows 10 #cantholdus pic.twitter.com/NDVrPbJuoc
PermalinkComments

laughingsquid: A Real Hedgehog Scurries Along to Music From the...

2015 Apr 23, 1:17


laughingsquid:

A Real Hedgehog Scurries Along to Music From the β€˜Sonic the Hedgehog’ Video Game While Collecting Golden Rings

PermalinkComments

laughingsquid: A Real Hedgehog Scurries Along to Music From the...

2015 Apr 23, 1:17


laughingsquid:

A Real Hedgehog Scurries Along to Music From the β€˜Sonic the Hedgehog’ Video Game While Collecting Golden Rings

PermalinkComments

Tweet from David_Risney

2015 Apr 2, 10:43
Tesla's April fools headline fooled stock trading algorithms causing $1.50 jump: http://www.bloombergview.com/articles/2015-04-02/tesla-stockholders-can-t-take-a-joke β€¦
PermalinkComments

Retweet of linkalis

2015 Mar 15, 9:30
Was skeptical at first, but now I'm sold! "USB Type-C Explained: What It Is and Why You’ll Want it" http://www.howtogeek.com/211843/usb-type-c-explained-what-it-is-and-why-youll-want-it/ β€¦ @howtogeek
PermalinkComments

Retweet of industrial_book

2015 Mar 6, 6:11
Old war. New battlefield. #mathjoke pic.twitter.com/TvWxI0h8Xw
PermalinkComments

Tweet from David_Risney

2015 Feb 1, 8:13
Presently enjoying Ghost in the Shell Arise. Only somewhat confused hearing voices of old Major and Piccolo out of different characters
PermalinkComments

Retweet of panzer

2015 Feb 1, 3:01
Call me old fashioned but I want Superbowl commercials to hypersexualize food and trucks not make me want to double check my childproofing
PermalinkComments
Older Entries Creative Commons License Some rights reserved.