git-watchtower 1.10.14 → 1.10.16

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.
@@ -2082,6 +2082,14 @@ let server = null;
2082
2082
 
2083
2083
  function createStaticServer() {
2084
2084
  return http.createServer((req, res) => {
2085
+ // DNS-rebinding protection: reject requests with non-loopback Host headers
2086
+ const host = (req.headers.host || '').replace(/:\d+$/, '').toLowerCase();
2087
+ if (host !== 'localhost' && host !== '127.0.0.1' && host !== '[::1]') {
2088
+ res.writeHead(403, { 'Content-Type': 'text/plain' });
2089
+ res.end('Forbidden: invalid Host header');
2090
+ return;
2091
+ }
2092
+
2085
2093
  const url = new URL(req.url, `http://localhost:${PORT}`);
2086
2094
  let pathname = url.pathname;
2087
2095
  const logPath = pathname; // Keep original for logging
@@ -3282,7 +3290,7 @@ async function start() {
3282
3290
  } else {
3283
3291
  // Static mode
3284
3292
  server = createStaticServer();
3285
- server.listen(PORT, () => {
3293
+ server.listen(PORT, '127.0.0.1', () => {
3286
3294
  addLog(`Server started on http://localhost:${PORT}`, 'success');
3287
3295
  addLog(`Serving ${STATIC_DIR.replace(PROJECT_ROOT, '.')}`, 'info');
3288
3296
  addLog(`Current branch: ${store.get('currentBranch')}`, 'info');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "git-watchtower",
3
- "version": "1.10.14",
3
+ "version": "1.10.16",
4
4
  "description": "Terminal-based Git branch monitor with activity sparklines and optional dev server with live reload",
5
5
  "main": "bin/git-watchtower.js",
6
6
  "bin": {
package/src/server/web.js CHANGED
@@ -342,6 +342,17 @@ class WebDashboardServer {
342
342
  * @private
343
343
  */
344
344
  _handleRequest(req, res) {
345
+ // DNS-rebinding protection: only allow requests whose Host header
346
+ // matches a known loopback address. Without this, a malicious page
347
+ // could resolve an attacker-controlled hostname to 127.0.0.1 and
348
+ // POST to /api/action to trigger destructive actions.
349
+ const host = (req.headers.host || '').replace(/:\d+$/, '').toLowerCase();
350
+ if (host !== 'localhost' && host !== '127.0.0.1' && host !== '[::1]') {
351
+ res.writeHead(403, { 'Content-Type': 'text/plain' });
352
+ res.end('Forbidden: invalid Host header');
353
+ return;
354
+ }
355
+
345
356
  const url = new URL(req.url, `http://localhost:${this.port}`);
346
357
  const pathname = url.pathname;
347
358