Skip to content

Releases: akasecurity/oUpdate

v0.2.12

Choose a tag to compare

@alsoknownaswill alsoknownaswill released this 31 Oct 06:05
v0.2.12
43baf1e

Maintenance release. Upgrade from any earlier version.

Targets

  • A review leg now checks that its reviewers can answer before it starts. If a reviewer cannot be reached, the leg is held and says why, instead of failing; the review runs on the next run once the reviewer is up.

v0.2.11

Choose a tag to compare

@alsoknownaswill alsoknownaswill released this 30 Oct 10:31
v0.2.11
b458002

Maintenance release. Upgrade from any earlier version.

Review

  • A hold caused by the reviewer now states the reason it gave, so the hold text says why the release was stopped.
  • Control, bidirectional and zero-width characters are removed from that reason before it is printed.

Evaluation

  • Added a limit eval with sourced post-cutoff cases, repeat runs and a detection rate with its interval, plus an npm transitive-dependency measurement.

v0.2.10

Choose a tag to compare

@alsoknownaswill alsoknownaswill released this 29 Oct 17:07
v0.2.10
f1dc09b

Maintenance release. Upgrade from any earlier version.

Supply chain

  • After a Homebrew Type A upgrade, oUpdate checks that the installed version equals the version that was reviewed.
  • poetry.lock and requirements.txt sha256 hashes are checked against PyPI's listing for each locked file.

Security

  • Reviewer request headers and forge tokens are only sent over https, or over http to a loopback host.

v0.2.9

Choose a tag to compare

@alsoknownaswill alsoknownaswill released this 29 Oct 15:55
v0.2.9
947ee3b

Maintenance release. Upgrade from any earlier version.

Review

  • Every review in a run starts in one private directory that is emptied before and after each review, so an agent CLI sees the same working directory each time and nothing one review writes reaches the next.

Code

  • applyHost is split into step modules, the keg and owner-waiter import cycle is gone, and the two-reviewer rule lives in one shared module. Behavior is unchanged.
  • 40 more scenario tests now run with real assertions.

v0.2.8

Choose a tag to compare

@alsoknownaswill alsoknownaswill released this 29 Oct 04:23
v0.2.8
572f7e3

Security release. Upgrade from 0.2.7 or earlier.

Review

  • A dependency whose lower bound falls (for example ^4.0.0 to ^1.7.3) now counts as an install-time change, because npm installs a different package and runs its install scripts. The check follows the spec npm installs for each name: optionalDependencies, else dependencies, else peerDependencies, with npm: aliases resolved, every || alternative read, and a version it cannot read held.
  • A changed or added npm-shrinkwrap.json is part of the install-time surface.
  • A version Bun cannot order is treated as unread instead of stopping the review.

Eval

  • New eval function-color-postinstall-hidden-download: four attack pull requests (install and update of function-color and function-flag) and five look-alikes and controls. oUpdate 0.2.8 blocks 4 of 4 attacks and passes 5 of 5 look-alikes and controls. The README explains how scoring works.

v0.2.7

Choose a tag to compare

@alsoknownaswill alsoknownaswill released this 29 Oct 03:14
v0.2.7
1aad79c

Security release. Upgrade from 0.2.6 or earlier.

Review

  • One rule decides an install-time hold: the release holds when the install-time surface changed against the previous version. README, docs and CI workflow files are never part of that surface.
  • An install hook entry is read for what it can load. A hook that runs a file in any language (shell, Python, Ruby, Perl and others) is followed to the files it names; a path built at run time is bounded by its literal prefix and holds the files in that directory, a path with no usable prefix holds the package without its docs, and a fully computed load holds every file.
  • Shell hooks: a variable that names a path is trusted only when its whole value is a plain word. eval, ./source, cd/pushd/popd, printf -v and array-element writes widen the file to every file, quoted or not.
  • Python hooks: import_module, run_module and run_path calls, aliased or bare, are followed like __import__; a stdlib import closes its shadow files; an import after a colon and a literal dynamic import are read.
  • An install statement from the allow-list counts as static only when its arguments are literal too.
  • Update targets load through a plugin registry, so a target can keep its own older names outside the public tree.
  • The public export leaves out paths listed in .publish-exclude, and the oss-scan host-name list is read from a private file.

Holds in this release

  • Packages whose install hook runs a fully computed load are held for a human read; their changed hook entries are shown whole.

oUpdate 0.2.6

Choose a tag to compare

@alsoknownaswill alsoknownaswill released this 28 Oct 15:49
v0.2.6

Security release. Upgrade from 0.2.5 or earlier.

Review

  • Package entries resolve the way Node resolves them: main, bin, exports and imports conditions, directory indexes, extensionless and .js specifiers, and bare names that load a bundled node_modules copy in the same artifact.
  • An unchanged file that the new release newly loads is shown in full. Imports are parsed with Bun's transpiler, so comments, regexes, templates, string concatenation, re-exports, require.resolve and Worker URLs do not hide a load, and the walk follows newly reached files until it meets what the old release already loaded. A file the parser rejects holds.
  • A package.json change that only retargets an entry at an existing, unchanged file is reviewed: the file it now points at is shown.
  • Install hooks: a new install hook holds and is shown. Hook text is read after $npm_package_* substitution and through every npm run, run-script, run-s and run-p script it names; node -e, --eval, -p and sh -c / bash -c bodies are read again, and --require, -r and --import paths are files the hook runs.
  • A source map named by a concatenated literal path is shown whole.
  • Artifact placement is indexed once per map, so large merged diffs review faster.

oUpdate 0.2.5

Choose a tag to compare

@alsoknownaswill alsoknownaswill released this 28 Oct 14:01
v0.2.5

Security release. Upgrade from 0.2.4 or earlier.

Review

  • oupdate image reads layer contents: it builds each image's merged filesystem from its layers and verified blobs, diffs the two images into ranked reviewer parts, and holds anything it cannot read. Removals of startup, maintainer and trust files hold, links are resolved by one resolver, and --no-layers skips the layer read.
  • Files that package code loads are shown: a binary is judged by its magic bytes, not its name, and a loaded ttf or text-signature binary is shown.
  • pnpm v9 snapshots are diffed per installed instance, and whitespace-only changes in long lines are marked.
  • bun.lock private non-.tgz tarball URLs count as URL dependencies, and a Gitea file list that does not match x-total-count fails closed.
  • Reviewer blocks refuse unknown keys.

Gate

  • Gate comment details render as code spans, so paths cannot mention or autolink.

Host

  • Homebrew bun is held while the host run is executing it.
  • Upstream bumps to pinned host tools are reported, and versioned GitHub asset names are rewritten.

Release

  • Release tags are signed. Public CI is pinned to the Bun the suite passes on.

oUpdate 0.2.4

Choose a tag to compare

@alsoknownaswill alsoknownaswill released this 28 Oct 11:53
v0.2.4

Security release. Upgrade from 0.2.3 or earlier; it tightens what the review and the gate accept.

Review

  • A release lands only on a pass from the pre-pass or the reviewer; a cooldown or advisory alone no longer lands it, and a skipped reviewer layer alone no longer lands a release.
  • A package the pre-pass stops is held without going to the model.
  • A reviewer answer that lacks the expected response headers is rejected (expectHeaders). A 503 or refused connection from the reviewer route is retried with short backoff under one deadline per base.
  • A file/symlink type change counts as changed. Plain source maps and declaration files are shown as a hash so a clean release is not held over budget; a map any non-map file names is shown.
  • Lockfile entries with no source or hash are held as unhashed in npm and pnpm alike; names and versions outside the registry grammar are rejected and escaped when shown.
  • Registry script bodies are fenced in the npm lane prompt.

Gate

  • A pending status is posted when no change was actually reviewed.
  • Layer details and lockfile parse errors are escaped in the gate comment.

Other

  • SECURITY.md with private reporting.
  • CI typechecks and tests on pull requests and main.

oUpdate 0.2.3

Choose a tag to compare

@alsoknownaswill alsoknownaswill released this 27 Oct 21:05
v0.2.3

Security release. Upgrade from 0.2.2 or earlier. It fixes the issues in advisory GHSA-mhr6-9xx9-84fp, where an update could be approved or land without its code being reviewed.

Review

  • Symlinks and hardlinks in an artifact are read. A link to a startup hook, or one that points outside the package, stops the release, and a link's target is shown to the reviewer.
  • Files are no longer skipped because their name looks like prose. A changed file of any extension reaches the reviewer. Files that package.json loads or runs (main, exports, bin, install scripts) are never treated as inert, and an unchanged file that newly becomes an entry is shown whole.
  • A NUL byte no longer hides a code file. A changed binary holds for a person, unless its bytes really are the image or font its name says.
  • Diffs compare lines exactly, so a whitespace-only change is shown. A large reorder is shown in full.
  • A release with nothing to review holds; oUpdate never records an approval on 0 parts.
  • PyPI: every wheel and the sdist of both releases are reviewed, each checked against the sha256 PyPI lists.
  • npm globals: the reviewed version is the one installed and verified. A package with an install hook holds for a person, since the file the hook runs is not read.
  • The reviewer client treats a truncated answer as a failure. It never sends the API key over plain http to another host, and never follows a redirect.
  • Archives are checked for size and file count before unpacking.

Gate (oupdate gate)

  • What the gate cannot see fails the PR: a deleted lockfile, any changed file the gate did not read, and manifest changes beyond dependency versions. A manifest's dependency change has to match its lockfile.
  • A git, URL or file dependency fails, as does a lockfile whose download URL is not the registry's own tarball or PyPI file for that version. A same-version source or hash swap also fails.
  • npm, pnpm and bun lockfile integrities are checked for every hash algorithm they record.
  • Breaking:
    • only PRs from a bot author on a same-repo branch are gated: pass --gate-login on GitHub Actions and --bot-login for a self-hosted bot.
    • a private-registry version now fails by default (--private-registry hold|list|review).
    • a prior status is trusted only with the gate's own comment for that commit.

Other

  • Gatekeeper checks parse codesign and spctl output by whole lines and need a real Team ID.
  • A keg restart needs an exact launchd label, and the process must belong to that keg.
  • ${NAME} in the host and targets config is now read from the environment, as documented (#9). An unset variable stops the run with its name.