ohos-playwright-mcp 0.2.5 → 0.2.7

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.
Files changed (2) hide show
  1. package/package.json +2 -2
  2. package/server.mjs +17 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ohos-playwright-mcp",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "description": "MCP server for HarmonyOS / OpenHarmony ArkWeb — playwright-core over CDP. 61 tools: navigation, input, network, cookies, storage, snapshot, tracing. The ohos counterpart of @playwright/mcp.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -38,7 +38,7 @@
38
38
  "node": ">=24"
39
39
  },
40
40
  "peerDependencies": {
41
- "ohos-playwright": ">=0.2.5",
41
+ "ohos-playwright": ">=0.2.8",
42
42
  "playwright-core": ">=1.59.0"
43
43
  },
44
44
  "publishConfig": {
package/server.mjs CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  import { createRequire } from 'node:module'
9
9
  import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'node:fs'
10
- import { dirname, join } from 'node:path'
10
+ import { dirname, join, resolve as resolvePath } from 'node:path'
11
11
  import { tmpdir } from 'node:os'
12
12
 
13
13
  const require = createRequire(import.meta.url)
@@ -30,6 +30,19 @@ const SETUP_PATH = resolveOrThrow('ohos-playwright/setup', 'ARKWEB_OHOS_PW
30
30
  const PW_CORE_PATH = resolveOrThrow('playwright-core', 'ARKWEB_PW_CORE')
31
31
  const INFO_PATH = process.env.OHOS_PW_INFO_PATH ?? `${tmpdir()}/ohos-playwright-cdp.json`
32
32
 
33
+ function safeOutputPath(inputPath) {
34
+ // 拒绝包含 .. 的路径,防止路径穿越
35
+ if (inputPath.includes('..')) {
36
+ throw new Error(`path traversal rejected: "${inputPath}" contains ".."`)
37
+ }
38
+ const resolved = resolvePath(inputPath)
39
+ const cwd = process.cwd()
40
+ if (!resolved.startsWith(tmpdir()) && !resolved.startsWith(cwd)) {
41
+ throw new Error(`output path must be within current directory or temp directory: ${resolved}`)
42
+ }
43
+ return resolved
44
+ }
45
+
33
46
  let cdpEndpoint = null
34
47
 
35
48
  await import(REGISTER_PATH)
@@ -47,7 +60,6 @@ let bootstrapPromise = null
47
60
  const consoleBuffer = [] // { pageUrl, type, text, ts }
48
61
  const networkRequests = [] // { id, url, method, status, requestHeaders, responseHeaders, postData, fromCache, durationMs }
49
62
  const networkById = new Map()
50
- const dialogQueue = [] // pending dialog handlers; auto-dismiss with default
51
63
  let dialogPolicy = { action: 'dismiss', promptText: '' }
52
64
  const routeHandlers = new Map() // pattern -> {handler, status: 'active', hits: 0}
53
65
 
@@ -269,7 +281,7 @@ tool('screenshot', 'Take a PNG screenshot. Default saves to a tmp path (ArkWeb r
269
281
  if (inline) {
270
282
  return { content: [{ type: 'image', data: buf.toString('base64'), mimeType: 'image/png' }] }
271
283
  }
272
- const outPath = path ?? join(tmpdir(), `ohos-screenshot-${Date.now()}.png`)
284
+ const outPath = path ? safeOutputPath(path) : join(tmpdir(), `ohos-screenshot-${Date.now()}.png`)
273
285
  mkdirSync(dirname(outPath), { recursive: true })
274
286
  writeFileSync(outPath, buf)
275
287
  return `saved ${buf.length} bytes to ${outPath}`
@@ -676,6 +688,7 @@ tool('pdf_save', 'Save the current page as PDF (headless-only in Chrome — may
676
688
  sObj({ path: sStr() }, ['path']),
677
689
  async ({ path }) => {
678
690
  const page = await getPage()
691
+ path = safeOutputPath(path)
679
692
  mkdirSync(dirname(path), { recursive: true })
680
693
  await page.pdf({ path })
681
694
  return `saved PDF to ${path}`
@@ -693,6 +706,7 @@ tool('stop_tracing', 'Stop tracing and save the .zip to `path`.',
693
706
  sObj({ path: sStr() }, ['path']),
694
707
  async ({ path }) => {
695
708
  await getPage()
709
+ path = safeOutputPath(path)
696
710
  mkdirSync(dirname(path), { recursive: true })
697
711
  await context.tracing.stop({ path })
698
712
  return `trace saved to ${path}`