Skip to content

Commit 91227b9

Browse files
committed
fix(webui): upgrade Tiptap to address attribute prototype vulnerability
1 parent 82be702 commit 91227b9

5 files changed

Lines changed: 84 additions & 29 deletions

File tree

apps/webui/package.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@
1616
"description": "",
1717
"dependencies": {
1818
"@openagentpack/playbooks": "workspace:*",
19-
"@tiptap/core": "^3.27.2",
20-
"@tiptap/extension-document": "^3.27.2",
21-
"@tiptap/extension-mention": "^3.27.2",
22-
"@tiptap/extension-paragraph": "^3.27.2",
23-
"@tiptap/extension-text": "^3.27.2",
24-
"@tiptap/pm": "^3.27.2",
25-
"@tiptap/react": "^3.27.2",
26-
"@tiptap/suggestion": "^3.27.2",
19+
"@tiptap/core": "3.30.4",
20+
"@tiptap/extension-document": "3.30.4",
21+
"@tiptap/extension-mention": "3.30.4",
22+
"@tiptap/extension-paragraph": "3.30.4",
23+
"@tiptap/extension-text": "3.30.4",
24+
"@tiptap/pm": "3.30.4",
25+
"@tiptap/react": "3.30.4",
26+
"@tiptap/suggestion": "3.30.4",
2727
"lucide-react": "^1.18.0",
2828
"react": "^19.2.7",
2929
"react-dom": "^19.2.7",

apps/webui/tests/serialize-prompt.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import Document from "@tiptap/extension-document";
33
import Mention from "@tiptap/extension-mention";
44
import Paragraph from "@tiptap/extension-paragraph";
55
import Text from "@tiptap/extension-text";
6+
import { Fragment } from "@tiptap/pm/model";
7+
import { ReplaceStep } from "@tiptap/pm/transform";
68
import { Editor } from "@tiptap/react";
79
import { editorToSubmitPrompt, fileMentionSentinel } from "@/lib/editor/serialize-prompt";
810
import { createSelectedEntry } from "@/lib/hooks/selected-files";
@@ -22,6 +24,24 @@ function makeEditor(content: object) {
2224
}
2325

2426
describe("editorToSubmitPrompt", () => {
27+
test("splits paragraphs using a single ProseMirror model instance", () => {
28+
const editor = makeEditor({
29+
type: "doc",
30+
content: [{ type: "paragraph", content: [{ type: "text", text: "abcd" }] }],
31+
});
32+
try {
33+
expect(ReplaceStep.fromJSON(editor.schema, { from: 0, to: 0 }).slice.content).toBeInstanceOf(Fragment);
34+
editor.commands.setTextSelection(3);
35+
expect(editor.commands.splitBlock()).toBe(true);
36+
expect(editor.getJSON().content).toEqual([
37+
{ type: "paragraph", content: [{ type: "text", text: "ab" }] },
38+
{ type: "paragraph", content: [{ type: "text", text: "cd" }] },
39+
]);
40+
} finally {
41+
editor.destroy();
42+
}
43+
});
44+
2545
test("mention maps to sentinel via buildFileBindings", () => {
2646
const editor = makeEditor({
2747
type: "doc",
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { describe, expect, test } from "bun:test";
2+
import { mergeAttributes } from "@tiptap/core";
3+
4+
describe("Tiptap attribute safety", () => {
5+
test("does not inherit attributes from a JSON-origin __proto__ key", () => {
6+
// Regression for GHSA-cp6q-959q-f8rh; use an inert marker instead of executable attributes.
7+
const untrustedAttributes = JSON.parse('{"__proto__":{"data-inherited":"unexpected"},"title":"file"}');
8+
const attributes = mergeAttributes({ class: "mention-tag" }, untrustedAttributes);
9+
10+
expect(Object.getPrototypeOf(attributes)).toBe(Object.prototype);
11+
expect("data-inherited" in attributes).toBe(false);
12+
expect(attributes.class).toBe("mention-tag");
13+
expect(attributes.title).toBe("file");
14+
});
15+
16+
test("continues merging ordinary mention classes and attributes", () => {
17+
const attributes = mergeAttributes(
18+
{ class: "mention-tag", "data-type": "mention", title: "previous" },
19+
{ class: "selected", "data-id": "file_1", title: "current" },
20+
);
21+
22+
expect(attributes).toEqual({
23+
class: "mention-tag selected",
24+
"data-type": "mention",
25+
"data-id": "file_1",
26+
title: "current",
27+
});
28+
});
29+
});

bun.lock

Lines changed: 23 additions & 20 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,15 @@
7272
"typescript": "^6.0.3"
7373
},
7474
"overrides": {
75+
"@tiptap/extension-bubble-menu": "3.30.4",
76+
"@tiptap/extension-floating-menu": "3.30.4",
7577
"brace-expansion": "5.0.9",
7678
"esbuild": "0.28.1",
7779
"fast-equals": "5.3.3",
7880
"js-yaml": "4.3.1",
7981
"nanoid": "3.3.18",
80-
"postcss": "8.5.23"
82+
"postcss": "8.5.23",
83+
"prosemirror-model": "1.25.11"
8184
},
8285
"trustedDependencies": [
8386
"@ast-grep/cli"

0 commit comments

Comments
 (0)