fix: improve extract parsing with proper decoding and error handling (#543)

* fix: implement proper Chromium localStorage LevelDB parsing
* feat: add IsMeta field to StorageEntry and keep META entries
* fix: add error logging for decryption and missing data fields
* fix: address PR review for localStorage parsing
* fix: use naïve instead of café in Latin-1 test to avoid typos false positive
* fix: extension enabled detection and sessionStorage decoding
* fix: session storage origin resolution and extension enabled detection
* fix: address PR review comments for storage parsing
This commit is contained in:
Roger authored and GitHub committed 2026-04-04 18:52:54 +08:00
1 parent a58d432688
commit 068b82178f
10 files changed
+497 -57

No files matched your search

+12 -1
View File
@@ -60,7 +60,7 @@ func extractExtensionsWithKeys(path string, keys []string) ([]types.ExtensionEnt
Description: manifest.Get("description").String(),
Version: manifest.Get("version").String(),
HomepageURL: manifest.Get("homepage_url").String(),
Enabled: ext.Get("state").Int() == 1,
Enabled: isExtensionEnabled(ext),
})
return true
})
@@ -68,6 +68,17 @@ func extractExtensionsWithKeys(path string, keys []string) ([]types.ExtensionEnt
return extensions, nil
}
// isExtensionEnabled checks whether an extension is enabled.
// Modern Chrome uses disable_reasons (array): empty [] = enabled, non-empty [1] = disabled.
// Older Chrome uses state (int): 1 = enabled.
func isExtensionEnabled(ext gjson.Result) bool {
reasons := ext.Get("disable_reasons")
if reasons.Exists() {
return reasons.IsArray() && len(reasons.Array()) == 0
}
return ext.Get("state").Int() == 1
}
// extractOperaExtensions extracts extensions from Opera's Secure Preferences,
// which stores extension data under "extensions.opsettings" instead of the
// standard "extensions.settings".