Skip to content

Commit d6581e5

Browse files
committed
fix: limit network info response fields
1 parent f794f62 commit d6581e5

3 files changed

Lines changed: 73 additions & 1 deletion

File tree

server/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { fileURLToPath } from 'url'
1414
import { blockCache } from './lib/cache'
1515
import { handleRouteError, parseNetwork, parseLimit, parseOffset, parseBlockOffset, parseAddress, ValidationError } from './lib/http'
1616
import { computeCirculatingSupply, currentBlockReward } from './lib/supply'
17+
import { toPublicNetworkInfo } from './lib/network-info'
1718
import { rpcWithNetwork } from '@fairco.in/rpc-client'
1819
import priceRouter from './routes/price'
1920
import statsHistoryRouter from './routes/stats-history'
@@ -441,7 +442,7 @@ app.get('/api/network-info', async (req, res) => {
441442
try {
442443
const network = parseNetwork(req.query.network)
443444
const networkInfo = await blockCache.getNetworkInfo(network)
444-
res.json(networkInfo)
445+
res.json(toPublicNetworkInfo(networkInfo))
445446
} catch (error) {
446447
handleRouteError(res, 'Failed to get network info', error)
447448
}

server/lib/network-info.test.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { describe, expect, it } from 'vitest'
2+
import { toPublicNetworkInfo } from './network-info'
3+
4+
describe('toPublicNetworkInfo', () => {
5+
it('returns only the public fields consumed by the frontend', () => {
6+
const publicInfo = toPublicNetworkInfo({
7+
version: 3000000,
8+
subversion: '/FairCoin:3.0.0/',
9+
protocolversion: 70015,
10+
connections: 8,
11+
relayfee: 0.001,
12+
networks: [{ name: 'ipv4', proxy: 'socks5://10.0.0.5:9050' }],
13+
localaddresses: [{ address: '203.0.113.7', port: 40404 }],
14+
localrelay: true,
15+
timeoffset: 0,
16+
warnings: 'backend warning text',
17+
})
18+
19+
expect(publicInfo).toEqual({
20+
version: 3000000,
21+
subversion: '/FairCoin:3.0.0/',
22+
protocolversion: 70015,
23+
connections: 8,
24+
relayfee: 0.001,
25+
})
26+
expect(publicInfo).not.toHaveProperty('networks')
27+
expect(publicInfo).not.toHaveProperty('localaddresses')
28+
expect(publicInfo).not.toHaveProperty('warnings')
29+
})
30+
31+
it('ignores malformed field values', () => {
32+
expect(toPublicNetworkInfo({ version: '3000000', connections: Number.NaN })).toEqual({
33+
version: undefined,
34+
subversion: undefined,
35+
protocolversion: undefined,
36+
connections: undefined,
37+
relayfee: undefined,
38+
})
39+
})
40+
})

server/lib/network-info.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
export interface PublicNetworkInfo {
2+
version?: number
3+
subversion?: string
4+
protocolversion?: number
5+
connections?: number
6+
relayfee?: number
7+
}
8+
9+
function pickNumber(value: unknown): number | undefined {
10+
return typeof value === 'number' && Number.isFinite(value) ? value : undefined
11+
}
12+
13+
function pickString(value: unknown): string | undefined {
14+
return typeof value === 'string' ? value : undefined
15+
}
16+
17+
export function toPublicNetworkInfo(networkInfo: unknown): PublicNetworkInfo {
18+
if (!networkInfo || typeof networkInfo !== 'object') {
19+
return {}
20+
}
21+
22+
const info = networkInfo as Record<string, unknown>
23+
24+
return {
25+
version: pickNumber(info.version),
26+
subversion: pickString(info.subversion),
27+
protocolversion: pickNumber(info.protocolversion),
28+
connections: pickNumber(info.connections),
29+
relayfee: pickNumber(info.relayfee),
30+
}
31+
}

0 commit comments

Comments
 (0)