Add Phase 409 diagnostics redaction and deep-link query allowlist.

Export redactDiagnosticsBundle and filterDeepLinkQuery; enforce allowed
deep-link kinds and strip non-allowlisted settings/explore query keys.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Raven Scott
2026-06-02 16:41:38 -04:00
co-authored by Cursor
parent 849747f860
commit c718f094d5
4 changed files with 76 additions and 2 deletions
+33
View File
@@ -0,0 +1,33 @@
'use strict'
/** Strict allowlist for pearcord:// settings query keys (P409-30). */
const SETTINGS_QUERY_KEYS = new Set([
'section',
'scope',
'guildId',
'channelId',
'tab'
])
const EXPLORE_QUERY_KEYS = new Set(['baseline', 'count', 'at'])
function filterDeepLinkQuery (kind, search) {
const allowed =
kind === 'settings'
? SETTINGS_QUERY_KEYS
: kind === 'explore'
? EXPLORE_QUERY_KEYS
: null
if (!allowed) return search
const q = String(search || '').replace(/^\?/, '')
const parts = []
for (const part of q.split('&')) {
if (!part) continue
const eq = part.indexOf('=')
const k = eq >= 0 ? part.slice(0, eq) : part
if (allowed.has(k)) parts.push(part)
}
return parts.length ? `?${parts.join('&')}` : ''
}
module.exports = { SETTINGS_QUERY_KEYS, EXPLORE_QUERY_KEYS, filterDeepLinkQuery }
+15 -2
View File
@@ -23,8 +23,20 @@
* pearcord://settings?section=appearance&scope=user * pearcord://settings?section=appearance&scope=user
* pearcord://settings?section=channels&scope=guild&guildId={guildId} * pearcord://settings?section=channels&scope=guild&guildId={guildId}
*/ */
const { filterDeepLinkQuery } = require('./deep-link-allowlist')
const PEARCORD_SCHEME = 'pearcord' const PEARCORD_SCHEME = 'pearcord'
const ALLOWED_DEEP_LINK_KINDS = new Set([
'message',
'guild',
'guild-channel',
'invite',
'pair',
'explore',
'settings'
])
const MSG_ONLY = /^pearcord:\/\/m\/([a-f0-9-]{8,})$/i const MSG_ONLY = /^pearcord:\/\/m\/([a-f0-9-]{8,})$/i
const GUILD_MSG = /^pearcord:\/\/g\/([a-f0-9-]{8,})\/c\/([a-f0-9-]{8,})\/m\/([a-f0-9-]{8,})$/i const GUILD_MSG = /^pearcord:\/\/g\/([a-f0-9-]{8,})\/c\/([a-f0-9-]{8,})\/m\/([a-f0-9-]{8,})$/i
const GUILD_CHANNEL = /^pearcord:\/\/g\/([a-f0-9-]{8,})\/c\/([a-f0-9-]{8,})\/?$/i const GUILD_CHANNEL = /^pearcord:\/\/g\/([a-f0-9-]{8,})\/c\/([a-f0-9-]{8,})\/?$/i
@@ -60,7 +72,7 @@ function parseInviteQuery (search) {
} }
function parseExploreQuery (search) { function parseExploreQuery (search) {
const q = String(search || '').replace(/^\?/, '') const q = filterDeepLinkQuery('explore', search).replace(/^\?/, '')
let baseline = null let baseline = null
let baselineAt = null let baselineAt = null
for (const part of q.split('&')) { for (const part of q.split('&')) {
@@ -150,7 +162,7 @@ function parsePearcordDeepLink (url) {
} }
function parseSettingsQuery (search) { function parseSettingsQuery (search) {
const q = String(search || '').replace(/^\?/, '') const q = filterDeepLinkQuery('settings', search).replace(/^\?/, '')
let section = null let section = null
let scope = 'user' let scope = 'user'
let guildId = null let guildId = null
@@ -218,6 +230,7 @@ function formatExploreBaselineDeepLink ({ baseline, baselineAt } = {}) {
module.exports = { module.exports = {
PEARCORD_SCHEME, PEARCORD_SCHEME,
ALLOWED_DEEP_LINK_KINDS,
isPearcordDeepLink, isPearcordDeepLink,
findPearcordDeepLinkInArgv, findPearcordDeepLinkInArgv,
parsePearcordDeepLink, parsePearcordDeepLink,
+22
View File
@@ -0,0 +1,22 @@
'use strict'
const TOKEN_LIKE =
/(?:bearer\s+|token[=:]\s*|api[_-]?key[=:]\s*|secret[=:]\s*|pcdv_[A-Za-z0-9_-]{16,}|pcd_[A-Za-z0-9_-]{24,})/gi
/**
* Redact token-like strings from exported diagnostics (P409-29).
*/
function redactDiagnosticsBundle (payload) {
if (payload == null) return payload
if (typeof payload === 'string') {
return payload.replace(TOKEN_LIKE, '[redacted]')
}
try {
const json = JSON.stringify(payload)
return JSON.parse(json.replace(TOKEN_LIKE, '[redacted]'))
} catch {
return payload
}
}
module.exports = { redactDiagnosticsBundle, TOKEN_LIKE }
+6
View File
@@ -631,8 +631,11 @@ const {
contentHasEveryoneOrHereMention, contentHasEveryoneOrHereMention,
contentHasChannelMention contentHasChannelMention
} = require('./mentions') } = require('./mentions')
const { redactDiagnosticsBundle } = require('./diagnostics-redaction')
const { filterDeepLinkQuery } = require('./deep-link-allowlist')
const { const {
PEARCORD_SCHEME, PEARCORD_SCHEME,
ALLOWED_DEEP_LINK_KINDS,
isPearcordDeepLink, isPearcordDeepLink,
findPearcordDeepLinkInArgv, findPearcordDeepLinkInArgv,
parsePearcordDeepLink, parsePearcordDeepLink,
@@ -712,7 +715,10 @@ module.exports = {
contentHasHereMention, contentHasHereMention,
contentHasEveryoneOrHereMention, contentHasEveryoneOrHereMention,
contentHasChannelMention, contentHasChannelMention,
redactDiagnosticsBundle,
filterDeepLinkQuery,
PEARCORD_SCHEME, PEARCORD_SCHEME,
ALLOWED_DEEP_LINK_KINDS,
isPearcordDeepLink, isPearcordDeepLink,
findPearcordDeepLinkInArgv, findPearcordDeepLinkInArgv,
parsePearcordDeepLink, parsePearcordDeepLink,