termbeam 1.19.1 → 1.19.3
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/server/preview.js +6 -4
- package/src/server/routes.js +25 -4
package/package.json
CHANGED
package/src/server/preview.js
CHANGED
|
@@ -32,10 +32,12 @@ function createPreviewProxy() {
|
|
|
32
32
|
.json({ error: 'Invalid port: must be an integer between 1 and 65535' });
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
//
|
|
36
|
-
// Express
|
|
37
|
-
|
|
38
|
-
const
|
|
35
|
+
// Derive forward path from req.url to preserve trailing slashes.
|
|
36
|
+
// Express *path params lose trailing slashes, causing redirect loops
|
|
37
|
+
// with servers that enforce them (e.g. mkdocs: /TermBeam → /TermBeam/).
|
|
38
|
+
const portPrefix = `/${req.params.port}`;
|
|
39
|
+
const urlWithoutQuery = req.url.split('?')[0];
|
|
40
|
+
const forwardPath = urlWithoutQuery.slice(portPrefix.length) || '/';
|
|
39
41
|
const search = req.url.includes('?') ? req.url.slice(req.url.indexOf('?')) : '';
|
|
40
42
|
|
|
41
43
|
const fwdHeaders = { ...req.headers, host: `127.0.0.1:${port}` };
|
package/src/server/routes.js
CHANGED
|
@@ -10,6 +10,15 @@ const log = require('../utils/logger');
|
|
|
10
10
|
const rateLimit = require('express-rate-limit');
|
|
11
11
|
|
|
12
12
|
const PUBLIC_DIR = path.join(__dirname, '..', '..', 'public');
|
|
13
|
+
|
|
14
|
+
// Resolve a user-provided path relative to rootDir and verify it stays within bounds.
|
|
15
|
+
// Returns the resolved path or null if it escapes rootDir.
|
|
16
|
+
function safePath(rootDir, userPath) {
|
|
17
|
+
const resolved = path.resolve(rootDir, userPath);
|
|
18
|
+
if (!resolved.startsWith(rootDir + path.sep) && resolved !== rootDir) return null;
|
|
19
|
+
return resolved;
|
|
20
|
+
}
|
|
21
|
+
|
|
13
22
|
const uploadedFiles = new Map(); // id -> filepath
|
|
14
23
|
|
|
15
24
|
const IMAGE_SIGNATURES = [
|
|
@@ -644,7 +653,10 @@ function setupRoutes(app, { auth, sessions, config, state, pushManager }) {
|
|
|
644
653
|
}
|
|
645
654
|
|
|
646
655
|
const rootDir = path.resolve(sessions.getSessionCwd(req.params.id));
|
|
647
|
-
const dir =
|
|
656
|
+
const dir = safePath(rootDir, req.query.dir || '.');
|
|
657
|
+
if (!dir) {
|
|
658
|
+
return res.status(403).json({ error: 'Path is outside session directory' });
|
|
659
|
+
}
|
|
648
660
|
|
|
649
661
|
const MAX_ENTRIES = 1000;
|
|
650
662
|
try {
|
|
@@ -798,7 +810,10 @@ function setupRoutes(app, { auth, sessions, config, state, pushManager }) {
|
|
|
798
810
|
}
|
|
799
811
|
|
|
800
812
|
const rootDir = path.resolve(sessions.getSessionCwd(req.params.id));
|
|
801
|
-
const filePath =
|
|
813
|
+
const filePath = safePath(rootDir, file);
|
|
814
|
+
if (!filePath) {
|
|
815
|
+
return res.status(403).json({ error: 'Path is outside session directory' });
|
|
816
|
+
}
|
|
802
817
|
|
|
803
818
|
try {
|
|
804
819
|
if (fs.lstatSync(filePath).isSymbolicLink()) {
|
|
@@ -829,7 +844,10 @@ function setupRoutes(app, { auth, sessions, config, state, pushManager }) {
|
|
|
829
844
|
}
|
|
830
845
|
|
|
831
846
|
const rootDir = path.resolve(sessions.getSessionCwd(req.params.id));
|
|
832
|
-
const filePath =
|
|
847
|
+
const filePath = safePath(rootDir, file);
|
|
848
|
+
if (!filePath) {
|
|
849
|
+
return res.status(403).json({ error: 'Path is outside session directory' });
|
|
850
|
+
}
|
|
833
851
|
|
|
834
852
|
try {
|
|
835
853
|
if (fs.lstatSync(filePath).isSymbolicLink()) {
|
|
@@ -860,7 +878,10 @@ function setupRoutes(app, { auth, sessions, config, state, pushManager }) {
|
|
|
860
878
|
}
|
|
861
879
|
|
|
862
880
|
const rootDir = path.resolve(sessions.getSessionCwd(req.params.id));
|
|
863
|
-
const filePath =
|
|
881
|
+
const filePath = safePath(rootDir, file);
|
|
882
|
+
if (!filePath) {
|
|
883
|
+
return res.status(403).json({ error: 'Path is outside session directory' });
|
|
884
|
+
}
|
|
864
885
|
|
|
865
886
|
try {
|
|
866
887
|
if (fs.lstatSync(filePath).isSymbolicLink()) {
|