From c86e66826cd1e543c66f2b978d87323efd6cbee1 Mon Sep 17 00:00:00 2001 From: "Bruno R. Morillo" <111511828+brmorillo@users.noreply.github.com> Date: Wed, 17 Jun 2026 17:18:21 -0300 Subject: [PATCH 1/4] improve: enrich package.json metadata for npm discoverability - description: replace generic text with a concise feature summary - exports: add conditional exports map (require/import/types) so bundlers resolve CJS vs ESM automatically without guessing - module: add "module" field pointing to ESM build for legacy bundlers - keywords: expand from 4 to 18 terms covering the actual modules (crypto, jwt, uuid, sorting, queue, cache, http, logging, storage, esm, commonjs) Co-Authored-By: Claude Sonnet 4.6 --- package.json | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index ad3d845..9895379 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,17 @@ { "name": "@brmorillo/utils", "version": "14.0.1", - "description": "Utility library for JavaScript/TypeScript projects", + "description": "Production-ready utility library for JS/TS — 27 modules behind one type-safe API: arrays, objects, strings, crypto, JWT, UUID, sorting, queues, caches, HTTP, logging, storage and more.", "main": "dist/index.js", + "module": "dist/index.mjs", "types": "dist/index.d.ts", + "exports": { + ".": { + "require": "./dist/index.js", + "import": "./dist/index.mjs", + "types": "./dist/index.d.ts" + } + }, "files": [ "dist/**/*", "README.md", @@ -44,7 +52,21 @@ "utils", "utilities", "helpers", - "typescript" + "typescript", + "javascript", + "nodejs", + "type-safe", + "cryptography", + "jwt", + "uuid", + "sorting", + "queue", + "cache", + "http", + "logging", + "storage", + "esm", + "commonjs" ], "author": "Bruno Morillo", "license": "LGPL-3.0-only", From 876f3c6fe00321a64af0f6d212dff708b8f01e77 Mon Sep 17 00:00:00 2001 From: "Bruno R. Morillo" <111511828+brmorillo@users.noreply.github.com> Date: Wed, 17 Jun 2026 17:26:34 -0300 Subject: [PATCH 2/4] ci: bump Node.js target from 20 to 24 in release workflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Node 20 is deprecated on GitHub Actions runners (forced to 24 since 2025-09-19). Change the explicit node-version in setup-node to 24 so the npm publish step runs on the correct declared version. Note: remaining warnings from actions/checkout@v4, actions/setup-node@v4, and softprops/action-gh-release@v2 are internal to those actions (their action.yml still says `runs.using: node20`); those require upstream updates by the action maintainers — the runner already forces Node 24 for them. Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6d0305a..37c7182 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -50,7 +50,7 @@ jobs: if: steps.tag.outputs.exists == 'false' uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 24 registry-url: 'https://registry.npmjs.org' - name: Install dependencies From f071274e0573048198834a93a169fb610e543be4 Mon Sep 17 00:00:00 2001 From: "Bruno R. Morillo" <111511828+brmorillo@users.noreply.github.com> Date: Wed, 17 Jun 2026 17:29:07 -0300 Subject: [PATCH 3/4] docs(security): add SECURITY.md with vulnerability reporting and security invariants - Supported-versions table (14.x active, 13.x critical-only until 2026-12-31) - Private reporting via GitHub Security Advisories + e-mail fallback - Response timeline: 48h ack, 5-day triage, 14-day patch for critical/high - Documents all security invariants enforced in CI: AES-256-GCM, ChaCha20-Poly1305, RSA-OAEP, JWT algorithm allowlist, path confinement, prototype-pollution protection, bcrypt for passwords - Dependency policy: exact pins, 3-month lag, CJS check, Gitleaks scan - Scope: in-scope vs out-of-scope for reports Co-Authored-By: Claude Sonnet 4.6 --- SECURITY.md | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..5ba99ff --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,103 @@ +# Security Policy + +## Supported versions + +Only the **current major** release line receives security fixes. + +| Version | Status | +| ------- | ------------------- | +| 14.x | ✅ Actively supported | +| 13.x | ⚠️ Critical fixes only (until 2026-12-31) | +| < 13 | ❌ Not supported | + +Upgrade to the latest `14.x` release to receive all patches. + +## Reporting a vulnerability + +**Do not open a public GitHub issue for security reports.** + +Report vulnerabilities privately via **GitHub Security Advisories**: + +1. Go to the [Security tab](https://github.com/brmorillo/utils/security/advisories) of this repository. +2. Click **"New draft security advisory"**. +3. Fill in the description, affected versions, and steps to reproduce. +4. Submit — the maintainer will be notified privately. + +Alternatively, send an e-mail to **bruno@rmorillo.com** with: +- Subject: `[SECURITY] @brmorillo/utils — ` +- Affected version(s) and runtime environment. +- A concise description and steps to reproduce. +- (Optional) a suggested fix or patch. + +### Response timeline + +| Event | Target | +| ----- | ------ | +| Acknowledgement | within **48 hours** | +| Initial triage & severity rating | within **5 business days** | +| Patch or workaround | within **14 days** for critical/high; **30 days** for medium/low | +| Public disclosure | after the patch is published (coordinated with reporter) | + +We follow [responsible disclosure](https://en.wikipedia.org/wiki/Responsible_disclosure). Credit will be given in the release notes unless you prefer to remain anonymous. + +## Security defaults — what the library guarantees + +These invariants are tested in CI and must not regress: + +### Cryptography (`CryptUtils`) + +- Symmetric encryption uses **AES-256-GCM** or **ChaCha20-Poly1305** — both authenticated; the `authTag` is verified on decryption, so tampering throws. +- RSA uses **OAEP with SHA-256** padding. PKCS#1 v1.5 is not provided. +- ECC default curve is **prime256v1** (P-256). +- **RC4 is intentionally absent** and must never be added. +- AES-CBC is not provided; do not simplify back to it. + +### Hashing (`HashUtils`) + +- Password hashing uses **bcrypt** (minimum cost 10). +- General-purpose digests are **SHA-256** and **SHA-512**. + +### JWT (`JWTUtils`) + +- `verify` enforces an `algorithms` allowlist (default `['HS256']`); the `none` algorithm is always rejected. +- `generate` defaults to `expiresIn: '1h'` and pins `HS256`. +- `decode` does **not** verify the signature — treat its output as untrusted. + +### Storage (`LocalStorageProvider`) + +- All file paths are confined to the configured `basePath`. Paths containing `../` or any other traversal sequence are rejected with a `StorageError`. + +### Object utilities (`ObjectUtils`) + +- `deepMerge` and `unflattenObject` silently drop keys that would modify `__proto__`, `constructor`, or `prototype` (prototype-pollution protection). + +### Error handling + +- `BaseError.toJSON()` omits the `stack` trace by default (opt in with `{ includeStack: true }`) — safe to forward in HTTP responses. +- All library errors extend `BaseError`; the library never throws a bare `Error`. + +### Retry (`RetryUtils`) + +- Backoff is capped at `maxDelay` (default 30 s) with optional jitter to prevent thundering-herd. + +## Dependency policy + +- All runtime and dev dependencies are pinned to **exact versions** (no `^` or `~`) for reproducible installs. +- Dependencies are updated **once a month**, intentionally staying **at least 3 months behind** the latest release to allow time for the community to detect supply-chain attacks or malicious publishes. +- Before adopting a new runtime dependency major, it is verified to ship a **CommonJS build** (required for dual CJS+ESM output). +- CI runs [Gitleaks](https://github.com/gitleaks/gitleaks) on every PR and push to `main` to detect accidentally committed secrets. + +## Scope + +In-scope for security reports: + +- Vulnerabilities in the library code itself (`src/`). +- Weaknesses in the cryptographic or JWT defaults described above. +- Path traversal or prototype-pollution bypasses. +- Supply-chain issues in pinned dependencies. + +Out of scope: + +- Vulnerabilities in example code (`examples/`) — these are illustrative only. +- Issues requiring physical access to the developer's machine. +- Denial-of-service against the npm registry or GitHub Actions infrastructure. From 227a192ee00d8eabff1587790473b7b8eb24cce9 Mon Sep 17 00:00:00 2001 From: "Bruno R. Morillo" <111511828+brmorillo@users.noreply.github.com> Date: Wed, 17 Jun 2026 17:30:52 -0300 Subject: [PATCH 4/4] =?UTF-8?q?docs(security):=20simplify=20supported=20ve?= =?UTF-8?q?rsions=20=E2=80=94=2014.x=20only?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the 13.x critical-fixes exception; only 14.x receives support. All older versions are unsupported. Co-Authored-By: Claude Sonnet 4.6 --- SECURITY.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/SECURITY.md b/SECURITY.md index 5ba99ff..267158c 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -7,8 +7,7 @@ Only the **current major** release line receives security fixes. | Version | Status | | ------- | ------------------- | | 14.x | ✅ Actively supported | -| 13.x | ⚠️ Critical fixes only (until 2026-12-31) | -| < 13 | ❌ Not supported | +| < 14 | ❌ Not supported | Upgrade to the latest `14.x` release to receive all patches.