The security signal log tailing can't see: tracking npm cooldown removals with Elastic Agent
This article describes a defensive monitoring technique for tracking npm package cooldown settings (min-release-age) on developer workstations using Elastic Agent's CEL (Common Expression Language) integration. The key challenge is that traditional log-tailing inputs cannot detect when a security-relevant config setting is removed from a file, as they only emit events on append. A snapshot-based CEL integration that re-reads .npmrc files on a 6-hour heartbeat solves this by comparing current state against prior snapshots and flagging absent cooldown keys. The approach includes agent-side filtering to prevent npm registry auth tokens from transiting the network.
Detection / Hunteropenrouter
What Happened
When hackers compromise a software package on npm (the main package manager for JavaScript), they often publish a malicious version and hope people install it quickly before anyone notices. npm added a setting called min-release-age that tells the package manager to ignore any version published less than a certain number of days ago, giving defenders time to detect and remove malicious packages. However, this setting lives in a small config file on each developer's computer, and if someone deletes it, traditional monitoring tools won't notice because they only watch for new lines being added to files, not lines being removed. This article explains how Elastic built a monitoring tool that takes periodic snapshots of these config files and alerts when the protective setting disappears. The approach also carefully filters out sensitive authentication tokens so they never leave the developer's computer. Organizations using npm should consider enabling min-release-age on all developer workstations and monitoring for its removal.
Key Takeaways
- npm's min-release-age setting (available since npm 11.10) excludes freshly published package versions from npm install, blunting supply-chain attacks at the developer workstation level where CI/CD guardrails don't reach
- Log-tailing inputs (filestream) cannot detect removal of config settings because they only emit on append; a snapshot-based CEL integration that re-reads the whole file on a heartbeat is needed to catch cooldown line removals
- Agent-side JavaScript script processors must filter .npmrc contents before transit to prevent registry auth tokens from leaving the workstation
- nvm (Node Version Manager) inflates npm version counts because each Node.js version ships its own npm binary; only npm 11.10+ enforces min-release-age, so version counts overstate actual protection coverage
- Small config files under 1024 bytes require native file identity (inode-based) rather than fingerprint-based identity in Filebeat, or they are silently held back from ingestion
Affected Systems
- Developer workstations running macOS, Linux, or Windows
- npm 11.10+ (required for min-release-age enforcement)
- Node.js environments using nvm (Node Version Manager)
- Systems with Elastic Agent deployed for endpoint telemetry
Vulnerabilities (CVEs)
None identified.
Attack Chain
- Supply Chain Risk: Attacker publishes a compromised npm package version targeting developer workstations outside CI/CD guardrails
- Defense Deployment: Organization enforces min-release-age=7 in .npmrc via Jamf or equivalent MDM, blocking installation of packages published within 7 days
- Defense Bypass Attempt: Someone removes the min-release-age setting from .npmrc on a developer workstation, either intentionally or accidentally
- Detection: CEL snapshot integration detects the cooldown key absence on the next 6-hour heartbeat, marking cooldown.absent=true
- Remediation: Jamf re-applies the setting within 24 hours; security team investigates hosts with repeated removals
Detection Availability
- YARA Rules: No
- Sigma Rules: No
- Snort/Suricata Rules: No
- KQL Queries: No
- Splunk SPL Queries: No
- EQL Queries: No
- Other Detection Logic: Yes
- Platforms: Elastic Agent CEL integration, Elasticsearch ingest pipeline, Filebeat JavaScript script processor
The article provides a complete ~40-line CEL script for Elastic Agent that snapshots .npmrc files on a 6-hour heartbeat, a JavaScript agent-side script processor to filter auth tokens before transit, and an Elasticsearch ingest pipeline (grok + set + convert + remove processors) to parse and index cooldown state. These are Elastic-specific configurations available in the article body.
Detection Engineering Assessment
| Dimension | Rating | Rationale |
|---|---|---|
| EDR Visibility | Medium | The article relies on Elastic Agent's CEL integration for filesystem access rather than traditional EDR process telemetry. EDR products may detect npm config modification commands but would not inherently track .npmrc content state changes without custom configuration. The approach requires a dedicated collection integration beyond standard EDR capabilities. |
| Network Visibility | None | This technique is entirely host-based config file monitoring. No network indicators are involved. The article explicitly filters sensitive data before it transits the network. |
| Detection Difficulty | Moderate | The article provides complete, copy-pasteable configurations for the CEL integration, script processor, and ingest pipeline. However, deployment requires Elastic Agent and Fleet infrastructure, custom integration setup, and coordination with MDM for enforcement. The technique is well-documented but requires platform-specific knowledge and multi-component configuration. |
Required Log Sources
- Elastic Agent CEL integration output (filesystem snapshots)
- Elasticsearch ingest pipeline logs
- Filebeat agent logs (for filestream debugging)
- MDM/UEM enforcement logs (e.g., Jamf) for config re-application tracking
Hunting Hypotheses
| Hypothesis | Telemetry | ATT&CK Stage | FP Risk |
|---|---|---|---|
| Consider hunting for developer workstations where npm config files exist but lack the min-release-age setting, indicating the cooldown protection is not enforced | Filesystem snapshot data from config file monitoring or EDR file integrity monitoring | Supply Chain Protection | Medium - hosts that never had the setting enforced would appear as non-compliant; correlate with MDM enforcement logs to distinguish never-enrolled from removed |
| Consider hunting for repeated removal of the min-release-age setting on the same host, which may indicate intentional bypass of supply chain protections | Time-series config file snapshots showing cooldown.absent=true events for the same host across multiple heartbeat intervals | Supply Chain Protection | Low - repeated removals after MDM re-application are unlikely to be accidental |
| Consider hunting for npm install commands executed on hosts where the min-release-age cooldown setting is absent, as these hosts are unprotected against freshly published compromised packages | Process execution logs (EDR) correlated with config file state snapshots | Execution | Medium - legitimate npm install activity on unprotected hosts is common; the risk is the exposure window, not the activity itself |
| Consider hunting for modifications to .npmrc files that remove specific security-relevant lines, as this pattern may indicate an attempt to weaken supply chain defenses | File integrity monitoring or config file snapshot diffs showing line removals | Defense Evasion | Medium - developers may legitimately modify .npmrc for registry configuration changes |
Control Gaps
- Traditional log-tailing/filestream inputs cannot detect config setting removals, only appends
- CI/CD pipeline supply chain guardrails do not extend to developer workstations
- npm version counts inflated by nvm overstate actual min-release-age enforcement coverage since only npm 11.10+ supports the setting
- Filebeat fingerprint file identity silently withholds files under 1024 bytes from ingestion
- Ingest pipeline filtering of auth tokens occurs too late - tokens would already have transited the network
Key Behavioral Indicators
- cooldown.absent=true events in Elasticsearch indicating min-release-age was removed from a host's .npmrc
- Host dropping out of periodic snapshot results entirely, indicating .npmrc file deletion
- Multiple cooldown.absent=true events for the same host across heartbeat intervals, indicating repeated removals
- npm config delete min-release-age command execution visible in process telemetry
- Presence of npm versions older than 11.10 on hosts with min-release-age configured, indicating incomplete enforcement
False Positive Assessment
Medium - The cooldown.absent=true signal will fire for any host where min-release-age is missing, including hosts that were never enrolled in enforcement, hosts where a developer legitimately modified .npmrc for other reasons and the setting was collateral damage, and new hosts before MDM applies the setting. Correlation with MDM enrollment status and enforcement logs is needed to distinguish intentional removals from configuration gaps.
Recommendations
Immediate Mitigation
- Verify against your organization's incident response runbook and team escalation paths before acting. Consider evaluating whether your developer workstations have npm's min-release-age setting enforced, and if not, consider deploying it via your MDM or configuration management tool
- If you use Elastic Agent, consider deploying the CEL snapshot integration described in the article to monitor .npmrc files for cooldown setting removal
- Consider auditing which npm versions are installed across your fleet, paying attention to nvm environments where multiple npm versions coexist, to identify hosts running versions older than 11.10 that cannot enforce min-release-age
Infrastructure Hardening
- Consider enforcing min-release-age=7 (or a value appropriate to your risk tolerance) in both user-level and system-global .npmrc files via MDM or configuration management, with daily re-application to self-heal removals
- If deploying the CEL integration, ensure the agent-side JavaScript script processor is configured to filter out all non-min-release-age lines before events leave the host, preventing auth token exposure
- Consider extending the snapshot monitoring approach to other package managers your developers use (pip, uv, pnpm, yarn, bun), checking cooldowns.dev for each manager's equivalent flag and its unit
- Evaluate whether your file integrity monitoring or config file monitoring tools use snapshot semantics rather than append-only tailing, as tail-based approaches cannot detect setting removals
User Protection
- Consider educating developers on the purpose of min-release-age and why they should not remove it from their .npmrc files
- If your organization uses nvm, consider documenting that only npm 11.10+ enforces min-release-age, and evaluate whether older Node.js versions in nvm environments need upgrading or additional controls
- Consider providing developers with a documented process for legitimate npm configuration changes that preserves the min-release-age setting
Security Awareness
- Consider incorporating supply chain attack awareness into existing developer security training, emphasizing that freshly published package versions carry higher risk
- Consider adding guidance on the min-release-age cooldown setting to internal developer documentation and onboarding materials
- If your organization runs security awareness programs, consider including a module on why developer workstations are a distinct attack surface from CI/CD pipelines and what protections apply to each
MITRE ATT&CK Mapping
Initial Access
Additional IOCs
- Command Lines:
- Purpose: Set the npm cooldown configuration to 7 days on a user's .npmrc | Tools:
npm| Stage: Configuration enforcement |npm config set min-release-age 7 - Purpose: Delete the npm cooldown setting, which removes .npmrc entirely if it is the only setting | Tools:
npm| Stage: Configuration removal (attack signal) |npm config delete min-release-age
- Purpose: Set the npm cooldown configuration to 7 days on a user's .npmrc | Tools: