Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ history, authorship, licenses, and dependency notices.

## Current release

[Web Console 1.6.178](https://github.com/PastureStack/web-console/releases/tag/1.6.178)
is packaged in [Server v1.6.516](https://github.com/PastureStack/server/releases/tag/v1.6.516).
It fixes inactive-environment view/edit loading: globally authorized project and
member data remains available, while inapplicable network/policy-manager reads
are skipped and explained in all thirteen packaged locales. It does not bypass
active-environment permissions or enable network writes in inactive environments.
[Web Console 1.6.179](https://github.com/PastureStack/web-console/releases/tag/1.6.179)
packages the reviewed Moment 2.31.0 and compatible dependency updates already
merged on `main`, plus the official shell-quote 1.11.0 security fix in both npm
and the browser bundle. Its archive is published independently of Server assembly.
The prior [Server v1.6.516](https://github.com/PastureStack/server/releases/tag/v1.6.516)
packages Web Console 1.6.178.

For component identities, checksums, focused tests, and known verification limits,
see the [current release note](docs/releases/web-console-1.6.178.md).
see the [current release note](docs/releases/web-console-1.6.179.md).
Historical changes are in [release notes](docs/releases), not this quick-start guide.
Use the Server image for deployment; the console archive alone is not a control plane.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{
"name": "@pasturestack/web-console",
"version": "1.6.178",
"version": "1.6.179",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@pasturestack/web-console",
"version": "1.6.178",
"version": "1.6.179",
"license": "Apache-2.0",
"dependencies": {
"sass": "1.103.1"
Expand Down Expand Up @@ -75,7 +75,7 @@
"rtlcss": "4.3.0",
"semver": "7.8.5",
"serialize-javascript": "7.1.0",
"shell-quote": "1.10.0",
"shell-quote": "1.11.0",
"socket.io-client": "4.8.3",
"sort-package-json": "file:vendor/sort-package-json-compat",
"source-map-url": "file:vendor/source-map-url-compat/source-map-url-0.4.0-rc16.0.tgz",
Expand Down Expand Up @@ -17622,9 +17622,9 @@
}
},
"node_modules/shell-quote": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.10.0.tgz",
"integrity": "sha512-w1aiOKwKuRgtwAReIIj89puqg+I7GvX4IbLrvmhXbzQsj1+Zwi4VO3+fa6ZF91TWSjIxoEkKnMeHcLEODK5ZXA==",
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.11.0.tgz",
"integrity": "sha512-JdxDPD0DBTyu08pq0kPC0xSNet/qsU07qT6IsX1AS8oO2ICNRY4ldNa8OAI6PuwAH8tG3lxEhbqmyp4Dw4036g==",
"dev": true,
"license": "MIT",
"engines": {
Expand Down
39 changes: 39 additions & 0 deletions docs/releases/web-console-1.6.179.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Web Console 1.6.179 — reviewed dependencies and shell quoting fix

This component release packages the dependency updates already merged through
PRs #180 and #182, based on `main` commit
`629e5714984afa9e66671c099773170f54519580`. The reviewed lock resolves Moment
2.31.0, markdown-it 14.3.2, postcss-selector-parser 7.1.6, proxy-addr 2.0.8,
compression 1.8.2 and source-map-js 1.2.2. It also updates shell-quote from 1.10.0
to official minimum-fixed 1.11.0 in npm and the vendored browser bundle.

The first exact-source CI [37500749166](https://github.com/PastureStack/web-console/actions/runs/37500749166)
failed closed on the newly published Critical
[GHSA-pqg4-j6r4-53mv](https://github.com/advisories/GHSA-pqg4-j6r4-53mv).
The affected library accepted line terminators in a string after a comment
token. The browser bundle contains that library, although the current product
callers do not establish this comment-then-string precondition: input-command
only parses, and the catalog answer preview quotes a single answer token.
This is library remediation, not a confirmed product command-injection claim.

The release diff updates numeric version metadata, the reviewed lock,
existing gate version constants, shell-quote vendor provenance and smoke pins,
focused security/legitimate-input regressions, README and this note. The browser
wrapper and application callers remain unchanged. The complete official 1.11.0
module bodies are used; no local security backport or new application feature
is introduced. The existing Critical/High audit threshold, fail-closed checks and
dated `GHSA-vfj7-8cjw-p6xm` build-input review remain unchanged; this is not a
zero-CVE claim or runtime not-affected VEX.

Publication uses the existing fixed-source `Validate Web Console` workflow:
source and supply-chain gates, Chrome unit tests, two production builds and a
byte comparison of the deterministic numeric-root archives. The immutable
[1.6.179 release](https://github.com/PastureStack/web-console/releases/tag/1.6.179)
records the tested source, normal signed PR merge, exact CI run, archive SHA-256
and size. Its assets reuse the retained CI archive and portable checksum without
rebuilding. The new numeric lightweight tag binds the tested signed commit;
the tag itself is not signed. Previous component tags and assets are preserved.

Server assembly and deployed browser acceptance are separate results. This
component publication does not claim deployment, complete permission/resource/
locale coverage, or promotion of any historical HOLD or INCOMPLETE result.
12 changes: 6 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@pasturestack/web-console",
"version": "1.6.178",
"version": "1.6.179",
"private": true,
"description": "PastureStack browser console for the compatible control platform.",
"repository": {
Expand Down Expand Up @@ -118,7 +118,7 @@
"rtlcss": "4.3.0",
"semver": "7.8.5",
"serialize-javascript": "7.1.0",
"shell-quote": "1.10.0",
"shell-quote": "1.11.0",
"socket.io-client": "4.8.3",
"sort-package-json": "file:vendor/sort-package-json-compat",
"source-map-url": "file:vendor/source-map-url-compat/source-map-url-0.4.0-rc16.0.tgz",
Expand Down
4 changes: 2 additions & 2 deletions scripts/check-modernization-blockers
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ with open('package.json', encoding='utf-8') as f:
print(json.load(f).get('version', ''))
PY
)
if [[ "$version" != "1.6.178" ]]; then
echo "UNEXPECTED_UI_ARTIFACT_VERSION version=$version expected=1.6.178"
if [[ "$version" != "1.6.179" ]]; then
echo "UNEXPECTED_UI_ARTIFACT_VERSION version=$version expected=1.6.179"
failures=$((failures + 1))
fi

Expand Down
2 changes: 1 addition & 1 deletion scripts/check-ui-console-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -143,4 +143,4 @@ if [[ -n ${PASTURESTACK_PRIVATE_MARKER:-} ]] && grep -RInF -- "$PASTURESTACK_PRI
fi

printf 'UI_CONSOLE_WORKSPACE_OK version=%s persistence=%s cross_tab=%s\n' \
1.6.178 browser-session broker-broadcast
1.6.179 browser-session broker-broadcast
2 changes: 1 addition & 1 deletion scripts/check-ui-critical-high-dependencies
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ if lock_bytes != baseline_bytes:
lock = json.loads(lock_bytes)
packages = lock.get("packages", {})
root = packages.get("", {})
if package.get("version") != "1.6.178":
if package.get("version") != "1.6.179":
fail(f"unexpected Web Console version: {package.get('version')}")
if root.get("version") != package.get("version"):
fail(f"lock root version differs: {root.get('version')}")
Expand Down
34 changes: 31 additions & 3 deletions scripts/node24-lock-smoke.js
Original file line number Diff line number Diff line change
Expand Up @@ -964,7 +964,7 @@ function expectBrowserifyReplacementVendorGlobals() {
const expected = {
"vendor/ansi-up/ansi-up-global.js": "a50281fdb1fbe71cf638f09e897d4f5b153a418f731be2db410c796982f75682",
"vendor/semver/semver-global.js": "d3c2df6e4e516f21e66e52675f1baf85ba753842fb3f603827f8815ecbc41e9b",
"vendor/shell-quote/shell-quote-global.js": "cdfa04900aae1f1cf27d3c06e6658534eebf74c48edb11dec3b83f9b7dbd4fa8",
"vendor/shell-quote/shell-quote-global.js": "bb1719d929d5435124120975b8df02c9084aea3907688d6125d0a80cf8665b8d",
};
const sandbox = { window: {}, self: {}, exports: undefined, module: undefined, define: undefined };
sandbox.global = sandbox;
Expand All @@ -988,13 +988,41 @@ function expectBrowserifyReplacementVendorGlobals() {
if (!shellQuote.quote(["hello world"]).includes("'hello world'")) {
fail("vendored shell-quote quote smoke failed");
}
for (const implementation of [shellQuote, require("shell-quote")]) {
for (const terminator of ["\n", "\r", "\u2028", "\u2029"]) {
const hostile = "a" + terminator + "id;#";
for (const tokens of [
["echo", "ok", { comment: "x" }, hostile],
implementation.parse("echo http://example.com/#fragment").concat(hostile),
]) {
let rejected = false;
try {
implementation.quote(tokens);
} catch (error) {
rejected = error.name === "TypeError";
}
if (!rejected) {
fail("shell-quote comment line-terminator rejection failed");
}
}
}
for (const answer of ["", "hello world", "O'Brien!", "$HOME; echo value", "line\nvalue"]) {
if (JSON.stringify(implementation.parse(implementation.quote([answer]))) !== JSON.stringify([answer])) {
fail("shell-quote legitimate single-token roundtrip failed");
}
}
if (implementation.quote(["echo", { comment: "x" }, "ordinary"]) !== "echo #x ordinary") {
fail("shell-quote ordinary post-comment token changed");
}
}
console.log("shell-quote-comment-boundary-smoke-ok implementations=2 hostile_cases=16 single_token_controls=10");
const ansiUp = new AnsiUp();
ansiUp.escape_html = false;
const ansiHtml = ansiUp.ansi_to_html("\u001b[31mred\u001b[0m <x>");
if (!ansiHtml.includes("red") || ansiHtml.includes("<")) {
fail(`vendored ansi_up smoke failed: ${ansiHtml}`);
}
console.log("browserify-replacement-vendor-smoke-ok semver=5.7.2 shell-quote=1.10.0 ansi_up=6.0.6");
console.log("browserify-replacement-vendor-smoke-ok semver=5.7.2 shell-quote=1.11.0 ansi_up=6.0.6");
}

function expectCommonmarkBrowserGlobal(file) {
Expand Down Expand Up @@ -1541,7 +1569,7 @@ expectPackageJsonVersion("md5-jkmyers", "0.0.1");
expectVersion("async", "3.2.6");
expectVersion("prismjs", "1.30.0");
expectVersion("lodash", "4.18.1");
expectVersion("shell-quote", "1.10.0");
expectVersion("shell-quote", "1.11.0");
expectVersion("dagre-d3-es", "7.0.14");
expectVersion("commonmark", "0.31.2");
expectPackageJsonVersion("billboard.js", "4.0.3");
Expand Down
30 changes: 30 additions & 0 deletions tests/unit/utils/shell-quote-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { module, test } from 'qunit';
import ShellQuote from 'ui/utils/shell-quote';

module('Unit | Utility | Shell quote', function() {
test('rejects all line terminators after a comment token', function(assert) {
['\n', '\r', '\u2028', '\u2029'].forEach((terminator) => {
assert.throws(() => ShellQuote.quote([
'echo', 'ok', { comment: 'x' }, `a${ terminator }id;#`,
]), /after a `comment` must not contain line terminators/);
});
});

test('rejects appended hostile strings after a parsed mid-word comment', function(assert) {
const command = ShellQuote.parse('echo http://example.com/#fragment');
assert.ok(command.some((token) => token && typeof token === 'object' && 'comment' in token));
['\n', '\r', '\u2028', '\u2029'].forEach((terminator) => {
assert.throws(() => ShellQuote.quote(command.concat(`a${ terminator }id;#`)),
/after a `comment` must not contain line terminators/);
});
});

test('preserves legitimate command parsing and single-token catalog quoting', function(assert) {
assert.deepEqual(ShellQuote.parse("echo 'hello world'"), ['echo', 'hello world']);
['', 'hello world', "O'Brien!", '$HOME; echo value', 'line\nvalue'].forEach((answer) => {
assert.deepEqual(ShellQuote.parse(ShellQuote.quote([answer])), [answer]);
});
assert.strictEqual(ShellQuote.quote(['echo', { comment: 'x' }, 'ordinary']), 'echo #x ordinary');
assert.strictEqual(ShellQuote.quote(['line\nvalue', { comment: 'x' }]), "'line\nvalue' #x");
});
});
9 changes: 8 additions & 1 deletion vendor/shell-quote/UPSTREAM.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
# Vendored shell-quote Browser Bundle

- Source package: `shell-quote@1.10.0` from the Node 24 no-publish lock baseline.
- Source package: `shell-quote@1.11.0` from the reviewed Node 24 lock baseline.
- Official package integrity: `sha512-JdxDPD0DBTyu08pq0kPC0xSNet/qsU07qT6IsX1AS8oO2ICNRY4ldNa8OAI6PuwAH8tG3lxEhbqmyp4Dw4036g==`.
- Source files: `index.js`, `parse.js`, and `quote.js` bundled with browserify standalone name `rc16ShellQuote`.
- License: MIT.

This preserves the existing PastureStack Web Console shell parse/quote behavior while removing `ember-browserify` and `npm:shell-quote` from the application build path.

Version 1.11.0 includes the official fix for
[GHSA-pqg4-j6r4-53mv](https://github.com/advisories/GHSA-pqg4-j6r4-53mv): strings
after a comment token cannot contain line terminators. The existing standalone
wrapper is retained; its three module bodies match the integrity-verified
official package. The MIT license text is unchanged.
Loading
Loading