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
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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: is this change necessary? there's an unfortunate inconsistency here now

newSimplePackageTaskFactory(nix.NewStoreCataloger, pkgcataloging.DeprecatedTag),
}
}
40 changes: 40 additions & 0 deletions syft/pkg/cataloger/binary/capabilities.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,46 @@ catalogers:
cpes:
- cpe:2.3:a:google:chrome:*:*:*:*:*:*:*:*
type: BinaryPkg
- method: glob
criteria:
- '**/Electron Framework'
packages:
- class: electron-binary-macos
name: electron
purl: pkg:generic/electron
cpes:
- cpe:2.3:a:electronjs:electron:*:*:*:*:*:*:*:*
type: BinaryPkg
- method: glob
criteria:
- '**/electron'
packages:
- class: electron-binary
name: electron
purl: pkg:generic/electron
cpes:
- cpe:2.3:a:electronjs:electron:*:*:*:*:*:*:*:*
type: BinaryPkg
- method: glob
criteria:
- '**/code'
packages:
- class: electron-binary-renamed-linux
name: electron
purl: pkg:generic/electron
cpes:
- cpe:2.3:a:electronjs:electron:*:*:*:*:*:*:*:*
type: BinaryPkg
- method: glob
criteria:
- '**/Code.exe'
packages:
- class: electron-binary-renamed-windows
name: electron
purl: pkg:generic/electron
cpes:
- cpe:2.3:a:electronjs:electron:*:*:*:*:*:*:*:*
type: BinaryPkg
- method: glob
criteria:
- '**/ffmpeg'
Expand Down
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 @@ -1917,6 +1917,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 @@ -913,6 +913,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",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are electron apps frequently named electron/Electron Framework? is this because people don't change the defaults? I wonder if this would be better served with a specialized cataloger that checks all executables in the electron cataloger package, below. This might also cover VS code if it scanned all binaries

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",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should probably be called something like visual-studio-code-binary and + -windows for the windows version. These could be merged together with the glob: **/{code,Code.exe}, I think and just be called visual-studio-code-binary

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.
83 changes: 83 additions & 0 deletions syft/pkg/cataloger/electron/capabilities.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# 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
- asar
- directory
- electron
- image
- javascript
- language
- package
parsers: # AUTO-GENERATED structure
- function: parsePackageJSON
detector: # AUTO-GENERATED
method: glob # AUTO-GENERATED
criteria: # AUTO-GENERATED
- '**/Contents/Resources/app/node_modules/*/package.json'
- '**/Contents/Resources/app/node_modules/*/*/package.json'
- '**/Contents/Resources/app/node_modules/*/*/*/package.json'
- '**/resources/app/node_modules/*/package.json'
- '**/resources/app/node_modules/*/*/package.json'
- '**/resources/app/node_modules/*/*/*/package.json'
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
- 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
purl_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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these paths would be covered by the package json cataloger, which is not enabled by default for directory scans (I think there is a desire to identify "full OS" scans and use the same catalogers as images, so that could change at some point). But if the package json cataloger is enabled, does this result in duplicate results and we're just deduplicating later?

"**/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