TypeScript tRPC Security Hardening ป้องกันแฮก — คู่มือฉบับสมบูรณ์ 2026 | SiamCafe Blog

TypeScript tRPC Security Hardening ป้องกันแฮก — คู่มือฉบับสมบูรณ์ 2026 | SiamCafe Blog

แนะนำ: ความสำคัญของความปลอดภัยใน 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:

  1. Information Gathering
    • ตรวจสอบการรั่วไหลของข้อมูลผ่าน Error Messages
    • ตรวจสอบ HTTP Headers ที่เปิดเผยข้อมูล Server
    • ตรวจสอบ CORS Configuration
  2. Authentication Testing
    • ทดสอบ Brute Force Attack
    • ทดสอบ Session Fixation
    • ทดสอบ Token Theft
  3. Input Validation Testing
    • ทดสอบ Buffer Overflow
    • ทดสอบ Type Confusion
    • ทดสอบ Prototype Pollution
  4. 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:

  1. Defense in Depth – ใช้ระบบรักษาความปลอดภัยหลายชั้น
  2. Principle of Least Privilege – ให้สิทธิ์เท่าที่จำเป็นเท่านั้น
  3. Secure by Default – ตั้งค่าความปลอดภัยเป็นค่าเริ่มต้น
  4. Fail Securely – เมื่อเกิด
จัดส่งรวดเร็วส่งด่วนทั่วประเทศ
รับประกันสินค้าเคลมง่าย มีใบรับประกัน
ผ่อนชำระได้บัตรเครดิต 0% สูงสุด 10 เดือน
สะสมแต้ม รับส่วนลดส่วนลดและคะแนนสะสม

© 2026 SiamLancard — จำหน่ายการ์ดแลน อุปกรณ์ Server และเครื่องพิมพ์ใบเสร็จ

SiamLancard
Logo
Free Forex EA — XM Signal · SiamCafe Blog · SiamLancard · Siam2R · iCafeFX
iCafeForex.com - สอนเทรด Forex | SiamCafe.net
Shopping cart