@zhangfengshun/dsh-remote-ssh 2.3.7 → 2.3.8

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/lib/index.js CHANGED
@@ -945,13 +945,18 @@ function normExec(r) {
945
945
  // HTTP 工具
946
946
  // ---------------------------------------------------------------------------
947
947
 
948
- function isTrusted(req) {
948
+ function isTrusted(req, requireRequestedWith) {
949
949
  const secFetchSite = req.headers["sec-fetch-site"];
950
950
  if (secFetchSite === "cross-site") return false;
951
951
  const host = req.headers["host"];
952
952
  if (!host) return false;
953
953
  const hostname = String(host).split(":")[0].replace(/^\[/, "").replace(/\]$/, "");
954
- if (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1" || hostname === "0.0.0.0") return true;
954
+ if (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1" || hostname === "0.0.0.0") {
955
+ // CSRF 加固(PR #4 的服务端半边):/remote-ssh/api/* 仅由本插件客户端调用,
956
+ // 其请求必带 x-requested-with;跨站 no-cors POST 无法携带非简单头,预检也会被拒。
957
+ if (requireRequestedWith && String(req.headers["x-requested-with"] || "").trim() !== "XMLHttpRequest") return false;
958
+ return true;
959
+ }
955
960
  return false;
956
961
  }
957
962
 
@@ -1503,7 +1508,9 @@ function apply(ctx, config) {
1503
1508
  kind: "prefix",
1504
1509
  path: "/remote-ssh/api",
1505
1510
  handler: async (req, res) => {
1506
- if (!isTrusted(req)) { writeError(res, new Error("forbidden"), 403); return; }
1511
+ // CSRF 加固:/remote-ssh/api/* 仅由本插件客户端调用,强制校验其必带的
1512
+ // x-requested-with 头(跨站攻击者无法在 no-cors POST 中携带非简单头)。
1513
+ if (!isTrusted(req, true)) { writeJson(res, 403, { ok: false, error: { code: "csrf", message: "missing x-requested-with header" } }); return; }
1507
1514
  if (req.method !== "POST") { writeError(res, new Error("method not allowed"), 405); return; }
1508
1515
  const pathname = new URL(req.url || "/", "http://dsh.internal").pathname;
1509
1516
  if (!pathname.startsWith(API_BASE)) { writeError(res, new Error("not-found"), 404); return; }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhangfengshun/dsh-remote-ssh",
3
- "version": "2.3.7",
3
+ "version": "2.3.8",
4
4
  "description": "DSH web plugin: VSCode Remote-SSH-like remote development (SSH to supercomputers/servers, remote workspace, file explorer, integrated terminal), integrated with dsh-better-sidebar and DSH settings.",
5
5
  "keywords": [
6
6
  "dsh",