WalleGriffkinder commited on
Commit
a0bbc9d
·
verified ·
1 Parent(s): 908bd01

Update server.js

Browse files
Files changed (1) hide show
  1. server.js +56 -18
server.js CHANGED
@@ -281,7 +281,7 @@ fileRouter.get('/deleteFile', async (req, res) => {
281
  }
282
 
283
  const absoluteRequestedPath = path.normalize(path.join(TELEGRAM_DATA_DIR, relativePath));
284
- if (!absoluteRequestedPath.startsWith(path.resolve(TELEGRAM_DATA_DIR))) {
285
  return res.status(403).json({ error: 'Forbidden: Path traversal attempt detected.' });
286
  }
287
 
@@ -318,19 +318,20 @@ fileRouter.get('/:botToken/deleteById', async (req, res) => {
318
  return res.status(404).json({ error: 'File not found or path not available via Telegram API (getFile).', details: fileInfo });
319
  }
320
 
321
- const relativePathFromTg = fileInfo.result.file_path;
322
- const absoluteRequestedPath = path.normalize(path.join(TELEGRAM_DATA_DIR, relativePathFromTg));
 
323
 
324
- if (!absoluteRequestedPath.startsWith(path.resolve(TELEGRAM_DATA_DIR))) {
325
- console.warn(`[DeleteById] Potential path traversal attempt blocked. Path: ${relativePathFromTg}`);
326
- return res.status(403).json({ error: 'Forbidden: Invalid file path resolved.' });
327
  }
328
 
329
- if (fssync.existsSync(absoluteRequestedPath) && fssync.statSync(absoluteRequestedPath).isFile()) {
330
- await fs.unlink(absoluteRequestedPath);
331
- res.json({ success: true, message: `File deleted successfully. Path: ${relativePathFromTg}`, file_id: file_id });
332
  } else {
333
- res.status(404).json({ error: 'File not found on disk for the given file_id.', path_attempted: relativePathFromTg });
334
  }
335
  } catch (error) {
336
  console.error(`Error in /:botToken/deleteById for file_id ${file_id}:`, error);
@@ -361,9 +362,17 @@ fileRouter.get('/downloadEncrypted', async (req, res) => {
361
  return res.status(404).json({ error: 'File not found or path not available via Telegram API.', details: fileInfo });
362
  }
363
 
364
- const filePathOnDisk = path.join(TELEGRAM_DATA_DIR, fileInfo.result.file_path);
365
- if (fssync.existsSync(filePathOnDisk) && fssync.statSync(filePathOnDisk).isFile()) {
366
- res.sendFile(filePathOnDisk, { headers: { 'Content-Disposition': `attachment; filename="${path.basename(fileInfo.result.file_path)}"` } }, err => {
 
 
 
 
 
 
 
 
367
  if (err && !res.headersSent) res.status(500).send('Error sending file.');
368
  });
369
  } else {
@@ -394,8 +403,27 @@ fileRouter.get('/:botToken/getFile', async (req, res) => {
394
  if (fileInfo.ok && fileInfo.result && fileInfo.result.file_path) {
395
  const spaceHost = process.env.SPACE_HOST;
396
  const publicSpaceUrl = spaceHost ? `https://${spaceHost}` : `http://localhost:${APP_PORT}`;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
397
 
398
- fileInfo.result.direct_download_link_by_path = `${publicSpaceUrl}/file/${fileInfo.result.file_path}`;
399
  fileInfo.result.direct_download_link_by_id = `${publicSpaceUrl}/file/${botToken}/downloadFile?file_id=${file_id}`;
400
 
401
  if (encryptionKeyBuffer) {
@@ -436,9 +464,17 @@ fileRouter.get('/:botToken/downloadFile', async (req, res) => {
436
  return res.status(404).json({ error: 'File not found or path not available via Telegram API.', details: fileInfo });
437
  }
438
 
439
- const filePathOnDisk = path.join(TELEGRAM_DATA_DIR, fileInfo.result.file_path);
440
- if (fssync.existsSync(filePathOnDisk) && fssync.statSync(filePathOnDisk).isFile()) {
441
- res.sendFile(filePathOnDisk, { headers: { 'Content-Disposition': `attachment; filename="${path.basename(fileInfo.result.file_path)}"` } }, err => {
 
 
 
 
 
 
 
 
442
  if (err && !res.headersSent) res.status(500).send('Error sending file.');
443
  });
444
  } else {
@@ -455,7 +491,9 @@ fileRouter.get('/:filepath(*)', (req, res) => {
455
  if (!relativePath || relativePath.includes('..')) return res.status(400).send('Invalid file path.');
456
 
457
  const absoluteRequestedPath = path.normalize(path.join(TELEGRAM_DATA_DIR, relativePath));
458
- if (!absoluteRequestedPath.startsWith(path.resolve(TELEGRAM_DATA_DIR))) return res.status(403).send('Forbidden.');
 
 
459
 
460
  if (fssync.existsSync(absoluteRequestedPath) && fssync.statSync(absoluteRequestedPath).isFile()) {
461
  res.sendFile(absoluteRequestedPath, err => {
 
281
  }
282
 
283
  const absoluteRequestedPath = path.normalize(path.join(TELEGRAM_DATA_DIR, relativePath));
284
+ if (!path.resolve(absoluteRequestedPath).startsWith(path.resolve(TELEGRAM_DATA_DIR))) {
285
  return res.status(403).json({ error: 'Forbidden: Path traversal attempt detected.' });
286
  }
287
 
 
318
  return res.status(404).json({ error: 'File not found or path not available via Telegram API (getFile).', details: fileInfo });
319
  }
320
 
321
+ const filePathOnDisk = fileInfo.result.file_path;
322
+ const resolvedDataDir = path.resolve(TELEGRAM_DATA_DIR);
323
+ const resolvedFilePathOnDisk = path.resolve(filePathOnDisk);
324
 
325
+ if (!resolvedFilePathOnDisk.startsWith(resolvedDataDir)) {
326
+ console.error(`[Security] Attempt to delete file outside TELEGRAM_DATA_DIR. Requested: ${filePathOnDisk}, Allowed base: ${resolvedDataDir}`);
327
+ return res.status(403).json({ error: 'Forbidden: File path is outside allowed directory.' });
328
  }
329
 
330
+ if (fssync.existsSync(resolvedFilePathOnDisk) && fssync.statSync(resolvedFilePathOnDisk).isFile()) {
331
+ await fs.unlink(resolvedFilePathOnDisk);
332
+ res.json({ success: true, message: `File deleted successfully. Path: ${filePathOnDisk}`, file_id: file_id });
333
  } else {
334
+ res.status(404).json({ error: 'File not found on disk for the given file_id.', path_attempted: filePathOnDisk });
335
  }
336
  } catch (error) {
337
  console.error(`Error in /:botToken/deleteById for file_id ${file_id}:`, error);
 
362
  return res.status(404).json({ error: 'File not found or path not available via Telegram API.', details: fileInfo });
363
  }
364
 
365
+ const filePathOnDisk = fileInfo.result.file_path;
366
+ const resolvedDataDir = path.resolve(TELEGRAM_DATA_DIR);
367
+ const resolvedFilePathOnDisk = path.resolve(filePathOnDisk);
368
+
369
+ if (!resolvedFilePathOnDisk.startsWith(resolvedDataDir)) {
370
+ console.error(`[Security] Attempt to access file outside TELEGRAM_DATA_DIR. Requested: ${filePathOnDisk}, Allowed base: ${resolvedDataDir}`);
371
+ return res.status(403).send('Forbidden: File path is outside allowed directory.');
372
+ }
373
+
374
+ if (fssync.existsSync(resolvedFilePathOnDisk) && fssync.statSync(resolvedFilePathOnDisk).isFile()) {
375
+ res.sendFile(resolvedFilePathOnDisk, { headers: { 'Content-Disposition': `attachment; filename="${path.basename(fileInfo.result.file_path)}"` } }, err => {
376
  if (err && !res.headersSent) res.status(500).send('Error sending file.');
377
  });
378
  } else {
 
403
  if (fileInfo.ok && fileInfo.result && fileInfo.result.file_path) {
404
  const spaceHost = process.env.SPACE_HOST;
405
  const publicSpaceUrl = spaceHost ? `https://${spaceHost}` : `http://localhost:${APP_PORT}`;
406
+
407
+ const apiFilePath = fileInfo.result.file_path;
408
+ let relativePathForLink = "";
409
+
410
+ const resolvedNormalizedDataDir = path.resolve(TELEGRAM_DATA_DIR);
411
+ const resolvedApiFilePath = path.resolve(apiFilePath);
412
+
413
+ if (resolvedApiFilePath.startsWith(resolvedNormalizedDataDir)) {
414
+ relativePathForLink = path.relative(resolvedNormalizedDataDir, resolvedApiFilePath);
415
+ } else {
416
+ console.warn(`[Warning] file_path from API (${apiFilePath}) does not seem to be inside TELEGRAM_DATA_DIR (${TELEGRAM_DATA_DIR}). Using file_path as is for link, which might be incorrect.`);
417
+ relativePathForLink = apiFilePath;
418
+ }
419
+
420
+ if (relativePathForLink.startsWith('..')) {
421
+ console.error(`[Security] Calculated relative path for link starts with '..': ${relativePathForLink}. Original API path: ${apiFilePath}`);
422
+ fileInfo.result.direct_download_link_by_path = "Error: could not construct safe relative path.";
423
+ } else {
424
+ fileInfo.result.direct_download_link_by_path = `${publicSpaceUrl}/file/${relativePathForLink.split(path.sep).join('/')}`;
425
+ }
426
 
 
427
  fileInfo.result.direct_download_link_by_id = `${publicSpaceUrl}/file/${botToken}/downloadFile?file_id=${file_id}`;
428
 
429
  if (encryptionKeyBuffer) {
 
464
  return res.status(404).json({ error: 'File not found or path not available via Telegram API.', details: fileInfo });
465
  }
466
 
467
+ const filePathOnDisk = fileInfo.result.file_path;
468
+ const resolvedDataDir = path.resolve(TELEGRAM_DATA_DIR);
469
+ const resolvedFilePathOnDisk = path.resolve(filePathOnDisk);
470
+
471
+ if (!resolvedFilePathOnDisk.startsWith(resolvedDataDir)) {
472
+ console.error(`[Security] Attempt to access file outside TELEGRAM_DATA_DIR. Requested: ${filePathOnDisk}, Allowed base: ${resolvedDataDir}`);
473
+ return res.status(403).send('Forbidden: File path is outside allowed directory.');
474
+ }
475
+
476
+ if (fssync.existsSync(resolvedFilePathOnDisk) && fssync.statSync(resolvedFilePathOnDisk).isFile()) {
477
+ res.sendFile(resolvedFilePathOnDisk, { headers: { 'Content-Disposition': `attachment; filename="${path.basename(fileInfo.result.file_path)}"` } }, err => {
478
  if (err && !res.headersSent) res.status(500).send('Error sending file.');
479
  });
480
  } else {
 
491
  if (!relativePath || relativePath.includes('..')) return res.status(400).send('Invalid file path.');
492
 
493
  const absoluteRequestedPath = path.normalize(path.join(TELEGRAM_DATA_DIR, relativePath));
494
+ if (!path.resolve(absoluteRequestedPath).startsWith(path.resolve(TELEGRAM_DATA_DIR))) {
495
+ return res.status(403).send('Forbidden: Path traversal attempt detected.');
496
+ }
497
 
498
  if (fssync.existsSync(absoluteRequestedPath) && fssync.statSync(absoluteRequestedPath).isFile()) {
499
  res.sendFile(absoluteRequestedPath, err => {