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:
@@ -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
@@ -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,
|
||||||
|
|||||||
@@ -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 }
|
||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user