Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions bin/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ Globs:
- /root/{snap/brave/*/,}.config/BraveSoftware/Brave-Browser
- /home/*/.config/microsoft-edge*/
- /root/.config/microsoft-edge*/
- /home/*/.config/vivaldi*/
- /root/.config/vivaldi*/
WindowsChromeProfiles:
- C:\Users\*\AppData\{Roaming,Local}\*\*\User Data
- C:\Windows\{System32,SysWOW64}\config\systemprofile\AppData\{Roaming,Local}\*\*\User Data
Expand Down
36 changes: 30 additions & 6 deletions definitions/ChromiumBrowser_Extensions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,21 @@ Name: Chromium Browser Extensions
Description: |
Parses all installed chromium extensions.

Manifest V3 extensions list the sites they can read or change in
`host_permissions` rather than `permissions`, so both are reported.
`ContentScriptMatches` lists the sites where the extension injects
its own scripts.

Author: Mike Cohen
Categories:
- Chrome
- Browser

FilenameRegex: "manifest.json"
Globs:
- "{{LinuxChromeProfiles}}/*/Extensions/**/manifest.json"
- "{{WindowsChromeProfiles}}/*/Extensions/**/manifest.json"
- "{{MacOSChromeProfiles}}/*/Extensions/**/manifest.json"
- "{{LinuxChromeProfiles}}/*/Extensions/*/*/manifest.json"
- "{{WindowsChromeProfiles}}/*/Extensions/*/*/manifest.json"
- "{{MacOSChromeProfiles}}/*/Extensions/*/*/manifest.json"

Sources:
- Preamble: |
Expand All @@ -24,20 +29,39 @@ Sources:
LET ManifestData = SELECT OSPath, parse_json(data=read_file(filename=OSPath)) AS Manifest
FROM Rows

-- Message names are case insensitive so lower case the keys to
-- match ResolveName()
LET LowerKeys(Item) = to_dict(item={
SELECT lowcase(string=_key) AS _key, _value FROM items(item=Item)
})

-- Find the Locale file to help with.
LET LocaleData = SELECT *, if(condition=Manifest.default_locale, else=dict(),
then=parse_json(data=read_file(
filename=OSPath.Dirname + "_locales" + Manifest.default_locale + "messages.json"))) AS Locale
then=LowerKeys(Item=parse_json(data=read_file(
filename=OSPath.Dirname + "_locales" + Manifest.default_locale + "messages.json")))) AS Locale
FROM ManifestData

LET GetIcon(Manifest) = Manifest.icons.`128` || Manifest.icons.`64` || Manifest.icons.`32` || Manifest.icons.`16`

-- Flatten the matches of all content scripts into one list of unique sites.
LET ContentScriptMatches(Manifest) = SELECT * FROM foreach(
row=Manifest.content_scripts,
query={ SELECT _value FROM foreach(row=matches) })
GROUP BY _value

VQL: |
SELECT OSPath, Manifest.author.email AS Email,
SELECT OSPath,
-- Manifests are stored in Extensions/<ID>/<Version>/
OSPath.Components[-3] AS ID,
OSPath.Components[-2] AS Version,
Manifest.author.email AS Email,
ResolveName(Message = Manifest.name, Locale=Locale) AS name,
ResolveName(Message = Manifest.description, Locale=Locale) AS description,
Manifest.manifest_version AS ManifestVersion,
Manifest.oauth2.scopes as Scopes,
Manifest.permissions as Permissions,
Manifest.host_permissions AS HostPermissions,
ContentScriptMatches(Manifest=Manifest)._value AS ContentScriptMatches,
Manifest.key as Key, if(condition=GetIcon(Manifest=Manifest),
then=upload(file=OSPath.Dirname + GetIcon(Manifest=Manifest))) AS Image,
Manifest AS _Manifest
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"appName": {
"message": "Example V3 Extension"
},
"appDesc": {
"message": "A Manifest V3 test extension"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"manifest_version": 3,
"name": "__MSG_appName__",
"description": "__MSG_appDesc__",
"default_locale": "en",
"version": "1.2.0",
"author": "Example Author",
"permissions": ["storage", "tabs", "scripting"],
"host_permissions": ["<all_urls>"],
"background": {
"service_worker": "background.js"
},
"content_scripts": [
{
"matches": ["https://*.example.com/*", "https://mail.example.net/*"],
"js": ["content.js"]
},
{
"matches": ["https://*.example.com/*", "https://bank.example.org/*"],
"js": ["bank.js"]
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"manifest_version": 2,
"name": "Example V2 Extension",
"description": "A Manifest V2 test extension",
"version": "2.1",
"permissions": ["storage", "https://www.example.com/*"],
"background": {
"scripts": ["background.js"],
"persistent": false
}
}
11 changes: 11 additions & 0 deletions testing/testcases/chrome_extensions.in.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Queries:
# One Manifest V3 extension with a default locale and one Manifest
# V2 extension.
- |
SELECT ID, Version, name, description, ManifestVersion,
Permissions, HostPermissions, ContentScriptMatches
FROM Artifact.Generic.Forensic.SQLiteHunter(
MatchFilename=TRUE, All=FALSE, Chrome=TRUE,
CustomGlob=testFiles + '/Chrome/Extensions/*/*/manifest.json')
WHERE _Source =~ "Chromium Browser Extensions"
ORDER BY ID
46 changes: 46 additions & 0 deletions testing/testcases/chrome_extensions.out.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# One Manifest V3 extension with a default locale and one Manifest
# V2 extension.
Query: SELECT ID, Version, name, description, ManifestVersion,
Permissions, HostPermissions, ContentScriptMatches
FROM Artifact.Generic.Forensic.SQLiteHunter(
MatchFilename=TRUE, All=FALSE, Chrome=TRUE,
CustomGlob=testFiles + '/Chrome/Extensions/*/*/manifest.json')
WHERE _Source =~ "Chromium Browser Extensions"
ORDER BY ID

Output: [
{
"ID": "aaaabbbbccccddddeeeeffffgggghhhh",
"Version": "1.2.0_0",
"name": "Example V3 Extension",
"description": "A Manifest V3 test extension",
"ManifestVersion": 3,
"Permissions": [
"storage",
"tabs",
"scripting"
],
"HostPermissions": [
"\u003call_urls\u003e"
],
"ContentScriptMatches": [
"https://*.example.com/*",
"https://mail.example.net/*",
"https://bank.example.org/*"
]
},
{
"ID": "iiiijjjjkkkkllllmmmmnnnnoooopppp",
"Version": "2.1_0",
"name": "Example V2 Extension",
"description": "A Manifest V2 test extension",
"ManifestVersion": 2,
"Permissions": [
"storage",
"https://www.example.com/*"
],
"HostPermissions": null,
"ContentScriptMatches": []
}
]

Loading