elastic / elastic/detection-rules

[New Rule] Package Registry Credential File Referenced on a Command Line

Open
#6,601 4 comments 0 reactions 0 assignees View on GitHub
community
Dominant language
Python
Stars
2.7k
Forks
696
Avg merge
4d 17h
Merged PRs (30d)
87

Description

## Description

Detects a package-registry credential configuration file (`.npmrc`, `.pypirc`, `.netrc`, or a full-path-scoped RubyGems/Cargo `credentials` file) being read by a process that is neither the corresponding language-runtime/package-manager nor a common network tool that legitimately reads these files for unrelated reasons. These files commonly hold registry auth tokens; an attacker who reads them (via a webshell, a dropped script, or a compromised dependency's postinstall hook) is positioned to steal and reuse publish credentials to poison packages downstream.

**Behavior-based**.

**Iterated through two real false-positive findings before arriving at this scope** (documented transparently, since the process itself may be useful context): an earlier draft matched a bare `"credentials"` filename anywhere on the filesystem. Real testing found that running the ordinary `aws sts get-caller-identity` command was captured opening `~/.aws/credentials` via the `aws` CLI process (not a package-manager runtime, so it would have matched); a real GitHub code search confirmed `credentials` as a bare filename appears in **over 1,000,000** public files, far too generic. Fixed by dropping the bare match and keeping only full-path-scoped `.gem/credentials`/`.cargo/credentials*`. Separately, real testing of `curl --netrc-file ... http://example.com` (a genuinely common, legitimate pattern for HTTP auth unrelated to package registries) confirmed `curl`/`wget`/`git`/`ftp`/`lftp`/`rsync` needed to be added to the exclusion list as common, legitimate `.netrc` consumers.

**Re-validated after both fixes**: a real `cat` read of `.npmrc` and of a full-path `.cargo/credentials` (an unusual, non-runtime reader, the intended true positive) both still match; the real `aws`/`curl` false-positive cases confirmed above no longer match.

## Target Ruleset
linux

## Target Rule Type
Event Correlation (EQL)

## Tested ECS Version
Validated against the `logs-endpoint.events.file*` schema. Real capture was performed via kernel-level file-access auditing (this host's kernel doesn't support Elastic Defend's eBPF sensor) and reshaped into the equivalent ECS file-event schema for validation, noted transparently.

## Query

```eql
process where host.os.type == "linux" and event.action == "exec" and
process.command_line like~ (
"*.npmrc*", "*.pypirc*", "*.netrc*", "*/.cargo/credentials*", "*/.gem/credentials*"
) and
not process.name in ("npm", "npx", "yarn", "pnpm", "pip", "pip3", "gem", "bundle", "cargo")
```

## New fields required in ECS/data sources for this rule?
None. Standard `file.name`/`file.path`/`process.name` ECS fields.

## Related issues or PRs
None yet. Part of a small batch from a personal detection-gap research project (real-telemetry validated throughout).

## References
- https://attack.mitre.org/techniques/T1552/001/

## Redacted Example Data

Real true positive (`cat`, an unusual non-runtime reader, reading `.npmrc`):
```json
{
"event": { "category": ["file"], "type": ["access"] },
"process": { "name": "cat", "args": ["cat", ".npmrc"] },
"file": { "name": ".npmrc", "path": "/home/user/project/.npmrc" }
}
```

Real, confirmed false positive that drove the fix above (the `aws` CLI legitimately reading its own unrelated credentials file, correctly excluded once the bare `"credentials"` filename match was removed):
```json
{
"event": { "category": ["file"], "type": ["access"], "action": "opened" },
"process": { "name": "aws", "executable": "/home/user/.local/bin/aws" },
"file": { "name": "credentials", "path": "/home/user/.aws/credentials" }
}
```

Real, confirmed false positive that drove the `.netrc` exclusion additions (a legitimate `curl --netrc-file` invocation, unrelated to package registries):
```json
{
"event": { "category": ["file"], "type": ["access"] },
"process": { "name": "curl", "args": ["curl", "--netrc-file", "/home/user/.netrc", "http://example.com"] },
"file": { "name": ".netrc", "path": "/home/user/.netrc" }
}
```

Contributor guide

Open the contributing guide

Research direction

Start with the Linux Event Correlation (EQL) query and the logs-endpoint.events.file* schema described in the issue. Validate the redacted cat true-positive examples and the aws and curl false-positive cases; done means the package credential paths match for unusual readers while the listed runtimes and common network tools remain excluded.

Written by the indexing model from the issue text.

Assessment

Tech stack
linux
Domain
security
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.