Zotero 9 cancels HTTP requests carrying an Origin header — BBT endpoints not exempted, breaks Obsidian integration
Environment
- Zotero 9.0.6 (macOS 26)
- Better BibTeX 9.0.36 (checked: master / 9.0.64 also does not opt in)
- Obsidian Zotero Integration 3.2.1 (
obsidian-zotero-desktop-connector, last release 2024-08)
Problem
Zotero 9's HTTP server cancels any request that carries an Origin header, unless the endpoint sets allowRequestsFromUnsafeWebContent or the request carries zotero-allowed-request / x-zotero-connector-api-version (see Zotero.Server.RequestHandler.prototype._processEndpoint in chrome/content/zotero/xpcom/server/server.js).
BBT's endpoints (/better-bibtex/cayw, /better-bibtex/json-rpc) do not set allowRequestsFromUnsafeWebContent, so every request from Obsidian's Zotero Integration fails with an empty reply, and the plugin reports "Cannot connect to Zotero... Better BibTeX".
Obsidian's plugin sends its requests via Obsidian's requestUrl (Electron main process), which automatically attaches Origin: app://obsidian.md — the plugin cannot suppress this header, and the plugin itself hasn't shipped a release since Aug 2024. This breaks probe, CAYW and JSON-RPC alike, i.e. the entire Obsidian workflow.
Reproduction
$ curl -i 'http://127.0.0.1:23119/better-bibtex/cayw?probe=true' -H 'Origin: app://obsidian.md'
curl: (52) Empty reply from server # connection cancelled, Zotero.debug logs "Preventing request from browser"
$ curl -i 'http://127.0.0.1:23119/better-bibtex/cayw?probe=true' # no Origin header
ready
$ curl -i 'http://127.0.0.1:23119/better-bibtex/cayw?probe=true' -H 'Origin: app://obsidian.md' -H 'zotero-allowed-request: true'
readySame behavior on /connector/ping, so the guard is at the Zotero server layer, not inside BBT — but BBT is the only endpoint affected tools rely on here, and opting in is a one-liner on BBT's side.
Suggested fix
Set allowRequestsFromUnsafeWebContent = true on the endpoint classes registered in content/cayw.ts and content/json-rpc.ts. Obsidian's requestUrl is an Electron main-process request, not a web-page context, so the threat model the Zotero 9 guard targets (arbitrary web pages probing localhost) does not apply to it.
Current workaround
Patched the Obsidian plugin's shared request-headers constant to include "zotero-allowed-request": "true". Works, but obviously gets overwritten on plugin update, and a proper fix on BBT's side would let users revert.
Source: retorquere/zotero-better-bibtex