flypig.co.uk

List items

Items from the current list are shown below.

Blog

21 Jan 2024 : Day 145 #
Yesterday was a light day of gecko development (heavy on everything else but light on gecko). I managed to update the user agent overrides but not a lot else.

The one thing I did do was think about next steps, which brings us to today. To recap, the DuckDuckGo main page is now working. The search page inexplicably has no search results on it and so needs fixing. But the first thing I need to do is check whether the user interaction flags are propagating properly. My working assumption is that in the cases where they're needed they're being set. What I'm less certain about is whether they're not being set when they're not needed.

The purpose of the Sec-Fetch-* headers is to allow the browser to work in collaboration with the server. The user doesn't necessarily trust the page they're viewing and the server doesn't necessarily trust the browser. But the user should trust the browser. And the user should trust the browser to send the correct Sec-Fetch-* headers to the server. Assuming they're set correctly a trustworthy site can then act on them accordingly; for example, by only showing private data when the page isn't being displayed in an iframe, say.

Anyway, the point is, setting the value of these headers is a security feature. The implicit contract between user and browser requires that they're set correctly and the user trusts the browser will do this. The result of not doing so could make it easier for attackers to trick the user. So getting the flags set correctly is really important.

When it comes to understanding the header values and the flags that control them, the key gateway is EmbedLiteViewChild::RecvLoadURL(). The logic for deciding whether to set the flags happens before this is called and all of the logic that uses the flag happens after it. So I'll place a breakpoint on this method and check the value of the flag in various situations.

Which situations? Here are the ones I can think of where the flag should be set to true:
  1. Open a URL at the command line with no existing tabs.
  2. Open a URL at the command line with existing tabs.
  3. Open a URL via D-Bus with no existing tabs.
  4. Open a URL via D-Bus with existing tabs.
  5. Open a URL using xdg-open with no existing tags.
  6. Open a URL using xdg-open with existing tags.
And for the following situations the flag should be set to false.
  1. Open a URL as the homepage.
  2. Enter a URL in the address bar.
  3. Open an item from the history.
  4. Open a bookmark.
  5. Select a link on a page.
  6. Open a URL using JavaScript.
  7. Open a page using the Back button.
  8. Open a page using the Forwards button.
  9. Reloading a page.
Here are the results of one debugging cycle. I've skipped the others that are similar to this.
$ gdb sailfish-browser
(gdb) b EmbedLiteViewChild::RecvLoadURL
Function "EmbedLiteViewChild::RecvLoadURL" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (EmbedLiteViewChild::RecvLoadURL) pending.
(gdb) r https://duckduckgo.com

Thread 8 "GeckoWorkerThre" hit Breakpoint 1, mozilla::embedlite::
    EmbedLiteViewChild::RecvLoadURL (this=0x7f88ad1c60, url=..., 
    aFromExternal=@0x7f9f3d3598: true) at mobile/sailfishos/embedshared/
    EmbedLiteViewChild.cpp:482
482     {
(gdb) p aFromExternal
$2 = (const bool &) @0x7f9f3d3598: true
(gdb) n
483       LOGT("url:%s", NS_ConvertUTF16toUTF8(url).get());
(gdb) n
867     ${PROJECT}/obj-build-mer-qt-xr/dist/include/nsCOMPtr.h:
    No such file or directory.
(gdb) n
487       if (Preferences::GetBool("keyword.enabled", true)) {
(gdb) n
493       if (aFromExternal) {
(gdb) n
497       LoadURIOptions loadURIOptions;
(gdb) n
498       loadURIOptions.mTriggeringPrincipal = nsContentUtils::GetSystemPrincipal();
(gdb) p /x flags
$3 = 0x341000
(gdb) p/x flags & nsIWebNavigation::LOAD_FLAGS_FIXUP_SCHEME_TYPOS
$6 = 0x200000
(gdb) p/x flags & nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP
$7 = 0x100000
(gdb) p/x flags & nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL
$8 = 0x40000
(gdb) p/x flags & nsIWebNavigation::LOAD_FLAGS_FROM_EXTERNAL
$9 = 0x1000
(gdb) p /x flags - (nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP
    | nsIWebNavigation::LOAD_FLAGS_FIXUP_SCHEME_TYPOS
    | nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL
    | nsIWebNavigation::LOAD_FLAGS_FROM_EXTERNAL)
$10 = 0x0
(gdb) 
In a couple of places (selecting links and reloading the page) the EmbedLiteViewChild::RecvLoadURL() method doesn't get called. For those cases I put a breakpoint on LoadInfo::GetLoadTriggeredFromExternal() instead. The process looks a little different:
(gdb) disable break
(gdb) break GetLoadTriggeredFromExternal
Breakpoint 2 at 0x7fb9d3430c: GetLoadTriggeredFromExternal. (2 locations)
(gdb) c
Continuing.

Thread 8 "GeckoWorkerThre" hit Breakpoint 2, mozilla::net::LoadInfo::
    GetLoadTriggeredFromExternal (this=0x7f89170cf0, 
    aLoadTriggeredFromExternal=0x7f9f3d3150) at netwerk/base/LoadInfo.cpp:1478
1478      *aLoadTriggeredFromExternal = mLoadTriggeredFromExternal;
(gdb) p mLoadTriggeredFromExternal
$1 = false
(gdb) 
I've been through and checked the majority of the cases separately. Here's a summary of the results once I apply these processes for all of the cases.
 
Situation Expected Flag set
Open a URL at the command line with no existing tabs. 1 1
Open a URL at the command line with the same tab open. 1 0
Open a URL at the command line with a different tab open. 1 1
Open a URL via D-Bus with no existing tabs. 1 1
Open a URL via D-Bus with the same tab open. 1 No effect
Open a URL via D-Bus with a different tab open. 1 1
Open a URL using xdg-open with no existing tags. 1 1
Open a URL using xdg-open with the same tab open. 1 No effect
Open a URL using xdg-open with a different tab open. 1 1
Open a URL as the homepage. 0 1
Enter a URL in the address bar. 0 0
Open an item from the history. 0 0
Open a bookmark. 0 0
Select a link on a page. 0 0
Open a URL using JavaScript. 0 Not tested
Open a page using the Back button. 0 Unavailable
Open a page using the Forwards button. 0 Unavailable
Reloading a page. 0 0

There are some notable entries in the table although broadly speaking the results are what I was hoping for. For example, when using D-Bus or xdg-open to open the same website that's already available, there is no effect. I hadn't expected this, but having now seen the behaviour in action, it makes perfect sense and looks correct. For the case of opening a URL via the command line with the same tab open, I'll need to look in to whether some other flag should be set instead; but on the face of it, this looks like something that may need fixing.

Similarly for opening a URL as the home page. I think the result is the reverse of what it should be, but I need to look into this more to check.

The forward and back button interactions are marked as "Unavailable". That's because the back and forward functionality are currently broken. I'm hoping that fixing Issue 1024 will also restore this functionality, after which I'll need to test this again.

Finally I didn't get time to test the JavaScript case. I'll have to do that tomorrow.

So a few things still to fix, but hopefully over the next couple of days these can all be ironed out.

If you'd like to read any of my other gecko diary entries, they're all available on my Gecko-dev Diary page.

Comments

Uncover Disqus comments