mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-25 06:14:59 +00:00
code: nextjs,frontends,security (3 files)
This commit is contained in:
28
dbal/cpp/src/daemon/http/security_limits.hpp
Normal file
28
dbal/cpp/src/daemon/http/security_limits.hpp
Normal file
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* @file security_limits.hpp
|
||||
* @brief Security constants and limits for HTTP server
|
||||
*
|
||||
* Defines limits to prevent CVE-style attacks.
|
||||
*/
|
||||
#ifndef DBAL_SECURITY_LIMITS_HPP
|
||||
#define DBAL_SECURITY_LIMITS_HPP
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace dbal {
|
||||
namespace daemon {
|
||||
namespace http {
|
||||
|
||||
// Security limits to prevent CVE-style attacks
|
||||
constexpr size_t MAX_REQUEST_SIZE = 65536; // 64KB max request (prevent buffer overflow)
|
||||
constexpr size_t MAX_HEADERS = 100; // Max 100 headers (prevent header bomb)
|
||||
constexpr size_t MAX_HEADER_SIZE = 8192; // 8KB max per header
|
||||
constexpr size_t MAX_PATH_LENGTH = 2048; // Max URL path length
|
||||
constexpr size_t MAX_BODY_SIZE = 10485760; // 10MB max body size
|
||||
constexpr size_t MAX_CONCURRENT_CONNECTIONS = 1000; // Prevent thread exhaustion
|
||||
|
||||
} // namespace http
|
||||
} // namespace daemon
|
||||
} // namespace dbal
|
||||
|
||||
#endif
|
||||
35
frontends/nextjs/src/app/packages/[...path]/route.ts
Normal file
35
frontends/nextjs/src/app/packages/[...path]/route.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { NextResponse } from 'next/server'
|
||||
import { readFile, stat } from 'fs/promises'
|
||||
import { getPackageContentType } from '@/lib/packages/server/get-package-content-type'
|
||||
import { resolvePackageFilePath } from '@/lib/packages/server/resolve-package-file-path'
|
||||
|
||||
interface PackageParams {
|
||||
path?: string[]
|
||||
}
|
||||
|
||||
export async function GET(request: Request, { params }: { params: PackageParams }) {
|
||||
const segments = params.path ?? []
|
||||
const filePath = resolvePackageFilePath(segments)
|
||||
|
||||
if (!filePath) {
|
||||
return NextResponse.json({ error: 'Not found' }, { status: 404 })
|
||||
}
|
||||
|
||||
try {
|
||||
const fileStat = await stat(filePath)
|
||||
if (!fileStat.isFile()) {
|
||||
return NextResponse.json({ error: 'Not found' }, { status: 404 })
|
||||
}
|
||||
|
||||
const fileBuffer = await readFile(filePath)
|
||||
const contentType = getPackageContentType(filePath)
|
||||
|
||||
return new NextResponse(fileBuffer, {
|
||||
headers: {
|
||||
'Content-Type': contentType,
|
||||
},
|
||||
})
|
||||
} catch (error) {
|
||||
return NextResponse.json({ error: 'Not found' }, { status: 404 })
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { resolvePackageFilePath } from './resolve-package-file-path'
|
||||
|
||||
const root = '/repo/packages'
|
||||
|
||||
describe('resolvePackageFilePath', () => {
|
||||
it('returns null for empty path', () => {
|
||||
expect(resolvePackageFilePath([], root)).toBeNull()
|
||||
})
|
||||
|
||||
it('returns resolved path for valid segments', () => {
|
||||
expect(resolvePackageFilePath(['social_hub', 'seed', 'metadata.json'], root)).toBe(
|
||||
'/repo/packages/social_hub/seed/metadata.json'
|
||||
)
|
||||
})
|
||||
|
||||
it('blocks path traversal', () => {
|
||||
expect(resolvePackageFilePath(['..', 'secrets.txt'], root)).toBeNull()
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user