Do not open a public GitHub issue for security vulnerabilities.
Report privately via either:
- GitHub Security Advisory (preferred): https://github.com/Refactron-ai/refactron/security/advisories/new
- Email:
omsherikar0229@gmail.com
You will receive an acknowledgement within 72 hours. For high or critical issues we coordinate disclosure with you and aim to ship a patched release before any public details are published. Please allow a reasonable embargo window.
When reporting, include a description, reproduction steps, the affected version, and the impact you believe it has. A reproduction we can run is worth more than a careful description of one.
| Version | Status |
|---|---|
0.4.x |
Supported. Security fixes ship here. |
0.3.x |
End of life. Contains known false-SAFE defects fixed in 0.4.x. |
≤ 0.2.x |
End of life. Contains GHSA-q3vj-5qq5-m84g. |
Refactron is pre-1.0 and ships behaviour changes in patch releases. Security fixes are not backported below the current minor; upgrade instead.
A verification layer. A diff goes in; SAFE, UNSAFE or UNPROVEN comes out,
backed by the repository's own test suite run in an isolated shadow tree with
changed-statement coverage fused in.
It ships two binaries from one npm package: refactron (CLI) and refactron-mcp
(a stdio MCP server). The PyPI distribution is a shim that locates and executes
the npm binary; it contains no engine code of its own.
The refactoring product — analyze, run, document, rollback, preflight,
init, the AST transforms and the atomic batch writer — was removed in 0.4.0.
Refactron no longer writes code. Anything below describing a write path to your
files describes something that does not exist.
Refactron's inputs are hostile by design. The diff under verification is authored by an AI agent, a contributor, or a codemod, and the test suite it runs belongs to the repository being verified. Both are treated as untrusted.
- Your working tree. Refactron never writes to it. Changes are applied to a copy under the system temp directory, the gates run there, and the copy is removed. There is no code path from a verdict to your files.
- Shadow-tree containment. A change whose path resolves outside the shadow
tree is refused. Containment is resolved with
realpath, not string comparison, and repository symlinks whose target escapes the repository are not mirrored into the tree. - Diff intake. A path taken from a diff's
---/+++headers is refused before it is read if it resolves outside the repository. - Your credentials. The test suite Refactron runs does not inherit them.
REFACTRON_TOKEN, CI tokens, cloud keys, and any variable whose name ends in_TOKEN,_SECRET,_API_KEY,_PASSWORDor_CREDENTIALSare removed from the environment handed to every spawn that executes the suite. - Verdict integrity. A false
SAFEis the only unforgivable defect in this product. Every degradation path — a missing sidecar, an unmeasurable coverage run, a test command we cannot parse, a flaky heal — resolves toUNPROVEN, never toSAFE.
Stated plainly, because a guarantee with an unstated hole is worse than no guarantee.
- We do not sandbox your test suite. Running
refactron verify-diffruns the repository's tests. That is no more and no less safe than runningnpm testorpyteston the same repository yourself. A test that writes to an absolute path, opens a socket, or spawns a process will do so. Isolation means the shadow tree is a genuine copy, not that the suite is confined to it. - We do not sandbox the Python sidecars. They parse source with the standard library and LibCST; they do not execute it.
- The MCP server applies no authentication. For a stdio transport the trust boundary is the process spawn: whoever starts the server can already run arbitrary commands as you. It makes no network calls and reaches no remote service. Do not expose it over a network transport without adding authentication first.
- A
SAFEverdict is not a proof of correctness. It means your suite ran the changed code and stayed green. It inherits exactly what your tests check. - Narrowing detection is a strong check, not a guarantee. Refactron reads the
test command and the environment and knows the common flags of
pytest,unittest,vitestandjest. A command using a flag it does not recognise reportsunknown, which does not cap the verdict. Narrowing configured inpytest.ini, a vitestinclude, or a jesttestMatchis not seen.
- npm releases are published from GitHub Actions with an OIDC trusted publisher
and
--provenance. Verify withnpm audit signatures. - PyPI releases use a trusted publisher. That attestation covers the shim,
not the engine: the shim executes whichever
refactronbinary is first on yourPATH. If you pin the PyPI package, pin the npm package to the same version. - Releases are gated on
npm audit --audit-level=high. - Remediation is lockfile-only where possible; a declared range is not widened to clear an advisory.
Node.js 18+ is required. Python 3.8+ is required for coverage-backed
verdicts and for the syntax, imports and statement-mapping sidecars. Without
Python, verdicts degrade to UNPROVEN rather than failing open.
| Advisory | Affected | Fixed | Summary |
|---|---|---|---|
| GHSA-q3vj-5qq5-m84g | >= 0.2.0, < 0.4.2 |
0.4.2 |
The shadow tree hardlinked unchanged files, so a verified test suite could write through into the caller's repository while the verdict reported SAFE. |
None outstanding. npm audit --audit-level=high reports zero vulnerabilities as
of 0.4.2.