Skip to content
Open
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
added electron cataloger & classifier
Signed-off-by: Rez Moss <hi@rezmoss.com>
  • Loading branch information
rezmoss committed Mar 19, 2026
commit c6bb6a82378b4af0149a351ef09efdff7805e35b
5 changes: 4 additions & 1 deletion internal/task/package_tasks.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/anchore/syft/syft/pkg/cataloger/dart"
"github.com/anchore/syft/syft/pkg/cataloger/debian"
"github.com/anchore/syft/syft/pkg/cataloger/dotnet"
"github.com/anchore/syft/syft/pkg/cataloger/electron"
"github.com/anchore/syft/syft/pkg/cataloger/elixir"
"github.com/anchore/syft/syft/pkg/cataloger/erlang"
"github.com/anchore/syft/syft/pkg/cataloger/gentoo"
Expand Down Expand Up @@ -180,12 +181,14 @@ func DefaultPackageTaskFactories() Factories {
newSimplePackageTaskFactory(conda.NewCondaMetaCataloger, pkgcataloging.DirectoryTag, pkgcataloging.InstalledTag, pkgcataloging.PackageTag, "conda"),
newSimplePackageTaskFactory(snap.NewCataloger, pkgcataloging.DirectoryTag, pkgcataloging.InstalledTag, pkgcataloging.ImageTag, "snap"),
newSimplePackageTaskFactory(ai.NewGGUFCataloger, pkgcataloging.DirectoryTag, pkgcataloging.ImageTag, "ai", "model", "gguf", "ml"),
newSimplePackageTaskFactory(electron.NewCataloger, pkgcataloging.DirectoryTag, pkgcataloging.ImageTag, pkgcataloging.LanguageTag, "electron", JavaScript, "asar"),

// deprecated catalogers ////////////////////////////////////////
// these are catalogers that should not be selectable other than specific inclusion via name or "deprecated" tag (to remain backwards compatible)
newSimplePackageTaskFactory(dotnet.NewDotnetDepsCataloger, pkgcataloging.DeprecatedTag), //nolint:staticcheck // TODO: remove in syft v2.0
newSimplePackageTaskFactory(dotnet.NewDotnetPortableExecutableCataloger, pkgcataloging.DeprecatedTag), //nolint:staticcheck // TODO: remove in syft v2.0
newSimplePackageTaskFactory(php.NewPeclCataloger, pkgcataloging.DeprecatedTag), //nolint:staticcheck // TODO: remove in syft v2.0
newSimplePackageTaskFactory(nix.NewStoreCataloger, pkgcataloging.DeprecatedTag), //nolint:staticcheck // TODO: remove in syft v2.0
//nolint:staticcheck // TODO: remove in syft v2.0
newSimplePackageTaskFactory(nix.NewStoreCataloger, pkgcataloging.DeprecatedTag),
}
}
22 changes: 22 additions & 0 deletions syft/pkg/cataloger/binary/classifier_cataloger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1392,6 +1392,28 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
Metadata: metadata("chrome-binary"),
},
},
{
logicalFixture: "electron/28.0.0/linux-amd64",
expected: pkg.Package{
Name: "electron",
Version: "28.0.0",
Type: "binary",
PURL: "pkg:generic/electron@28.0.0",
Locations: locations("electron"),
Metadata: metadata("electron-binary"),
},
},
{
logicalFixture: "electron-framework/28.0.0/darwin-arm64",
expected: pkg.Package{
Name: "electron",
Version: "28.0.0",
Type: "binary",
PURL: "pkg:generic/electron@28.0.0",
Locations: locations("Electron Framework"),
Metadata: metadata("electron-binary-macos"),
},
},
{
logicalFixture: "ffmpeg/7.1.1/darwin-arm64",
expected: pkg.Package{
Expand Down
46 changes: 46 additions & 0 deletions syft/pkg/cataloger/binary/classifiers.go
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,52 @@ func DefaultClassifiers() []binutils.Classifier {
PURL: mustPURL("pkg:generic/chrome@version"),
CPEs: singleCPE("cpe:2.3:a:google:chrome:*:*:*:*:*:*:*:*"),
},
{
Class: "electron-binary-macos",
FileGlob: "**/Electron Framework",
EvidenceMatcher: m.FileContentsVersionMatcher(
// Electron/28.0.0 pattern found in Electron framework binaries
`Electron/(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
Package: "electron",
PURL: mustPURL("pkg:generic/electron@version"),
CPEs: singleCPE("cpe:2.3:a:electronjs:electron:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "electron-binary",
FileGlob: "**/electron",
EvidenceMatcher: binutils.MatchAll(
// Match both Electron and Chrome version patterns to confirm it's Electron
m.FileContentsVersionMatcher(`Electron/(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
m.FileContentsVersionMatcher(`Chrome/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+`),
),
Package: "electron",
PURL: mustPURL("pkg:generic/electron@version"),
CPEs: singleCPE("cpe:2.3:a:electronjs:electron:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
// VS Code and other Electron apps on Linux that rename the binary to "code"
Class: "electron-binary-renamed-linux",
FileGlob: "**/code",
EvidenceMatcher: binutils.MatchAll(
m.FileContentsVersionMatcher(`Electron/(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
m.FileContentsVersionMatcher(`Chrome/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+`),
),
Package: "electron",
PURL: mustPURL("pkg:generic/electron@version"),
CPEs: singleCPE("cpe:2.3:a:electronjs:electron:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
// VS Code and other Electron apps on Windows (Code.exe)
Class: "electron-binary-renamed-windows",
FileGlob: "**/Code.exe",
EvidenceMatcher: binutils.MatchAll(
m.FileContentsVersionMatcher(`Electron/(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
m.FileContentsVersionMatcher(`Chrome/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+`),
),
Package: "electron",
PURL: mustPURL("pkg:generic/electron@version"),
CPEs: singleCPE("cpe:2.3:a:electronjs:electron:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "ffmpeg-binary",
FileGlob: "**/ffmpeg",
Expand Down
Binary file not shown.
Binary file not shown.
52 changes: 52 additions & 0 deletions syft/pkg/cataloger/electron/capabilities.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Cataloger capabilities. See ../README.md for documentation.

catalogers:
- ecosystem: javascript # MANUAL
name: electron-cataloger # AUTO-GENERATED
type: generic # AUTO-GENERATED
source: # AUTO-GENERATED
file: syft/pkg/cataloger/electron/cataloger.go
function: NewCataloger
selectors: # AUTO-GENERATED
- directory
- image
- javascript
- electron
- asar
- language
parsers: # AUTO-GENERATED structure
- function: parseAsarArchive
detector: # AUTO-GENERATED
method: glob # AUTO-GENERATED
criteria: # AUTO-GENERATED
- '**/app.asar'
- '**/Contents/Resources/app.asar'
- '**/Contents/Resources/electron.asar'
- '**/Contents/Resources/app/node_modules.asar'
- '**/resources/app.asar'
- '**/resources/electron.asar'
- '**/resources/app/node_modules.asar'
metadata_types: # AUTO-GENERATED
- pkg.NpmPackage
package_types: # AUTO-GENERATED
- npm
json_schema_types: # AUTO-GENERATED
- JavascriptNpmPackage
capabilities: # MANUAL - preserved across regeneration
- name: license
default: true
- name: dependency.depth
default:
- direct
- indirect
- name: dependency.edges
default: ""
- name: dependency.kinds
default:
- runtime
- name: package_manager.files.listing
default: false
- name: package_manager.files.digests
default: false
- name: package_manager.package_integrity_hash
default: false
30 changes: 30 additions & 0 deletions syft/pkg/cataloger/electron/cataloger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package electron

import (
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/pkg/cataloger/generic"
)

const catalogerName = "electron-cataloger"

// NewCataloger returns a cataloger for packaged Electron apps.
func NewCataloger() pkg.Cataloger {
return generic.NewCataloger(catalogerName).
WithParserByGlobs(parseAsarArchive,
"**/app.asar",
"**/Contents/Resources/app.asar", // macOS
"**/Contents/Resources/electron.asar", // macOS alt
"**/Contents/Resources/app/node_modules.asar", // macOS VS Code style
"**/resources/app.asar", // Linux/Win
"**/resources/electron.asar", // Linux/Win alt
"**/resources/app/node_modules.asar", // Linux/Win VS Code style
).
WithParserByGlobs(parsePackageJSON,
"**/Contents/Resources/app/node_modules/*/package.json", // macOS
"**/Contents/Resources/app/node_modules/*/*/package.json", // macOS scoped
"**/Contents/Resources/app/node_modules/*/*/*/package.json", // macOS nested
"**/resources/app/node_modules/*/package.json", // Linux/Win
"**/resources/app/node_modules/*/*/package.json", // Linux/Win scoped
"**/resources/app/node_modules/*/*/*/package.json", // Linux/Win nested
)
}
Loading
Loading