

แนะนำ: ความสำคัญของความปลอดภัยใน tRPC สำหรับ TypeScript
ในยุคที่การพัฒนาแอปพลิเคชันแบบ Full-Stack ด้วย TypeScript กำลังได้รับความนิยมสูงสุด tRPC (TypeScript Remote Procedure Call) ได้กลายเป็นเครื่องมือสำคัญที่ช่วยให้นักพัฒนาสามารถสร้าง API ที่ type-safe ได้อย่างรวดเร็วและมีประสิทธิภาพ อย่างไรก็ตาม ความสะดวกสบายที่ tRPC มอบให้อาจกลายเป็นจุดอ่อนด้านความปลอดภัยหากไม่ได้รับการป้องกันอย่างเหมาะสม
บทความนี้จะพาคุณไปทำความเข้าใจเกี่ยวกับการ Hardening ความปลอดภัยของ tRPC อย่างละเอียด ครอบคลุมตั้งแต่พื้นฐานไปจนถึงเทคนิคขั้นสูงที่ใช้ในปี 2026 เราจะพูดถึงช่องโหว่ที่พบบ่อย วิธีการป้องกัน และแนวปฏิบัติที่ดีที่สุดในการรักษาความปลอดภัยให้กับแอปพลิเคชัน tRPC ของคุณ
การโจมตีทางไซเบอร์ในปัจจุบันมีความซับซ้อนมากขึ้น โดยเฉพาะการโจมตีแบบ API Abuse, Injection Attacks, และการรั่วไหลของข้อมูลผ่าน Type Inference ที่ไม่ถูกควบคุม บทความนี้จะช่วยให้คุณเข้าใจถึงความเสี่ยงเหล่านี้และวิธีการรับมืออย่างมีประสิทธิภาพ
1. พื้นฐานความปลอดภัยของ tRPC และความเสี่ยงที่พบบ่อย
1.1 tRPC ทำงานอย่างไรในมุมมองความปลอดภัย
tRPC ทำงานบนหลักการของ Remote Procedure Call ที่ใช้ HTTP/HTTPS เป็น Transport Layer โดยข้อมูลจะถูกส่งผ่าน JSON หรือ Protocol Buffers ซึ่งแตกต่างจาก REST API ทั่วไปที่ใช้ HTTP Methods และ Endpoints ในการกำหนดการทำงาน tRPC จะใช้ฟังก์ชันโดยตรงผ่าน TypeScript Compiler
ความเสี่ยงหลักที่พบใน tRPC ได้แก่:
- Type Injection – การส่งข้อมูลที่ไม่ตรงตาม Type ที่กำหนดไว้
- Authorization Bypass – การข้ามขั้นตอนการตรวจสอบสิทธิ์ผ่าน Middleware
- Information Leakage – การรั่วไหลของข้อมูลผ่าน Error Messages
- Rate Limiting Bypass – การหลีกเลี่ยงการจำกัดจำนวนคำขอ
- Input Validation Bypass – การส่งข้อมูลที่ผิดรูปแบบผ่าน Type System
1.2 การตั้งค่า tRPC พื้นฐานที่ปลอดภัย
ก่อนอื่น เรามาเริ่มต้นด้วยการตั้งค่า tRPC Server ที่มีความปลอดภัยขั้นพื้นฐาน:
// server.ts - การตั้งค่า tRPC Server เบื้องต้น
import { initTRPC } from '@trpc/server';
import { createHTTPServer } from '@trpc/server/adapters/standalone';
import { z } from 'zod';
import superjson from 'superjson';
// 1. กำหนด Context ที่มีข้อมูลผู้ใช้
export const createContext = async ({ req }: { req: Request }) => {
const token = req.headers.get('authorization')?.replace('Bearer ', '');
// ตรวจสอบและ decode token
const user = await verifyToken(token);
return {
user,
// เพิ่ม Request ID สำหรับการติดตาม
requestId: crypto.randomUUID(),
};
};
// 2. ตั้งค่า tRPC ด้วย Transformer ที่ปลอดภัย
const t = initTRPC.context<typeof createContext>().create({
transformer: superjson,
// จำกัดขนาดของ Request
maxRequestBodySize: 1024 * 1024, // 1MB
// ปิดการส่ง Error Stack Trace ไปยัง Client
isDev: process.env.NODE_ENV === 'development',
errorFormatter: (shape) => {
// ซ่อนรายละเอียดของ Error ใน Production
if (process.env.NODE_ENV === 'production') {
return {
code: shape.code,
message: 'An error occurred',
};
}
return shape;
},
});
// 3. Middleware สำหรับตรวจสอบ Authentication
const isAuthenticated = t.middleware(async ({ ctx, next }) => {
if (!ctx.user) {
throw new TRPCError({
code: 'UNAUTHORIZED',
message: 'You must be logged in',
});
}
return next({
ctx: {
...ctx,
user: ctx.user,
},
});
});
// 4. Export Procedures ที่ผ่านการตรวจสอบ
export const publicProcedure = t.procedure;
export const protectedProcedure = t.procedure.use(isAuthenticated);
export const router = t.router;
2. การป้องกัน Input Validation และ Type Safety
2.1 Zod Validation ที่ครอบคลุม
Zod เป็นเครื่องมือสำคัญในการตรวจสอบ Input ใน tRPC การใช้ Zod อย่างถูกต้องสามารถป้องกันการโจมตีหลายรูปแบบได้:
// schemas/user.schema.ts - การกำหนด Schema ที่ปลอดภัย
import { z } from 'zod';
// จำกัดความยาวของ String เพื่อป้องกัน Buffer Overflow
export const usernameSchema = z
.string()
.min(3, 'Username must be at least 3 characters')
.max(50, 'Username must not exceed 50 characters')
.regex(/^[a-zA-Z0-9_]+$/, 'Username can only contain letters, numbers, and underscores');
// ป้องกัน XSS และ HTML Injection
export const displayNameSchema = z
.string()
.min(1)
.max(100)
.transform((val) => sanitizeHtml(val));
// ตรวจสอบ Email Format และป้องกัน Injection
export const emailSchema = z
.string()
.email('Invalid email format')
.max(254, 'Email too long')
.transform((val) => val.toLowerCase().trim());
// จำกัดค่า Enum เพื่อป้องกันการส่งค่าที่ไม่ถูกต้อง
export const userRoleSchema = z.enum(['admin', 'user', 'moderator']);
// Complex Schema สำหรับการสร้างผู้ใช้
export const createUserSchema = z.object({
username: usernameSchema,
email: emailSchema,
password: z
.string()
.min(8, 'Password must be at least 8 characters')
.max(128, 'Password too long')
.regex(
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/,
'Password must contain uppercase, lowercase, number and special character'
),
role: userRoleSchema.default('user'),
}).strict(); // ป้องกันการส่ง Field ที่ไม่จำเป็น
// Schema สำหรับ Pagination ที่ป้องกัน DoS
export const paginationSchema = z.object({
page: z.coerce.number().int().positive().max(1000).default(1),
limit: z.coerce.number().int().positive().max(100).default(20),
cursor: z.string().optional(),
});
2.2 การป้องกัน Type Inference Attack
Type Inference ใน tRPC อาจทำให้เกิดช่องโหว่หากไม่ได้รับการจัดการอย่างถูกต้อง:
| ช่องโหว่ | ผลกระทบ | วิธีการป้องกัน |
|---|---|---|
| Type Leakage | ผู้โจมตีสามารถเห็นโครงสร้างข้อมูลภายใน | ใช้ Output Validation และ Transform |
| Infinite Recursion | TypeScript Compiler หยุดทำงาน | จำกัดความลึกของ Type |
| Type Confusion | ข้อมูลถูกตีความผิดประเภท | ใช้ Discriminated Union และ Branded Types |
| Template Literal Injection | SQL/NoSQL Injection ผ่าน Template Literals | Sanitize Input ก่อนใช้งาน |
3. การจัดการ Authentication และ Authorization
3.1 Multi-Layer Authentication
การใช้ Authentication หลายชั้นช่วยเพิ่มความปลอดภัยให้กับระบบ tRPC ของคุณ:
// middleware/auth.middleware.ts - ระบบ Authentication หลายชั้น
import { TRPCError } from '@trpc/server';
import jwt from 'jsonwebtoken';
import { RateLimiter } from 'limiter';
// Layer 1: Token Validation
const validateToken = async (token: string) => {
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET!, {
algorithms: ['HS256'], // ระบุ Algorithm ที่อนุญาต
issuer: 'siamcafe-blog',
audience: 'siamcafe-api',
});
return decoded;
} catch (error) {
throw new TRPCError({
code: 'UNAUTHORIZED',
message: 'Invalid or expired token',
});
}
};
// Layer 2: Session Validation
const validateSession = async (userId: string, sessionId: string) => {
const session = await redis.get(`session:${userId}:${sessionId}`);
if (!session) {
throw new TRPCError({
code: 'UNAUTHORIZED',
message: 'Session expired',
});
}
return JSON.parse(session);
};
// Layer 3: Permission Check
const checkPermissions = (requiredRoles: string[]) => {
return t.middleware(async ({ ctx, next }) => {
const userRole = ctx.user?.role;
if (!userRole || !requiredRoles.includes(userRole)) {
throw new TRPCError({
code: 'FORBIDDEN',
message: 'Insufficient permissions',
});
}
return next({ ctx });
});
};
// Layer 4: Rate Limiting per User
const rateLimiter = new RateLimiter({
tokensPerInterval: 10,
interval: 'second',
});
const rateLimitMiddleware = t.middleware(async ({ ctx, next }) => {
const userId = ctx.user?.id || 'anonymous';
const remaining = await rateLimiter.removeTokens(1, userId);
if (remaining < 0) {
throw new TRPCError({
code: 'TOO_MANY_REQUESTS',
message: 'Rate limit exceeded',
});
}
return next({ ctx });
});
// รวม Middleware ทั้งหมด
export const superSecureProcedure = t.procedure
.use(rateLimitMiddleware)
.use(isAuthenticated)
.use(checkPermissions(['admin', 'moderator']));
3.2 การจัดการ Session และ Token อย่างปลอดภัย
การจัดการ Session และ Token ที่ปลอดภัยเป็นสิ่งสำคัญในการป้องกันการโจมตีแบบ Session Hijacking และ Token Theft:
- ใช้ Short-Lived Access Tokens – ตั้งค่า Token ให้หมดอายุในเวลาสั้น (15-30 นาที)
- Refresh Token Rotation – เปลี่ยน Refresh Token ทุกครั้งที่มีการใช้งาน
- Device Fingerprinting – ตรวจสอบ Device ที่ใช้ในการ Login
- Session Invalidation – ยกเลิก Session ทั้งหมดเมื่อมีการเปลี่ยน Password
- IP Address Validation – ตรวจสอบ IP Address ที่เปลี่ยนแปลงผิดปกติ
4. การป้องกันการโจมตีขั้นสูง
4.1 การป้องกัน GraphQL-like Query Complexity Attack
tRPC อาจถูกโจมตีด้วยการส่ง Query ที่ซับซ้อนเกินไป ซึ่งทำให้ Server ทำงานหนัก:
// middleware/query-complexity.middleware.ts
import { TRPCError } from '@trpc/server';
// กำหนดความซับซ้อนของแต่ละ Field
const fieldComplexity: Record<string, number> = {
'user': 1,
'users': 5,
'posts': 3,
'comments': 2,
'analytics': 10,
};
// Middleware สำหรับตรวจสอบ Query Complexity
const queryComplexityMiddleware = t.middleware(async ({ ctx, next, path }) => {
// วิเคราะห์ความซับซ้อนของ Query
const complexity = calculateComplexity(path, ctx.input);
// จำกัดความซับซ้อนสูงสุด
if (complexity > 100) {
throw new TRPCError({
code: 'PAYLOAD_TOO_LARGE',
message: 'Query too complex',
});
}
return next({ ctx });
});
// Middleware สำหรับป้องกัน N+1 Query Problem
const batchQueryMiddleware = t.middleware(async ({ ctx, next }) => {
// ใช้ DataLoader สำหรับ Batch Queries
const loaders = createDataLoaders(ctx.user);
return next({
ctx: {
...ctx,
loaders,
},
});
});
4.2 การป้องกัน Timing Attacks
Timing Attacks เป็นการโจมตีที่อาศัยเวลาตอบสนองของ Server เพื่อเดาข้อมูล:
// utils/constant-time.ts - การเปรียบเทียบแบบ Constant Time
import { timingSafeEqual } from 'crypto';
export async function constantTimeCompare(a: string, b: string): Promise<boolean> {
// แปลง String เป็น Buffer
const bufA = Buffer.from(a, 'utf8');
const bufB = Buffer.from(b, 'utf8');
// ใช้ timingSafeEqual เพื่อป้องกัน Timing Attack
if (bufA.length !== bufB.length) {
// ทำให้เวลาตอบสนองเท่ากัน
await sleep(100);
return false;
}
return timingSafeEqual(bufA, bufB);
}
// ใช้ใน Middleware
const timingSafeMiddleware = t.middleware(async ({ ctx, next }) => {
const startTime = process.hrtime.bigint();
const result = await next({ ctx });
const endTime = process.hrtime.bigint();
const duration = Number(endTime - startTime) / 1_000_000; // ms
// ทำให้เวลาตอบสนองคงที่
const targetDuration = 50; // 50ms
if (duration < targetDuration) {
await sleep(targetDuration - duration);
}
return result;
});
4.3 การป้องกัน Server-Side Request Forgery (SSRF)
SSRF เป็นการโจมตีที่ผู้โจมตีใช้ Server ของคุณในการส่ง Request ไปยัง Internal Services:
| ประเภท SSRF | ตัวอย่าง | การป้องกัน |
|---|---|---|
| Basic SSRF | http://localhost:3000/admin | Block Private IP Ranges |
| DNS Rebinding | http://attacker.com (ชี้ไปที่ Internal IP) | Validate DNS Resolution |
| Protocol Smuggling | file:///etc/passwd | Whitelist Allowed Protocols |
| Blind SSRF | Error Messages ที่เปิดเผยข้อมูล | Generic Error Messages |
// utils/ssrf-protection.ts
import { URL } from 'url';
import { isIP } from 'net';
const BLOCKED_IP_RANGES = [
'10.0.0.0/8',
'172.16.0.0/12',
'192.168.0.0/16',
'127.0.0.0/8',
'169.254.0.0/16',
'::1/128',
'fc00::/7',
'fe80::/10',
];
const ALLOWED_PROTOCOLS = ['https:', 'http:'];
export function validateExternalUrl(url: string): boolean {
try {
const parsedUrl = new URL(url);
// ตรวจสอบ Protocol
if (!ALLOWED_PROTOCOLS.includes(parsedUrl.protocol)) {
return false;
}
// ตรวจสอบ IP Address
const hostname = parsedUrl.hostname;
if (isIP(hostname)) {
if (isPrivateIP(hostname)) {
return false;
}
} else {
// DNS Resolution Check
const resolvedIP = dnsResolve(hostname);
if (resolvedIP && isPrivateIP(resolvedIP)) {
return false;
}
}
// ตรวจสอบ Port
const port = parseInt(parsedUrl.port) || 443;
if (port < 1024 && ![80, 443].includes(port)) {
return false;
}
return true;
} catch {
return false;
}
}
5. การจัดการ Logging และ Monitoring
5.1 Secure Logging Practices
การ Logging ที่ปลอดภัยจะช่วยให้คุณตรวจจับและตอบสนองต่อการโจมตีได้อย่างรวดเร็ว:
// middleware/secure-logging.middleware.ts
import { createLogger, format, transports } from 'winston';
import { v4 as uuidv4 } from 'uuid';
// สร้าง Logger ที่ปลอดภัย
const logger = createLogger({
level: process.env.LOG_LEVEL || 'info',
format: format.combine(
format.timestamp(),
format.json()
),
defaultMeta: { service: 'siamcafe-api' },
transports: [
new transports.File({
filename: 'logs/error.log',
level: 'error',
maxsize: 5242880, // 5MB
maxFiles: 5,
}),
new transports.File({
filename: 'logs/combined.log',
maxsize: 5242880,
maxFiles: 5,
}),
],
});
// ใน Production ไม่ให้ Log ไป Console
if (process.env.NODE_ENV !== 'production') {
logger.add(new transports.Console({
format: format.combine(
format.colorize(),
format.simple()
),
}));
}
// Middleware สำหรับ Secure Logging
const secureLoggingMiddleware = t.middleware(async ({ ctx, next, path, input }) => {
const requestId = uuidv4();
const startTime = Date.now();
// ลบข้อมูลที่ sensitive ออกจาก Log
const sanitizedInput = sanitizeForLogging(input);
logger.info('API Request', {
requestId,
path,
userId: ctx.user?.id || 'anonymous',
input: sanitizedInput,
ip: ctx.req?.headers['x-forwarded-for'] || ctx.req?.socket?.remoteAddress,
userAgent: ctx.req?.headers['user-agent'],
});
try {
const result = await next({ ctx });
const duration = Date.now() - startTime;
logger.info('API Response', {
requestId,
path,
duration,
status: 'success',
});
return result;
} catch (error) {
const duration = Date.now() - startTime;
// Log Error แต่ไม่เปิดเผย Stack Trace
logger.error('API Error', {
requestId,
path,
duration,
errorCode: error.code,
errorMessage: error.message,
userId: ctx.user?.id,
});
throw error;
}
});
// ฟังก์ชันสำหรับ Sanitize ข้อมูลก่อน Log
function sanitizeForLogging(input: any): any {
if (typeof input === 'object' && input !== null) {
const sanitized: any = {};
for (const [key, value] of Object.entries(input)) {
// ซ่อนข้อมูลที่ sensitive
if (['password', 'token', 'secret', 'key', 'authorization'].includes(key.toLowerCase())) {
sanitized[key] = '***REDACTED***';
} else if (typeof value === 'object') {
sanitized[key] = sanitizeForLogging(value);
} else {
sanitized[key] = value;
}
}
return sanitized;
}
return input;
}
5.2 Real-time Monitoring และ Alerting
การ Monitoring แบบ Real-time ช่วยให้คุณตรวจจับและตอบสนองต่อภัยคุกคามได้ทันที:
- Anomaly Detection – ตรวจจับพฤติกรรมที่ผิดปกติ เช่น การเรียก API ที่ไม่เคยมีมาก่อน
- Rate Limiting Alerts – แจ้งเตือนเมื่อมี Rate Limiting เกิดขึ้นบ่อยครั้ง
- Error Rate Monitoring – ติดตามอัตราการเกิด Error ที่สูงผิดปกติ
- Suspicious Pattern Detection – ตรวจจับรูปแบบการโจมตีที่รู้จัก
- Performance Metrics – ติดตาม Performance ที่ผิดปกติ เช่น Response Time ที่ช้าลง
6. การ Deploy และ Infrastructure Security
6.1 Secure Deployment Practices
การ Deploy tRPC Application อย่างปลอดภัยต้องคำนึงถึงหลายปัจจัย:
// deployment/security-check.ts
import { exec } from 'child_process';
import { promisify } from 'util';
const execAsync = promisify(exec);
async function performSecurityChecks(): Promise<boolean> {
const checks = [
// 1. ตรวจสอบ Dependency Vulnerabilities
checkDependencies(),
// 2. ตรวจสอบ Environment Variables
checkEnvironmentVariables(),
// 3. ตรวจสอบ SSL/TLS Configuration
checkSSLConfiguration(),
// 4. ตรวจสอบ CORS Configuration
checkCORSConfiguration(),
// 5. ตรวจสอบ Rate Limiting Configuration
checkRateLimiting(),
];
const results = await Promise.all(checks);
return results.every(result => result);
}
async function checkDependencies(): Promise<boolean> {
try {
const { stdout } = await execAsync('npm audit --json');
const audit = JSON.parse(stdout);
if (audit.metadata.vulnerabilities.high > 0 ||
audit.metadata.vulnerabilities.critical > 0) {
console.error('High or Critical vulnerabilities found!');
return false;
}
return true;
} catch (error) {
console.error('Failed to check dependencies:', error);
return false;
}
}
// Dockerfile ที่ปลอดภัย
const dockerfile = `
FROM node:20-alpine AS builder
# 1. ใช้ Non-Root User
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nodejs -u 1001
WORKDIR /app
# 2. คัดลอกเฉพาะไฟล์ที่จำเป็น
COPY package*.json ./
COPY tsconfig*.json ./
COPY src/ ./src/
# 3. ติดตั้ง Dependencies และ Build
RUN npm ci --only=production
RUN npm run build
# 4. Production Image
FROM node:20-alpine
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nodejs -u 1001
WORKDIR /app
# 5. คัดลอกเฉพาะไฟล์ที่จำเป็นสำหรับ Production
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./
# 6. ตั้งค่า Security Options
RUN chown -R nodejs:nodejs /app
USER nodejs
# 7. ใช้ Read-Only Filesystem
ENV NODE_ENV=production
EXPOSE 3000
CMD ["node", "dist/server.js"]
`;
6.2 การใช้ API Gateway และ WAF
การใช้ API Gateway และ Web Application Firewall (WAF) ช่วยเพิ่ม Layer ความปลอดภัยอีกชั้น:
| คุณสมบัติ | API Gateway | WAF | ประโยชน์ |
|---|---|---|---|
| Rate Limiting | ✅ | ✅ | ป้องกัน DoS/DDoS |
| IP Filtering | ✅ | ✅ | บล็อก IP ที่น่าสงสัย |
| SQL Injection Prevention | ❌ | ✅ | ตรวจจับและบล็อก Injection |
| XSS Protection | ❌ | ✅ | ป้องกัน Cross-Site Scripting |
| Request Validation | ✅ | ✅ | ตรวจสอบ Format Request |
| SSL Termination | ✅ | ❌ | จัดการ SSL Certificate |
| Load Balancing | ✅ | ❌ | กระจาย Traffic |
7. การทดสอบความปลอดภัย (Security Testing)
7.1 Automated Security Testing
การทดสอบความปลอดภัยแบบอัตโนมัติช่วยให้คุณค้นหาช่องโหว่ได้ก่อนที่จะถูกโจมตี:
// tests/security.test.ts
import { describe, it, expect } from 'vitest';
import { appRouter } from '../src/router';
import { createContext } from '../src/context';
describe('tRPC Security Tests', () => {
// 1. Input Validation Tests
describe('Input Validation', () => {
it('should reject SQL injection attempts', async () => {
const ctx = await createContext({ req: {} as any });
const caller = appRouter.createCaller(ctx);
await expect(
caller.user.create({
username: "' OR 1=1 --",
email: "[email protected]",
password: "Test1234!@",
})
).rejects.toThrow('Username can only contain letters, numbers, and underscores');
});
it('should reject XSS attempts', async () => {
const ctx = await createContext({ req: {} as any });
const caller = appRouter.createCaller(ctx);
await expect(
caller.user.create({
username: "testuser",
email: "<script>alert('xss')</script>@test.com",
password: "Test1234!@",
})
).rejects.toThrow('Invalid email format');
});
it('should reject oversized payloads', async () => {
const ctx = await createContext({ req: {} as any });
const caller = appRouter.createCaller(ctx);
const largeData = 'x'.repeat(1000000);
await expect(
caller.post.create({
title: largeData,
content: "test content",
})
).rejects.toThrow();
});
});
// 2. Authorization Tests
describe('Authorization', () => {
it('should reject unauthorized access', async () => {
const ctx = await createContext({ req: {} as any });
const caller = appRouter.createCaller(ctx);
await expect(
caller.admin.deleteUser({ userId: 1 })
).rejects.toThrow('You must be logged in');
});
it('should enforce role-based access', async () => {
const userContext = await createContext({
req: {
headers: {
authorization: 'Bearer user_token',
},
} as any,
});
const caller = appRouter.createCaller(userContext);
await expect(
caller.admin.manageSystem()
).rejects.toThrow('Insufficient permissions');
});
});
// 3. Rate Limiting Tests
describe('Rate Limiting', () => {
it('should enforce rate limits', async () => {
const ctx = await createContext({ req: {} as any });
const caller = appRouter.createCaller(ctx);
// ส่ง Request จำนวนมาก
const requests = Array(100).fill(null).map(() =>
caller.public.healthCheck()
);
const results = await Promise.allSettled(requests);
const rejected = results.filter(r => r.status === 'rejected');
expect(rejected.length).toBeGreaterThan(0);
});
});
});
7.2 Penetration Testing Checklist
รายการตรวจสอบสำหรับการ Penetration Testing tRPC Application:
- Information Gathering
- ตรวจสอบการรั่วไหลของข้อมูลผ่าน Error Messages
- ตรวจสอบ HTTP Headers ที่เปิดเผยข้อมูล Server
- ตรวจสอบ CORS Configuration
- Authentication Testing
- ทดสอบ Brute Force Attack
- ทดสอบ Session Fixation
- ทดสอบ Token Theft
- Input Validation Testing
- ทดสอบ Buffer Overflow
- ทดสอบ Type Confusion
- ทดสอบ Prototype Pollution
- Business Logic Testing
- ทดสอบ IDOR (Insecure Direct Object Reference)
- ทดสอบ Mass Assignment
- ทดสอบ Race Condition
8. Best Practices และ Real-World Use Cases
8.1 กรณีศึกษา: การป้องกันการโจมตีในระบบ E-Commerce
ระบบ E-Commerce ขนาดใหญ่ที่ใช้ tRPC ต้องรับมือกับการโจมตีหลายรูปแบบ:
- Price Manipulation – ป้องกันด้วย Server-Side Validation และ Signed Prices
- Inventory Abuse – ใช้ Distributed Locks และ Queue System
- Coupon Fraud – ตรวจสอบ Coupon Usage Rate และ Limit Per User
- Review Spam – ใช้ Machine Learning Detection และ CAPTCHA
8.2 กรณีศึกษา: ระบบ Healthcare API
ระบบ Healthcare ที่ต้องปฏิบัติตาม HIPAA และ PDPA มีข้อกำหนดความปลอดภัยที่เข้มงวด:
// healthcare/audit-trail.ts
import { TRPCError } from '@trpc/server';
// Audit Trail Middleware สำหรับ Healthcare
const auditTrailMiddleware = t.middleware(async ({ ctx, next, path, input }) => {
// บันทึกทุกการเข้าถึงข้อมูลผู้ป่วย
const auditEntry = {
userId: ctx.user?.id,
action: path,
patientId: input?.patientId,
timestamp: new Date().toISOString(),
ipAddress: ctx.req?.headers['x-forwarded-for'],
userAgent: ctx.req?.headers['user-agent'],
accessType: 'read',
dataAccessed: sanitizeForAudit(input),
};
// บันทึก Audit Log ในระบบที่ปลอดภัย
await saveAuditEntry(auditEntry);
// ตรวจสอบการเข้าถึงที่ผิดปกติ
if (await detectAnomalousAccess(auditEntry)) {
// แจ้งเตือน Security Team
await notifySecurityTeam(auditEntry);
// บล็อกการเข้าถึงหากผิดปกติรุนแรง
throw new TRPCError({
code: 'FORBIDDEN',
message: 'Access denied due to security policy',
});
}
return next({ ctx });
});
// Data Encryption Middleware
const encryptionMiddleware = t.middleware(async ({ ctx, next }) => {
const result = await next({ ctx });
// เข้ารหัสข้อมูลที่ sensitive ก่อนส่งกลับ
if (result.data?.patientInfo) {
result.data.patientInfo = encryptPatientData(result.data.patientInfo);
}
return result;
});
8.3 Best Practices สรุป
แนวปฏิบัติที่ดีที่สุดสำหรับการรักษาความปลอดภัย tRPC Application:
- Defense in Depth – ใช้ระบบรักษาความปลอดภัยหลายชั้น
- Principle of Least Privilege – ให้สิทธิ์เท่าที่จำเป็นเท่านั้น
- Secure by Default – ตั้งค่าความปลอดภัยเป็นค่าเริ่มต้น
- Fail Securely – เมื่อเกิด