Only the latest major version of @brazilian-utils/brazilian-utils receives security updates.
| Version | Supported |
|---|---|
| 2.x | ✅ |
| < 2.0 | ❌ |
If you are on an unsupported version, please upgrade to the latest 2.x release before reporting
an issue, as it may already be fixed.
Please do not report security vulnerabilities through public GitHub issues, discussions, or pull requests.
The preferred way to report a vulnerability is through GitHub's private reporting feature:
- Go to the Security tab of this repository.
- Click "Report a vulnerability".
- Fill in as much detail as you can (see below).
This creates a private conversation with maintainers and lets us coordinate a fix and disclosure without exposing the issue publicly before a patch is available.
If you are unable to use GitHub's private reporting for any reason, you can email support@brazilian-utils.com.br instead.
To help us triage and fix the issue quickly, please include:
- A description of the vulnerability and its potential impact.
- Steps to reproduce it (a minimal code sample using
@brazilian-utils/brazilian-utilsis ideal). - The affected version(s).
- Any suggested fix or mitigation, if you have one.
This policy covers the @brazilian-utils/brazilian-utils npm package and the source code in this
repository, including:
- Any code path that could lead to unexpected/unsafe behavior when using the library's exported utilities (e.g. ReDoS in a validator/formatter, prototype pollution, unsafe use of dynamic code).
- Build/release tooling in this repository (
scripts/, CI workflows) if it could compromise the integrity of the published package.
Out of scope: vulnerabilities in third-party dependencies of your project, or issues that only
affect the documentation site (docs/) content itself rather than the published package (still
report doc-content issues, but via a regular issue).
This library ships with zero runtime dependencies, which limits the supply-chain attack surface, but does not eliminate the need for review. Still report anything you find.
This project is maintained by volunteers in their spare time, so these are targets, not a contract; they are what we aim for on every report, and we will tell you when we cannot meet one.
| Step | Target |
|---|---|
| Acknowledgement of your report | within 7 days |
| Assessment (confirmed or not, severity, what we plan to do) | within 14 days |
| Fix or mitigation published | within 90 days of confirming the report |
Confirmed issues that are critical (for example, a vulnerability that any consumer hits with the default usage of a utility) are worked on before anything else and are released as soon as a fix is ready, without waiting for other changes. If a fix needs more than 90 days, we agree a new date with you instead of letting the report go quiet.
If you get no acknowledgement within 14 days, the report probably got lost: send it again through the other channel above (e-mail if you used GitHub, or the other way around).
We follow coordinated disclosure: please keep the report private until a fix is available, and we keep you informed along the way.
- A confirmed vulnerability is fixed on
mainand released in the latest2.xversion through the regular release flow. - On release, we publish a GitHub Security Advisory
for the repository, which assigns a CVE through GitHub's CNA, so it reaches Dependabot,
npm audit, OSV and the other scanners consumers already use. - The advisory and the release notes describe the affected versions, the fixed version and any workaround, and credit you as the reporter unless you prefer to remain anonymous.
Vulnerabilities reported publicly by mistake are handled the same way, just without the embargo.
Every version is published from the release workflow in this repository with npm provenance (Sigstore), and no maintainer publishes from a personal machine. To check that the copy you installed is the one the workflow built:
npm audit signaturesIt verifies the registry signature and the provenance attestation of every installed package.
The attestation, with the commit and the workflow run that built the version, is also shown on the
"Provenance" panel of the version on npmjs.com.
A CycloneDX SBOM of each version ships inside the package as brazilian-utils.cdx.json (so it
sits in node_modules/@brazilian-utils/brazilian-utils/ after install) and is also kept as the
sbom-<tag> artifact of its release run under
Actions → Release.
- No credential lives in the repository, in the package or in the documentation site. Publishing to npm uses Trusted Publishing (OIDC), so there is no npm token to store or rotate.
- The only secrets the project holds are the Codecov upload token and the Stryker dashboard key,
kept as GitHub Actions encrypted secrets, readable by the workflows alone and only by the jobs
that need them. Maintainers with the
Adminrole are the only people who can set or replace them; nobody can read them back. - A secret is rotated when a maintainer leaves, when a workflow that used it is removed, when the provider announces an exposure and whenever a leak is suspected, in that case before anything else is investigated.
- Nothing in the project reads a
.envfile, and.gitignoreexcludes them. GitHub's push protection rejects known credential formats at push time and TruffleHog scans the commits of every pull request and the whole history weekly; a finding is treated as a leak, so the credential is rotated first and the history is rewritten only afterwards, if ever.
- The published package has zero runtime dependencies, and a pull request that adds one is not merged (see CONTRIBUTING.md).
- No development dependency with a known vulnerability of high or critical severity may be merged
or released:
audit-ci --highand OSV-Scanner run on every pull request and block it, and the weekly Security run catches advisories published in between. Lower severities are fixed in the next regular Dependabot update, and before the next release when a fixed version exists. - An advisory is allow-listed only when it cannot reach the published package or the release
pipeline (a development-only dependency in a code path the toolchain never exercises), and the
allow list in
.github/workflows/check.ymlnames each advisory by ID so the exception is reviewable; it is removed as soon as a fixed version is available. - Every such exception is also recorded as a
not_affectedstatement, with its justification and impact, inopenvex.json, the project's OpenVEX document, so consumers' scanners can be told why the advisory does not apply;npm run check:vexruns on every pull request and fails when the VEX document and the suppression lists disagree. - Static analysis has no accepted threshold of open findings: every ESLint, TypeScript, knip, jscpd,
actionlint and zizmor finding blocks the merge, and the OpenSSF Scorecard findings uploaded to
the Security tab are worked in the next change to the affected file. The only suppressions are the
documented Stryker equivalent-mutant comment and the
audit-ciallow list above.
The library is a set of pure functions with no runtime dependencies, so the surface is small; this is what it consists of and what protects each part.
Assets: the integrity of the package consumers install; the correctness of the validators (a wrong "valid" lets bad data into a consumer's system); the availability of the consumer's process (a utility must not hang or blow up on adversarial input); and the CEP or address a consumer sends to a third-party API through the two lookup utilities.
Actors and entry points: end users of consumer applications, whose strings reach the utilities
as arguments; the CEP API providers, whose HTTP responses reach getAddressInfoByCep and
getCepInfoByAddress; contributors, through pull requests from forks; maintainers, with write
access and release approval; and the automation (GitHub Actions, Dependabot, release-please, the
npm registry).
| Threat | Mitigation |
|---|---|
| Adversarial input makes a utility throw, hang or read a polluted prototype | Every utility has property-based tests that feed it arbitrary values, prototype-chain keys as state codes included, and assert it never throws; the suites are mutation-tested; there is no eval, new Function or dynamic code, and lookups read own properties only. |
| A malicious or vulnerable dependency reaches consumers | Zero runtime dependencies; development dependencies are pinned by the lockfile and checked by audit-ci, OSV-Scanner and Dependabot under the policy above. |
| A fork's pull request runs code with access to secrets or write tokens | Workflows use pull_request only, a read-only GITHUB_TOKEN, persist-credentials: false and no secrets for fork builds; GitHub requires a maintainer's approval before running workflows for outside contributors. |
| The build or release pipeline is tampered with to publish a modified package | Every action is pinned to a commit SHA and linted by actionlint and zizmor; jobs run with the least permissions; the package is staged on npm through OIDC Trusted Publishing with provenance and becomes installable only after a maintainer approves it with 2FA; releases are immutable and ship an SBOM. |
| A maintainer account is compromised | Two-factor authentication on the GitHub organization and on npm, no long-lived tokens, single-purpose secrets rotated under the policy above, and a release that still needs the staged-version approval. |
| A CEP API returns malformed or hostile data, or is unavailable | Responses are validated before use and treated as untrusted; only the CEP or address being looked up is sent, over HTTPS; retries are bounded and the utilities return null instead of throwing. |
| A dataset or check-digit rule goes stale and a validator gives a wrong answer | Datasets are regenerated from their official sources by the Update datasets workflow through reviewable pull requests, every rule cites its official source in a @see tag, and the tests pin official examples. |
Vulnerability reports that reveal a threat missing from this table are welcome; the table is updated with the fix.