Skip to content

Commit b17901d

Browse files
committed
fix: exclude vulnerable Bootstrap runtime plugins
1 parent c737a65 commit b17901d

14 files changed

Lines changed: 128 additions & 16 deletions

app/components/page-header/template.hbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070
</ul>
7171
{{#if item.showAlert}}
7272
{{#tooltip-element class="tooltip-warning" type='tooltip-warning' tooltipFor="showAlert"}}
73-
{{#link-to item.alertRoute data-toggle="tooltip" data-placement="bottom"}}!{{/link-to}}
73+
{{#link-to item.alertRoute}}!{{/link-to}}
7474
{{/tooltip-element}}
7575
{{/if}}
7676
</li>

docs/baselines/npm-package-lock.sass-replacement.node24-ignore-scripts.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
{
22
"name": "@pasturestack/web-console",
3-
"version": "1.6.56-pasturestack.35",
3+
"version": "1.6.56-pasturestack.36",
44
"lockfileVersion": 3,
55
"requires": true,
66
"packages": {
77
"": {
88
"name": "@pasturestack/web-console",
9-
"version": "1.6.56-pasturestack.35",
9+
"version": "1.6.56-pasturestack.36",
1010
"license": "Apache-2.0",
1111
"dependencies": {
1212
"sass": "1.99.0"

docs/modernization.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,15 @@ responsive local, OpenID Connect, SAML, MFA, and recovery layout; a
4545
reduced-motion animated gradient; new PastureStack-owned authentication and
4646
favicon assets; and a root favicon response so the login console remains clean.
4747

48+
`v1.6.56-pasturestack.36` removes the unsupported aggregate Bootstrap 3
49+
JavaScript bundle from the production graph. The compatibility UI now loads
50+
only the reviewed transition, collapse, and dropdown modules required by the
51+
navigation and menus. The vulnerable Button, Tooltip, and Popover plug-ins are
52+
excluded from both test and production artifacts, and source gates prevent
53+
their data APIs or jQuery entry points from being restored accidentally.
54+
Bootstrap-derived Sass remains temporarily isolated behind the existing theme
55+
boundary and must be replaced as a separate visual migration.
56+
4857
Production candidate packages omit JavaScript and third-party Intl source maps.
4958
They also omit the development-only `none` pseudo-locale. Development and test
5059
builds retain application source maps and the pseudo-locale for local diagnostics.

ember-cli-build.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,13 @@ module.exports = function(defaults) {
105105
app.import('node_modules/@xterm/xterm/css/xterm.css');
106106
app.import('node_modules/@xterm/xterm/lib/xterm.js');
107107
app.import('node_modules/@xterm/addon-fit/lib/addon-fit.js');
108-
app.import('vendor/bootstrap-sass/assets/javascripts/bootstrap.js');
108+
// Bootstrap 3 is out of support. Keep its reviewed styles during the
109+
// compatibility migration, but only ship the two JavaScript behaviours the
110+
// console still uses. In particular, do not re-introduce button.js,
111+
// tooltip.js, popover.js, or the aggregate bootstrap.js bundle.
112+
app.import('vendor/bootstrap-sass/assets/javascripts/bootstrap/transition.js');
113+
app.import('vendor/bootstrap-sass/assets/javascripts/bootstrap/collapse.js');
114+
app.import('vendor/bootstrap-sass/assets/javascripts/bootstrap/dropdown.js');
109115
app.import('node_modules/jgrowl/jquery.jgrowl.js');
110116
app.import('node_modules/jgrowl/jquery.jgrowl.css');
111117
app.import('node_modules/jquery.cookie/jquery.cookie.js');

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@pasturestack/web-console",
3-
"version": "1.6.56-pasturestack.35",
3+
"version": "1.6.56-pasturestack.36",
44
"private": true,
55
"directories": {
66
"doc": "doc",

scripts/check-modernization-blockers

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ with open('package.json', encoding='utf-8') as f:
4141
print(json.load(f).get('version', ''))
4242
PY
4343
)
44-
if [[ "$version" != "1.6.56-pasturestack.35" ]]; then
45-
echo "UNEXPECTED_UI_ARTIFACT_VERSION version=$version expected=1.6.56-pasturestack.35"
44+
if [[ "$version" != "1.6.56-pasturestack.36" ]]; then
45+
echo "UNEXPECTED_UI_ARTIFACT_VERSION version=$version expected=1.6.56-pasturestack.36"
4646
failures=$((failures + 1))
4747
fi
4848

scripts/check-ui-bootstrap-sass-bower-migration

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ cd "$(dirname "$0")/.."
55

66
python3 - <<'PY_CHECK'
77
import json
8+
import re
89
from pathlib import Path
910
1011
pkg = json.loads(Path("package.json").read_text())
@@ -22,14 +23,62 @@ if vendor_package.get("version") != "3.4.3":
2223
raise SystemExit("vendor bootstrap-sass must track npm bootstrap-sass 3.4.3")
2324
if vendor_package.get("license") != "MIT":
2425
raise SystemExit("vendor bootstrap-sass license metadata must remain MIT")
26+
27+
build = Path("ember-cli-build.js").read_text(encoding="utf-8")
28+
runtime_imports = re.findall(
29+
r"app\.import\('(?P<path>vendor/bootstrap-sass/assets/javascripts/[^']+)'\)",
30+
build,
31+
)
32+
expected_imports = [
33+
"vendor/bootstrap-sass/assets/javascripts/bootstrap/transition.js",
34+
"vendor/bootstrap-sass/assets/javascripts/bootstrap/collapse.js",
35+
"vendor/bootstrap-sass/assets/javascripts/bootstrap/dropdown.js",
36+
]
37+
if runtime_imports != expected_imports:
38+
raise SystemExit(
39+
"Bootstrap runtime allowlist drift: "
40+
f"actual={runtime_imports!r} expected={expected_imports!r}"
41+
)
42+
43+
forbidden_source_patterns = {
44+
"Bootstrap loading-state data API": re.compile(r"data-loading-text", re.I),
45+
"Bootstrap Button data API": re.compile(r"data-toggle\s*=\s*['\"]buttons?['\"]", re.I),
46+
"Bootstrap Tooltip data API": re.compile(r"data-toggle\s*=\s*['\"]tooltip['\"]", re.I),
47+
"Bootstrap Popover data API": re.compile(r"data-toggle\s*=\s*['\"]popover['\"]", re.I),
48+
"Bootstrap Button jQuery API": re.compile(r"\.button\s*\("),
49+
"Bootstrap Tooltip jQuery API": re.compile(r"\.tooltip\s*\("),
50+
"Bootstrap Popover jQuery API": re.compile(r"\.popover\s*\("),
51+
}
52+
active_sources = [
53+
path
54+
for root in (Path("app"), Path("tests"))
55+
for path in root.rglob("*")
56+
if path.is_file() and path.suffix in {".js", ".hbs", ".html"}
57+
]
58+
violations = []
59+
for path in active_sources:
60+
source = path.read_text(encoding="utf-8")
61+
for description, pattern in forbidden_source_patterns.items():
62+
if pattern.search(source):
63+
violations.append(f"{path}: {description}")
64+
if violations:
65+
raise SystemExit(
66+
"Vulnerable Bootstrap runtime API restored:\n" + "\n".join(violations)
67+
)
2568
PY_CHECK
2669

2770
if grep -R "bower_components/bootstrap-sass-official\\|node_modules/bootstrap-sass" -n ember-cli-build.js app/styles package.json docs/baselines/npm-package-lock.sass-replacement.node24-ignore-scripts.json 2>/dev/null; then
2871
echo "Bootstrap Sass must be imported from vendored maintenance source, not Bower or node_modules" >&2
2972
exit 1
3073
fi
3174

32-
grep -q "vendor/bootstrap-sass/assets/javascripts/bootstrap.js" ember-cli-build.js
75+
if grep -q "app.import('vendor/bootstrap-sass/assets/javascripts/bootstrap.js')" ember-cli-build.js; then
76+
echo "The unsupported aggregate Bootstrap JavaScript bundle must not be imported" >&2
77+
exit 1
78+
fi
79+
grep -q "vendor/bootstrap-sass/assets/javascripts/bootstrap/transition.js" ember-cli-build.js
80+
grep -q "vendor/bootstrap-sass/assets/javascripts/bootstrap/collapse.js" ember-cli-build.js
81+
grep -q "vendor/bootstrap-sass/assets/javascripts/bootstrap/dropdown.js" ember-cli-build.js
3382
grep -q "vendor/bootstrap-sass/assets/stylesheets/bootstrap" app/styles/app-light.scss
3483
grep -q "vendor/bootstrap-sass/assets/stylesheets/bootstrap" app/styles/app-dark.scss
3584
test -f vendor/bootstrap-sass/LICENSE

scripts/check-ui-console-workspace

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,4 +134,4 @@ if [[ -n ${PASTURESTACK_PRIVATE_MARKER:-} ]] && grep -RInF -- "$PASTURESTACK_PRI
134134
fi
135135

136136
printf 'UI_CONSOLE_WORKSPACE_OK version=%s persistence=%s cross_tab=%s\n' \
137-
1.6.56-pasturestack.35 browser-session broker-broadcast
137+
1.6.56-pasturestack.36 browser-session broker-broadcast

scripts/check-ui-static-artifact-layout

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,21 @@ cat >"$tmpdir/dist/index.html" <<'HTML'
1717
<script src="assets/vendor-test.js"></script>
1818
<script src="assets/ui-test.js"></script>
1919
HTML
20-
printf 'vendor\n' >"$tmpdir/dist/assets/vendor-test.js"
20+
printf 'vendor bs.collapse bs.dropdown\n' >"$tmpdir/dist/assets/vendor-test.js"
2121
printf 'ui\n' >"$tmpdir/dist/assets/ui-test.js"
2222
printf 'source map\n' >"$tmpdir/dist/assets/ui-test.js.map"
2323
printf '{}\n' >"$tmpdir/dist/translations/en-us.json"
2424
printf '{}\n' >"$tmpdir/dist/translations/none.json"
2525

26+
printf 'vendor bs.collapse bs.dropdown bs.tooltip\n' >"$tmpdir/dist/assets/vendor-test.js"
27+
if SOURCE_DATE_EPOCH=1700000000 bash ./scripts/package-static-candidate \
28+
9.9.9 "$tmpdir/dist" "$tmpdir/unsafe.tar.gz" >"$tmpdir/unsafe.out" 2>&1; then
29+
echo "VULNERABLE_BOOTSTRAP_RUNTIME_ACCEPTED"
30+
exit 1
31+
fi
32+
grep -q 'DIST_VULNERABLE_BOOTSTRAP_RUNTIME_PRESENT signature=bs.tooltip' "$tmpdir/unsafe.out"
33+
printf 'vendor bs.collapse bs.dropdown\n' >"$tmpdir/dist/assets/vendor-test.js"
34+
2635
out="$tmpdir/9.9.9.tar.gz"
2736
out_repeat="$tmpdir/9.9.9-repeat.tar.gz"
2837
SOURCE_DATE_EPOCH=1700000000 bash ./scripts/package-static-candidate 9.9.9 "$tmpdir/dist" "$out" >"$tmpdir/ui-static-layout.out"

0 commit comments

Comments
 (0)