]> zoso.dev Git - nano-pow.git/commitdiff
Reject server request if headers indicate content is larger than max allowed. Destroy...
authorChris Duncan <chris@zoso.dev>
Mon, 21 Apr 2025 13:01:21 +0000 (06:01 -0700)
committerChris Duncan <chris@zoso.dev>
Mon, 21 Apr 2025 13:01:21 +0000 (06:01 -0700)
src/bin/server.ts

index bf3f5a9bfe57f9ee6c9f0c4990da67a2c01e2f94..b98d580d1945019581a4931f7be57fe11ef11a43 100755 (executable)
@@ -6,7 +6,7 @@ import { launch } from 'puppeteer'
 import { subtle } from 'node:crypto'
 import { readFile, unlink, writeFile } from 'node:fs/promises'
 import * as http from 'node:http'
-import { AddressInfo } from 'node:net'
+import { AddressInfo, Socket } from 'node:net'
 import { homedir } from 'node:os'
 import { join } from 'node:path'
 import type { NanoPowOptions, WorkGenerateRequest, WorkGenerateResponse, WorkValidateRequest, WorkValidateResponse } from '#types'
@@ -30,10 +30,11 @@ function log (...args: any[]): void {
 }
 
 process.title = 'NanoPow Server'
+const MAX_BODY_SIZE = 256
+const MAX_IDLE_TIME = 5000
 const MAX_REQUEST_COUNT = 10
-const MAX_REQUEST_TIME = 60000
 const MAX_REQUEST_SIZE = 1024
-const MAX_BODY_SIZE = 256
+const MAX_REQUEST_TIME = 60000
 
 const requests: Map<string, { tokens: number, time: number }> = new Map()
 
@@ -149,6 +150,12 @@ const server = http.createServer((req, res): void => {
        let data: Buffer[] = []
        let reqSize = 0
        if (req.method === 'POST') {
+               if (+(req.headers['content-length'] ?? 0) > MAX_BODY_SIZE) {
+                       res.writeHead(413, { 'Content-Type': 'text/plain' })
+                       res.end('Content Too Large')
+                       req.socket.destroy()
+                       return
+               }
                req.on('data', (chunk: Buffer): void => {
                        reqSize += chunk.byteLength
                        if (reqSize > MAX_REQUEST_SIZE) {
@@ -185,7 +192,14 @@ Full documentation: <https://www.npmjs.com/package/nano-pow>
        }
 })
 
-server.on('error', (e): void => {
+server.headersTimeout = MAX_IDLE_TIME
+server.keepAliveTimeout = MAX_IDLE_TIME
+
+server.on('connection', (c: Socket): void => {
+       c.setTimeout(MAX_IDLE_TIME, () => c.destroy())
+})
+
+server.on('error', (e: Error): void => {
        log('Server error', e)
        try {
                shutdown()