Eapolsniper's Blog
01000010 01100101 00100000 01000101 01111000 01100011 01100101 01101100 01101100 01100101 01101110 01110100 00100000 01010100 01101111 00100000 01000101 01100001 01100011 01101000 00100000 01001111 01110100 01101000 01100101 01110010 00000000 00000000 00000000 00000000

Introducing EndpointBOM

Today I’m excited to announce the release of EndpointBOM, a new open-source tool designed to generate Software Bill of Materials (SBOM) files specifically for developer workstations. This tool helps security teams and developers identify installed packages and plugins across endpoints, making it easier to detect malicious packages or vulnerable dependencies.

What is EndpointBOM and why did I create it?

This year has been non-stop news articles regarding 3rd party dependency compromises, malicious developer extensions, and malicious MCP servers. As a Product Security Engineer at a global high security SaaS company, I’ve been finding it exhausting to research every time something new makes the news. While we have active defenses, seeing companies continuously get compromised and put in the news definitely raises the concern of how we can not only have our active defenses, but have automated detection if those prevention steps fail or have a gap. If you get a headache when you hear Shai-Hulud, postmark-mcp, GlassWorm, or ShadyPanda, then you may be my target audience.

I went hunting for solutions to the problem of knowing what 3rd party packages, applications, browser extensions, and IDE plugins are installed on developer endpoints. This was surprisingly difficult for me to find tooling that did this reliably and in a manner where a team can easily monitor, conduct historical investigations, and receive automated threat alerts before we’re reading about it in the news. The best I could really do was Crowdstrike, and it’s a lot of effort to use Crowdstrike in this manner at scale across hundreds or thousands of endpoints without manually programming in threats and indicators of compromise.

This explains why I created something new. I wanted something similar to Syft, but for developer endpoints, and I wanted the output to be not only consumable in an industry standard format, but formatted in a way that provides as much value as possible. I also didn’t want any part of this process to cost money, with the hopes of making attacker’s lives more difficult now that I’m on the defense side more than the offense :evil:.

So what is EndpointBOM in a TLDR? It collects system applications, installed 3rd party dependencies from a large number of package ecosystems, IDE plugins, MCP servers installed in IDEs, and browser extensions (if you enable the feature). This not only catches what’s installed globally on systems, which is what other tools were doing, but it gathers from individual projects and virtual environments such as Python’s VENV. It does not report on dependency files such as package.json that haven’t been installed, it only looks at active risk, not perceived risk.

For added value, I found several package managers including NPM and brew keep very good logs on the system of what’s been installed and uninstalled. I have my tool gather and parse these logs. The tool is intended to be run on intervals such as daily, and by parsing these logs, we not only get a “what was installed at this exact moment the tool ran” but we also receive every specific package and version installed between the last run of EndpointBOM and now. The tool bundles these logfiles into a zip with the CycloneDX files, in case there is an incident they provide valuable targeting information for how the package got installed, (main VS transitive, was the package installed with a pinned version (3.3.1) or through a rule such as ^3.3.0).

NPM logs, especially, get deleted at irregular intervals, so capturing them is important. This can be configured on systems and I would recommend preserving for 30 days in corporate environments. On my system they actually seem to clear daily, so running EndpointBOM near the end of the day would be my recommendation if you want to have daily scans. For higher security, running mid-day around 1PM and end of day around 10PM local time would be more likely to capture everything without configuring NPM logging on every system.

Some other fun features are the tool gathers internal IPs, hostname, logged in user, and public IP if enabled (requires external service interaction so disabled by default). All of these get packaged into CycloneDX format that has been specifically designed to build and preserve transitive states of packages and functional dependency trees.

While these can be imported into any tool that supports CycloneDX, I specifically designed it to connect to OWASP’s Dependency-Track, which is a free UI for SBOM analysis. While the UI doesn’t easily view every custom field I included, it’s easy enough to work with and definitely a bargain at the price of “free OSS”.

By enabling the OSV.dev database in Dependency-Track, you get automatic scanning for malicious packages, IDE plugins, and MCP servers. You can easily set up alerting for malware to go to various systems Slack, Teams, Jira, or Email.

While each user’s individual use cases will vary, I took a stab at building out recommendations for Jamf configurations as an example, but basically just put the executable(s) on the system and run it, and then send the files to wherever you want to work with them with a script.

For Dependency-Track, since I have custom fields, I’ve included a python script you can use for easy testing, and a buildable golang executable which will store your Dependency-Track URL and API key a little more securely than if it’s in a clear text file. This executable will automatically upload the SBOMS to Dependency-Track and sort them by hostname and version for you, making this a turnkey installation for you.

The overall flow would be:

  1. Get the executables on the system somehow (Jamf, AD, etc)
  2. Create a script that attaches to a cronjob/task scheduler to run daily
  3. Have the script run endpointbom with any flags you’d like (or use a config file)
  4. Run whatever file upload script you want to get files back to you, such as the load-to-dependency-track

While not mine, you may be wondering what is Dependency-Track? It’s a fantastic web based application created by OWASP! Watch the demo to see what you need to know about it regarding this tool, but for some additional clarity, it’s two docker containers that run. The database runs on one container as well as the API, and the UI runs on another container.

For file uploads, your endpoints need to be able to access the API on the DB server.

Important Notes

  • Browser extension scans are turned off by default because in some cases, you need to give the executable full disk permissions or it will cause a popup to the user the first time the command is run and they must accept it and put in their password, if they’re admin.
  • I’ve tested the Mac client pretty extensively but not the Windows or Linux clients yet, so test these before you deploy to production. Though you should test everything before deploying to production, since this is still very new software.
  • Grabbing the public ip is disabled by default because it calls to external services on the internet not owned by me, but commonly used to find your public IP. This may not be what everyone wants, but it makes it a lot easier to know the host’s IP in a remote environment if an alert goes off.

Video Walkthrough

Key Features

Supported Package Managers

EndpointBOM currently supports scanning for packages installed via:

  • JavaScript/TypeScript: npm, yarn, pnpm (with transitive dependency support)
  • Python: pip (with dependency listing)
  • Ruby: gem
  • Rust: cargo
  • PHP: composer
  • Go: Go modules (with transitive dependencies)
  • macOS: Homebrew (formulae and casks)
  • Windows: Chocolatey
  • VS Code: Extensions and plugins

Smart Scanning Behavior

The tool intelligently adapts based on privileges:

  • With Admin/Root: Automatically scans all user profiles for complete endpoint inventory
  • Without Admin: Scans only the current user with a clear warning message

In most environments, there is only one user on a system, so admin permissions are not really required. You may get a few additional packages. If you’re running through MDM such as Jamf, this won’t matter as it’s going to run as admin anyway.

Getting Started

Installation

The easiest way to get started is to download the latest release from the GitHub releases page. Pre-built binaries are available for:

  • macOS (Intel and Apple Silicon)
  • Windows (x64)
  • Linux (x64)

Basic Usage

For the most complete scan, run with admin/root privileges:

# macOS/Linux
sudo ./endpointbom

# Windows (run as Administrator)
endpointbom.exe

The tool will automatically create a scans/ directory next to the executable and save the SBOM files there. This keeps your scan results organized and prevents them from being accidentally committed to version control.

Use Cases

EndpointBOM is useful for several scenarios:

  1. Security Audits: Generate SBOMs for vulnerability scanning and compliance reporting
  2. Supply Chain Security: Identify potentially malicious packages or compromised dependencies
  3. Incident Response: Quickly inventory installed software during security incidents
  4. Compliance: Meet requirements for software inventory and dependency tracking