Check trusted location before from_webstore in chromiumSideloaded

Resolves #50706

chromiumSideloaded returned true as soon as from_webstore was 0, never
reaching the trusted-location check. First-party browser components are
installed by the browser itself and so always report
from_webstore:false, which made the location exemption unreachable and
flagged components like Edge Copilot Bridge as sideloaded_unverified.

Check location for Internal/Component first. The existing collector
fixture asserted the buggy behaviour and is updated to a genuinely
sideloaded location, with a first-party component case added.
This commit is contained in:
Juan Fernandez
2026-08-07 15:39:47 -04:00
committed by GitHub
parent fc97ff2e61
commit 9cb3a5e206
2 changed files with 56 additions and 9 deletions
@@ -40,18 +40,34 @@ func TestHasBroadHostPerms(t *testing.T) {
func TestChromiumSideloaded(t *testing.T) {
// fromWebstore: -1 unknown, 0 no, 1 yes. location: 0 unknown, 1 internal, 4 unpacked, 5 component, 10 external.
// Exhaustive over those two sets. Keep it that way — the outcome turns on
// which of the two signals is consulted first, so a reordering can silently
// change a case no test covers.
cases := []struct {
fw, loc int
want bool
}{
{1, 1, false}, // store + internal
{0, 1, true}, // explicitly not webstore
{1, 5, false}, // store + component
{1, 0, false}, // store-flagged, location unreadable -> nothing anomalous
{-1, 1, false}, // internal, store signal unknown
{-1, 4, true}, // unpacked
{-1, 10, true}, // external/policy
{-1, 5, false}, // component
{-1, 0, false}, // both unknown -> conservative, no flag
{1, 4, true}, // store-flagged but unpacked location -> still anomalous
{1, 10, true}, // store-flagged but external/policy location -> still anomalous
// A trusted location wins over from_webstore: the browser installs its
// own first-party components itself, so they always report
// from_webstore:false and must not be called sideloaded.
{0, 1, false}, // first-party internal component
{0, 5, false}, // first-party component (e.g. Edge Copilot Bridge)
// from_webstore:false still flags anything without a trusted location.
{0, 0, true}, // not from the store, location unknown
{0, 4, true}, // not from the store, unpacked
{0, 10, true}, // not from the store, external/policy
}
for _, c := range cases {
if got := chromiumSideloaded(c.fw, c.loc); got != c.want {
@@ -129,12 +145,21 @@ func TestCollectChromiumProfile(t *testing.T) {
`{"name":"Claude Dev","version":"9.9.9","manifest_version":3,"permissions":["<all_urls>"]}`)
unpackedID := "cccccccccccccccccccccccccccccccc"
// Secure Preferences: AI ext not-from-webstore (sideloaded), unpacked entry.
// First-party browser component: installed by the browser itself, so
// from_webstore is false and location is 5 (component). Preferences-only,
// like a real built-in. Must NOT be flagged sideloaded. Carries broad host
// perms so the assertion below can tell "sideloaded token suppressed" apart
// from "risk never computed at all".
componentID := "dddddddddddddddddddddddddddddddd"
// Secure Preferences: AI ext not-from-webstore and externally installed
// (sideloaded), unpacked entry, and a trusted first-party component.
prefs := map[string]any{
"extensions": map[string]any{
"settings": map[string]any{
aiID: map[string]any{"from_webstore": false, "location": 1},
unpackedID: map[string]any{"location": 4, "path": unpackedSrc, "manifest": map[string]any{"name": "Claude Dev", "version": "9.9.9", "permissions": []string{"<all_urls>"}}},
aiID: map[string]any{"from_webstore": false, "location": 10},
unpackedID: map[string]any{"location": 4, "path": unpackedSrc, "manifest": map[string]any{"name": "Claude Dev", "version": "9.9.9", "permissions": []string{"<all_urls>"}}},
componentID: map[string]any{"from_webstore": false, "location": 5, "manifest": map[string]any{"name": "Edge Copilot Bridge", "version": "1.2.3", "permissions": []string{"<all_urls>"}}},
},
},
}
@@ -175,6 +200,16 @@ func TestCollectChromiumProfile(t *testing.T) {
if up.Name != "Claude Dev" || up.SHA256 == "" || !contains(up.RiskFlags, "sideloaded_unverified") {
t.Errorf("unpacked ext wrong: %+v", up)
}
comp, ok := by[componentID]
if !ok {
t.Fatal("first-party component (Preferences-only) not recovered")
}
// Exact match, not a negated substring check: the component must lose the
// sideloaded token and keep every other flag it earns. A negated contains()
// would also pass if risk were never computed for this row at all.
if comp.RiskFlags != "broad_host_permissions" {
t.Errorf("RiskFlags=%q want %q — a trusted first-party component drops only the sideloaded token", comp.RiskFlags, "broad_host_permissions")
}
}
func contains(haystack, needle string) bool { return strings.Contains(haystack, needle) }
@@ -20,8 +20,11 @@ func hasBroadHostPerms(patterns []string) bool {
return false
}
// Chromium Manifest::Location values we treat as trusted-origin.
// Chromium Manifest::Location values we act on: kInvalidLocation — which is also
// the Go zero value, so it covers a Preferences entry with no "location" key —
// and the two we treat as trusted-origin.
const (
chromiumLocUnknown = 0
chromiumLocInternal = 1
chromiumLocComponent = 5
)
@@ -29,14 +32,23 @@ const (
// chromiumSideloaded reports whether a Chromium extension was installed outside
// the Web Store (unpacked/dev, external, or policy-forced). Conservative: when
// both signals are unknown it returns false to avoid false positives.
//
// A trusted location is checked first and wins over from_webstore. The browser
// installs its own first-party components (Edge Copilot Bridge, for instance),
// so by definition they are never web-store-installed and always report
// from_webstore:false — checking that signal first would make the trusted-origin
// exemption unreachable and flag every built-in component as sideloaded.
func chromiumSideloaded(fromWebstore, location int) bool {
if location == chromiumLocInternal || location == chromiumLocComponent {
return false
}
if fromWebstore == 0 { // explicitly not from the web store
return true
}
if location != 0 && location != chromiumLocInternal && location != chromiumLocComponent {
return true
}
return false
// The trusted locations already returned above, so any location we can read
// at this point is one an ordinary install does not land in; only an
// unreadable location is left alone.
return location != chromiumLocUnknown
}
// geckoSideloaded reports whether a Gecko addon is unsigned/temporary or was