T05 · Unauthorized Access and Privilege Escalation
- Location
src/tools.ts:45- Finding
Dynamic Exchange Discovery Exceeds the Declared Network Allowlist
- Content
View full analysis
Vulnerability Details
File Location:
src/tools.ts:45-71, 127-139
Vulnerability Type: Least-privilege violation through undeclared network destinations
Risk Level: MediumVulnerable Code
ts const exportList = Object.keys(pmxt) as Array<keyof typeof pmxt>; // Try to find the Exchange class constructor from exports if needed, or use imported Exchange const ExchangeClass = (pmxt as any).Exchange || Exchange; // Dynamic discovery for any other exchanges for (const key of exportList) { const normalizedKey = key.toLowerCase(); if (exchanges.has(normalizedKey)) continue; const ExportedItem = (pmxt as any)[key]; // Check if it is a class that extends Exchange (and is not Exchange itself) // We use prototype check to confirm inheritance if ( typeof ExportedItem === 'function' && ExportedItem.prototype instanceof ExchangeClass && ExportedItem !== ExchangeClass ) { try { const instance = new ExportedItem(); exchanges.set(normalizedKey, instance); // console.log(`Loaded exchange: ${key}`); } catch (e) { console.warn(`Failed to initialize exchange adapter for ${key}:`, e); } } }ts const targets = normalizedExchange ? (exchanges.has(normalizedExchange) ? [normalizedExchange] : []) : Array.from(exchanges.keys()); if (normalizedExchange && targets.length === 0) { return { success: false, error: `Unsupported exchange: ${exchange}` }; } const promises = targets.map(async (key) => { const client = exchanges.get(key); if (!client) return; try { // Assuming all exchanges implement fetchMarkets({ query }) // If the signature varies, we might need more robust checking or an adapter const markets = await (client as any).fetchMarkets({ query }); if (Array.isArray(markets)) { results.push(...markets.map(m => normalizeM ...[truncated 2666 chars]- Remediation
View remediation
Remediation Suggestions
- Remove automatic discovery and registration of arbitrary
pmxtjsexchange subclasses. - Define an immutable allowlist containing only
polymarket,kalshi, andlimitless. - Construct clients exclusively from explicit, reviewed adapter constructors.
- When no exchange is supplied, target only the explicit allowlist rather than all map entries.
- Enforce destination restrictions at the HTTP or runtime sandbox layer in addition to application checks.
- Pin
pmxtjsto an exact reviewed version instead of a caret range, and update it only after dependency review. - Add tests proving that unexpected exported
Exchangesubclasses are neither initialized nor queried. - Consider requiring an explicit exchange argument to avoid unnecessary disclosure of each query to multiple providers.
- Remove automatic discovery and registration of arbitrary
