Skip to content

Commit

Permalink
Replaces unused jwt auth with signed requests used by debug app
Browse files Browse the repository at this point in the history
  • Loading branch information
asyed94 committed Aug 26, 2024
1 parent 1508226 commit 7de34d9
Show file tree
Hide file tree
Showing 8 changed files with 36 additions and 92 deletions.
16 changes: 11 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ This will remove all docker images created by the server during the build proces

These api are protected preventing general public to wiping out debug data to authenticate use `/authenticate/:passphrase`. `passphrase` is set in `config.ts` config file or within the system env variable.

GET `/log/api-stats` this endpint emit the rpc interface call counts and avg tps along with a few a other information. This endpoint support query by time range. i.e `/log/api-stats?start={x}&end={x}`. The parameter value can be either `yyyy-mm-dd` or unix epoch in millisecond. (NOTE standard unix epoch is in seconds which does not work, it has to be in millisecond accuracy). Not setting any timestamp parameter will returns paginated json of all the entry in db.
GET `/log/api-stats` this endpoint emits the rpc interface call counts and avg tps along with a few a other information. This endpoint support query by time range. i.e `/log/api-stats?start={x}&end={x}`. The parameter value can be either `yyyy-mm-dd` or unix epoch in millisecond. (NOTE standard unix epoch is in seconds which does not work, it has to be in millisecond accuracy). Not setting any timestamp parameter will returns paginated json of all the entry in db.

GET `/log/txs` this endpoint return the txs it has been made through rpc server. This endpoint support dynmaic pagination. i.e `/log/txs?max=30&page=9`.
Default values are `1000` for `max` and `0` for page.
Expand All @@ -117,15 +117,21 @@ GET `/log/status` this endpint return status of logging such as date of recordin

GET `/log/startTxCapture` this endpoint set the config value to true which control whether to capture incoming txs and store in database.

GET `/log/stopRPCCapture` this endpoint set the config value to false which control whether to capture incoming rpc interface call stat and store in database
GET `/log/stopRPCCapture` this endpoint set the config value to false which control whether to capture incoming rpc interface call stat and store in database.

GET `/log/startRPCCapture` this endpoint set the config value to true which control whether to capture rpc interface call stat and store in database.

GET `/log/stopTxCapture` this endpoint set the config value to false which control whether to capture incoming txs and store in database
GET `/log/stopTxCapture` this endpoint set the config value to false which control whether to capture incoming txs and store in database.

GET `/cleanStatTable` this endpoint trigger purging of table that store interface stats
GET `/log/cleanStatTable` this endpoint trigger purging of table that store interface stats.

GET `/cleanTxTable` this endpoint trigger purging of table that store transaction logging
GET `/log/cleanTxTable` this endpoint trigger purging of table that store transaction logging.

GET `/counts` this endpoint emits the nestedCounters report as an array.

GET `/counts-reset` this endpoint resets the internal nestedCounters object.

GET `/api/subsribe` this endpoint changes the subscribed validator node to the ip and port specified in the `ip` and `port` query parameters.

# Health Check

Expand Down
4 changes: 0 additions & 4 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,6 @@ type Config = {
statLog: boolean
statLogIntervalSec: number
statLogLimit: number
passphrase: string
secret_key: string

blockCacheSettings: {
lastNBlocksSize: number
Expand Down Expand Up @@ -166,8 +164,6 @@ export const CONFIG: Config = {
statLog: false,
statLogIntervalSec: 10,
statLogLimit: 10000,
passphrase: process.env.PASSPHRASE || 'sha4d3um', // this is to protect debug routes
secret_key: process.env.SECRET_KEY || 'YsDGSMYHkSBMGD6B4EmD?mFTWG2Wka-Z9b!Jc/CLkrM8eLsBe5abBaTSGeq?6g?P', // this is the private key that rpc server will used to sign jwt token
adaptiveRejection: true,
filterDeadNodesFromArchiver: false,
verbose: false,
Expand Down
22 changes: 0 additions & 22 deletions src/middlewares/authorize.ts

This file was deleted.

11 changes: 0 additions & 11 deletions src/middlewares/debugMiddleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,18 +65,7 @@ export function handleDebugAuth(_req: any, res: any, next: any, authLevel: any)
message: 'FORBIDDEN!',
})
}
} else {
// /* prettier-ignore */ if (logFlags.verbose) console.log('Signature is not correct')
}
} else {
// if (logFlags.verbose) {
// const parsedCounter = parseInt(sigObj.count)
// if (Number.isNaN(parsedCounter)) {
// console.log('Counter is not a number')
// } else {
// console.log('Counter is not larger than last counter', parsedCounter, lastCounter)
// }
// }
}
}
}
Expand Down
31 changes: 0 additions & 31 deletions src/routes/authenticate.ts

This file was deleted.

10 changes: 5 additions & 5 deletions src/routes/log.ts
Original file line number Diff line number Diff line change
Expand Up @@ -339,23 +339,23 @@ router.route('/cleanTxTable').get(async function (req: Request, res: Response) {
})

router.route('/startTxCapture').get(async function (req: Request, res: Response) {
if (CONFIG.recordTxStatus) return res.json({ message: 'Tx recording already enabled' }).status(304)
if (CONFIG.recordTxStatus) return res.json({ message: 'Tx recording already enabled' }).status(204)
debug_info.txRecordingStartTime = Date.now()
debug_info.txRecordingEndTime = 0
CONFIG.recordTxStatus = true

res.json({ message: 'Transaction status recording enabled' }).status(200)
})
router.route('/stopTxCapture').get(async function (req: Request, res: Response) {
if (!CONFIG.recordTxStatus) return res.json({ message: 'Tx recording already stopped' }).status(304)
if (!CONFIG.recordTxStatus) return res.json({ message: 'Tx recording already stopped' }).status(204)
debug_info.txRecordingEndTime = Date.now()
CONFIG.recordTxStatus = false
res.send({ message: 'Transaction status recording disabled' }).status(200)
})

router.route('/startRPCCapture').get(async function (req: Request, res: Response) {
if (CONFIG.statLog) {
return res.json({ message: 'Interface stats are recording already' }).status(304)
return res.json({ message: 'Interface stats are recording already' }).status(204)
}
debug_info.interfaceRecordingStartTime = Date.now()
debug_info.interfaceRecordingEndTime = 0
Expand All @@ -365,15 +365,15 @@ router.route('/startRPCCapture').get(async function (req: Request, res: Response
})
router.route('/stopRPCCapture').get(async function (req: Request, res: Response) {
if (!CONFIG.statLog) {
return res.json({ message: 'Interface stats recording already stopped' }).status(304)
return res.json({ message: 'Interface stats recording already stopped' }).status(204)
}
debug_info.interfaceRecordingEndTime = Date.now()
CONFIG.statLog = false
res.json({ message: 'RPC interface recording disabled' }).status(200)
})
router.route('/countRPCCapture').get(async function (req: Request, res: Response) {
if (!CONFIG.statLog) {
return res.json({ message: 'Interface stats recording disabled' }).status(304)
return res.json({ message: 'Interface stats recording disabled' }).status(204)
}
res.json(getInterfaceStatCounts()).status(200)
})
Expand Down
21 changes: 7 additions & 14 deletions src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import * as WebSocket from 'ws'
import cookieParser from 'cookie-parser'
import { methods, saveTxStatus } from './api'
import { debug_info, setupLogEvents } from './logger'
import authorize from './middlewares/authorize'
import injectIP from './middlewares/injectIP'
import { setupDatabase } from './storage/sqliteStorage'
import {
Expand All @@ -21,7 +20,6 @@ import {
updateEdgeNodeConfig,
} from './utils'
import { router as logRoute } from './routes/log'
import { router as authenticate } from './routes/authenticate'
import { healthCheckRouter } from './routes/healthCheck'
import { Request, Response } from 'express'
import { CONFIG, CONFIG as config } from './config'
Expand Down Expand Up @@ -104,24 +102,20 @@ if (config.dashboard.enabled && config.dashboard.dist_path) {
// app.set('views', clientDirectory);
}

app.get('/api/subscribe', authorize, (req: Request, res: Response) => {
app.get('/api/subscribe', handleDebugAuth, (req: Request, res: Response) => {

Check failure

Code scanning / CodeQL

Missing rate limiting High

This route handler performs
authorization
, but is not rate-limited.
nestedCountersInstance.countEvent('api', 'subscribe')
const query = req.query
if (!query || !req.ip || !query.port) {
if (!query || !query.ip || !query.port) {
console.log('Invalid ip or port')
return res.end('Invalid ip or port')
}
const ip = req.ip || '127.0.0.1'
const port = req.connection.localPort || 9001
const success = changeNode(ip, port, true)
if (!success) {
res.end(`Ip not in the nodelist ${ip}:${port}, node subscription rejected`)
return
}
const ip = query.ip.toString() || '127.0.0.1'
const port = parseInt(query.port.toString()) || 9001
changeNode(ip, port)
res.end(`Successfully changed to ${ip}:${port}`)

Check failure

Code scanning / CodeQL

Reflected cross-site scripting High

Cross-site scripting vulnerability due to a
user-provided value
.
})

app.get('/counts', authorize, (req: Request, res: Response) => {
app.get('/counts', handleDebugAuth, (req: Request, res: Response) => {

Check failure

Code scanning / CodeQL

Missing rate limiting High

This route handler performs
authorization
, but is not rate-limited.
nestedCountersInstance.countEvent('api', 'counts')
const arrayReport = nestedCountersInstance.arrayitizeAndSort(nestedCountersInstance.eventCounters)
if (req.headers.accept === 'application/json') {
Expand All @@ -139,7 +133,7 @@ app.get('/counts', authorize, (req: Request, res: Response) => {
}
})

app.get('/counts-reset', authorize, (req: Request, res: Response) => {
app.get('/counts-reset', handleDebugAuth, (req: Request, res: Response) => {

Check failure

Code scanning / CodeQL

Missing rate limiting High

This route handler performs
authorization
, but is not rate-limited.
nestedCountersInstance.eventCounters = new Map()
res.write(`counts reset ${Date.now()}`)
res.end()
Expand Down Expand Up @@ -193,7 +187,6 @@ app.use(async (req: Request, res: Response, next: NextFunction) => {
})

app.use('/log', handleDebugAuth, logRoute)

Check failure

Code scanning / CodeQL

Missing rate limiting High

This route handler performs
authorization
, but is not rate-limited.
app.use('/authenticate', authenticate)
app.use('/', healthCheckRouter)
app.use(injectIP)
// reject subscription methods from http
Expand Down
13 changes: 13 additions & 0 deletions use_test_key.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
diff --git a/src/config.ts b/src/config.ts
index b1ac6d7..27d70ea 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -203,5 +203,7 @@ export const CONFIG: Config = {
},
enableBlockCache: false,
useRoundRobinConsensorSelection: true,
- devPublicKeys: {}
+ devPublicKeys: {
+ '774491f80f47fedb119bb861601490f42bc3ea3b57fc63906c0d08e6d777a592': 3,
+ }
}

0 comments on commit 7de34d9

Please sign in to comment.