git-watchtower 2.3.12 → 2.3.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/casino/index.js +7 -0
- package/src/server/web.js +37 -1
package/package.json
CHANGED
package/src/casino/index.js
CHANGED
|
@@ -110,6 +110,13 @@ function disable() {
|
|
|
110
110
|
// up to ~15 frames × 120 ms = 1.8 s after disable, and lossMessage stayed
|
|
111
111
|
// set so isLossAnimating() reported true into the next session.
|
|
112
112
|
resetLossState();
|
|
113
|
+
// Drop the marquee render callback so a stale closure to the previous
|
|
114
|
+
// session's render() doesn't survive across enable/disable cycles. In
|
|
115
|
+
// production this is mostly hygiene (bin/git-watchtower.js wires the
|
|
116
|
+
// callback exactly once at startup against a singleton render fn), but
|
|
117
|
+
// tests that re-use the casino module saw the previous test's callback
|
|
118
|
+
// persist into the next setRenderCallback assignment.
|
|
119
|
+
marqueeCallback = null;
|
|
113
120
|
}
|
|
114
121
|
|
|
115
122
|
/**
|
package/src/server/web.js
CHANGED
|
@@ -46,6 +46,36 @@ const SSE_KEEPALIVE_INTERVAL = 15000;
|
|
|
46
46
|
*/
|
|
47
47
|
const MAX_STALLED_PUSHES = 60;
|
|
48
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Content-Security-Policy header for the dashboard HTML.
|
|
51
|
+
*
|
|
52
|
+
* The dashboard uses inline <script> and inline <style> blocks (the whole
|
|
53
|
+
* UI is bundled at build time), and makes XHR / EventSource calls to
|
|
54
|
+
* /api/... on the same origin. No external resources are loaded.
|
|
55
|
+
*
|
|
56
|
+
* `default-src 'none'` denies everything not explicitly allowed.
|
|
57
|
+
* `script-src` / `style-src` need 'unsafe-inline' for the bundled blocks.
|
|
58
|
+
* `connect-src 'self'` lets XHR + SSE hit /api/... .
|
|
59
|
+
* `base-uri 'none'` blocks <base> injection from rewriting URLs.
|
|
60
|
+
* `form-action 'none'` blocks any rogue form posts.
|
|
61
|
+
* `frame-ancestors 'none'` blocks embedding (defense vs. clickjacking).
|
|
62
|
+
*
|
|
63
|
+
* Defense-in-depth — the dashboard already escapes user-supplied content
|
|
64
|
+
* everywhere we render it, but a future regression that forgets escHtml
|
|
65
|
+
* is mitigated here.
|
|
66
|
+
*/
|
|
67
|
+
const CONTENT_SECURITY_POLICY = [
|
|
68
|
+
"default-src 'none'",
|
|
69
|
+
"script-src 'self' 'unsafe-inline'",
|
|
70
|
+
"style-src 'self' 'unsafe-inline'",
|
|
71
|
+
"connect-src 'self'",
|
|
72
|
+
"img-src 'self' data:",
|
|
73
|
+
"font-src 'self'",
|
|
74
|
+
"base-uri 'none'",
|
|
75
|
+
"form-action 'none'",
|
|
76
|
+
"frame-ancestors 'none'",
|
|
77
|
+
].join('; ');
|
|
78
|
+
|
|
49
79
|
/**
|
|
50
80
|
* Actions the web dashboard is allowed to POST to /api/action. Every entry
|
|
51
81
|
* here MUST be matched by a `case` in `handleWebAction` in bin/git-watchtower.js
|
|
@@ -474,7 +504,12 @@ class WebDashboardServer {
|
|
|
474
504
|
|
|
475
505
|
// Routes
|
|
476
506
|
if (pathname === '/' && req.method === 'GET') {
|
|
477
|
-
res.writeHead(200, {
|
|
507
|
+
res.writeHead(200, {
|
|
508
|
+
'Content-Type': 'text/html; charset=utf-8',
|
|
509
|
+
'Content-Security-Policy': CONTENT_SECURITY_POLICY,
|
|
510
|
+
'X-Content-Type-Options': 'nosniff',
|
|
511
|
+
'Referrer-Policy': 'no-referrer',
|
|
512
|
+
});
|
|
478
513
|
res.end(this._cachedHtml);
|
|
479
514
|
return;
|
|
480
515
|
}
|
|
@@ -673,4 +708,5 @@ module.exports = {
|
|
|
673
708
|
STATE_PUSH_INTERVAL,
|
|
674
709
|
MAX_STALLED_PUSHES,
|
|
675
710
|
ALLOWED_ACTIONS,
|
|
711
|
+
CONTENT_SECURITY_POLICY,
|
|
676
712
|
};
|