anthropics / anthropics/claude-code

claude.ai Gmail MCP create_draft: the google.com/url wrapper is emitted CORRUPTED (raw 0x17 in place of "=1"), and the substituted signature carries no gmail_signature marker

オープン
#93,271 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る
area:cowork area:mcp bug platform:web
主要言語
Python
スター
145k
フォーク
23.1k
PR マージ指標
PR 指標を取得中

説明

Concerns the **claude.ai Gmail MCP connector** (`create_draft`), used from Cowork on the web.

Two defects, neither covered by the existing redirect-wrapper issues (#91287, #80204, #66847), which are about URLs being wrapped. This is about the wrapper being **malformed**, and about the signature substitution being **undetectable**.

## 1. The redirect wrapper is emitted with a raw control byte

A draft created with `create_draft` came back with every signature link rewritten to `https://www.google.com/url?q=...&source=gmail&ust=&sa=E`, which is the known behaviour. But in the stored `htmlBody`, `ust=1789075556686000` was emitted as:

```
&ust\x1789075556686000&sa=E
```

A raw `0x17` (ETB) byte sits where `=1` should be. Every wrapped link in the draft carried it. That is not a redirect, it is a corrupted URL, and it shipped to an external recipient before anyone noticed. Reproduced by reading the sent message back with `get_message` (`FULL_CONTENT`) and with `list_drafts` (`DRAFT_VIEW_FULL`).

Looks like a formatting/escaping bug where the timestamp is spliced in: `=1` collapsing to `\x17` is exactly what happens if `"=1"` is treated as an escape rather than literal text.

## 2. The substituted signature is indistinguishable from a real one, downstream

`create_draft` cannot attach the account's real Gmail signature, so the draft carries a hand-assembled copy. That copy has **no `class="gmail_signature"`** and no `data-smartmail` attribute — the markers Gmail itself always emits.

The consequence: nothing downstream can tell a genuine signature from the substituted one. In our case the draft was later opened in the Gmail composer and edited by hand; the body was corrected, the replica signature rode along untouched, and the email went out with the sender's phone line as `+1 647-952-3336` (an anchor with no `href`) and six corrupted wrapper links.

Also in that copy: `href="javascript:void(0)"` on a `tel:` link that is `tel:+1...` in the real signature.

## Impact

A user who drafts through the connector and then finishes in Gmail — which is the natural workflow, and the one Gmail's own UI encourages — sends mail with broken links under their own name and has no signal that anything is wrong. The body reads correctly; only the signature is damaged, which is the part nobody re-reads.

## What would fix it

- The escaping bug in (1) on its own.
- For (2): either emit the account's real signature, or emit `class="gmail_signature"` on the substituted block so tooling can detect the substitution, or return a field on the draft saying the signature was synthesised.

## Workaround in use

We now diff the outgoing signature against a reference captured from a signature Gmail itself inserted, and refuse to send on any difference; and any draft not built in a fresh Gmail composer is discarded and rebuilt rather than edited. That is a lot of machinery for what looks like a string-formatting bug.

コントリビューションガイド

このリポジトリのコントリビューションガイドは索引されていません

調査の方向性

Start at the claude.ai Gmail MCP connector's create_draft entry point and reproduce the result by reading the message with get_message (FULL_CONTENT) and list_drafts (DRAFT_VIEW_FULL). Trace how the redirect-wrapper timestamp and substituted signature are emitted; done means no raw 0x17 corruption and the synthesized signature is detectable through a marker or draft field.

索引モデルが issue の本文から書いたものです。

評価

領域
api
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
活発
明瞭さ
おおむね明確
初心者へのやさしさ
42/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。