# Files field restricts published contents

- **Pattern:** `ab-002361` (`sdk-package-quality.package-config.files-field`)
- **Severity:** high
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-002361
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-002361)

## Why it matters

Without a `files` allowlist or `.npmignore`, running `npm publish` sends your entire repository — test fixtures, CI configs, editor settings, source TypeScript, internal tooling, and potentially `.env.example` files — to every consumer who installs your package. ISO 25010 confidentiality is directly impacted: internal implementation details that weren't meant to be public are now permanently embedded in a versioned npm release. SLSA L2 requires artifact provenance; publishing unpredicted files breaks that guarantee. Bloated packages also slow installs for all downstream users.

## Severity rationale

High because the absence of a `files` allowlist exposes internal source code, test fixtures, and configuration files to all npm consumers permanently, with no way to remove them from published versions.

## Remediation

Add a `files` allowlist to `package.json` restricting publication to only built output and essential metadata.

```json
{
  "files": [
    "dist",
    "README.md",
    "LICENSE"
  ]
}
```

Verify what gets published before releasing: `npm pack --dry-run` prints every file that would be included. Anything outside `dist/`, `README.md`, and `LICENSE` should raise a question. The `files` allowlist is safer than `.npmignore` — new directories are excluded by default rather than accidentally included.

## Detection

- **ID:** `files-field`
- **Severity:** `high`
- **What to look for:** Enumerate all files that would be published by npm pack. For each, classify whether it should be included (dist, types) or excluded (tests, fixtures, source). check `package.json` for the `files` array, which controls what gets included when the package is published to npm. Without it, everything not in `.npmignore` or `.gitignore` gets published — including test files, source code, config files, and documentation that consumers don't need. Look for:
  1. `files` array in `package.json`
  2. OR `.npmignore` file with appropriate exclusions
  3. Whether the `files` array actually covers the build output (`dist/`, `lib/`, etc.)
  4. Whether `README.md` and `LICENSE` are included (they're always included by default)
- **Pass criteria:** The `files` field is present in `package.json` and restricts published contents to build output, type declarations, and essential metadata. OR a well-configured `.npmignore` excludes source code, tests, and development files — at least 1 files array entry must be configured to prevent publishing test fixtures and source files. Report: "X files in package, Y explicitly included via files field."
- **Fail criteria:** No `files` field and no `.npmignore`. The entire repo (minus `.gitignore` patterns) will be published, including test files, CI config, editor config, and source code.
- **Skip (N/A) when:** Python package (uses `pyproject.toml` `[tool.setuptools.packages]` or `MANIFEST.in`), Rust crate (uses `Cargo.toml` `include`/`exclude`), Go module (no publish artifact — source is the distribution). For these ecosystems, check the equivalent mechanism.
- **Cross-reference:** The `minimal-deps` check verifies that published dependencies are also minimal.
- **Detail on fail:** `"No files field in package.json and no .npmignore. Running 'npm pack --dry-run' would include src/, tests/, .github/, tsconfig.json, and other development files. This bloats install size and exposes internal code."`
- **Remediation:** The `files` field is an allowlist — only listed paths get published. This is safer than `.npmignore` (a denylist) because new files are excluded by default.

  ```json
  // package.json:
  {
    "files": [
      "dist",
      "README.md",
      "LICENSE"
    ]
  }
  ```

  Verify what gets published before releasing: `npm pack --dry-run` shows exactly what files would be included. Aim for the smallest possible publish footprint.

---

## External references

- iso-25010 security.confidentiality
- ssdf PS.3.2
- slsa L2

Taxons: supply-chain, code-quality

HTML version: https://auditbuffet.com/patterns/ab-002361
