ความปลอดภัยและการยืนยันตัวตนของ MCP
เพิ่มการยืนยันตัวตนให้เซิร์ฟเวอร์ MCP ด้วยโทเค็น OAuth 2.0 ตรวจสอบข้อมูลนำเข้าเพื่อป้องกันการโจมตีแบบฉีดคำสั่ง และใช้หลักสิทธิ์เท่าที่จำเป็นกับสิทธิ์ของเครื่องมือ
ความปลอดภัยและการยืนยันตัวตนของ MCP เป็นบทเรียน AI Engineering Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน AI Engineering Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส AI Engineering Academy มีบทเรียนทั้งหมด 4 บทเรียน
เหตุผลที่ความปลอดภัยของ MCP สำคัญ
เซิร์ฟเวอร์ MCP คือประตูเข้าสู่ระบบต่าง ๆ ของคุณ หากไม่มีการรักษาความปลอดภัยที่เหมาะสม ไคลเอ็นต์ AI ที่ถูกบุกรุกหรือ Prompt ที่เป็นอันตรายอาจอ่านข้อมูลละเอียดอ่อน เรียกใช้การดำเนินการที่ทำลายข้อมูล หรือดึงข้อมูลออกผ่านช่องทางการเรียกใช้เครื่องมือได้ ความปลอดภัยสำหรับเซิร์ฟเวอร์ MCP ต้องใช้ การป้องกันเชิงลึกหลายชั้น ได้แก่ การตรวจสอบสิทธิ์ที่ชั้นการส่งข้อมูล การอนุญาตที่ระดับเครื่องมือ และการตรวจสอบข้อมูลนำเข้าในการเรียกใช้ทุกครั้ง
ความปลอดภัยของเซิร์ฟเวอร์ภายในเครื่องเทียบกับเซิร์ฟเวอร์ระยะไกล
การส่งข้อมูลผ่าน stdio ซึ่ง Claude Desktop ใช้ มีความปลอดภัยในตัว: เซิร์ฟเวอร์ทำงานเป็นโพรเซสภายในเครื่องและเข้าถึงได้เฉพาะผู้ใช้ที่เริ่มการทำงาน เครือข่ายที่เปิดเผยเซิร์ฟเวอร์ MCP ซึ่งใช้ HTTP/SSE ต้องเผชิญกับภัยคุกคามด้านความปลอดภัยบนเว็บอย่างเต็มรูปแบบ เช่น การข้ามการตรวจสอบสิทธิ์ การโจมตีแบบแทรกคำสั่ง และการเข้าถึงโดยไม่ได้รับอนุญาต ข้อกำหนดด้านความปลอดภัยจะแตกต่างกันอย่างมากตามรูปแบบการนำไปใช้งาน
- stdio ภายในเครื่อง: เชื่อถือผู้ใช้ภายในเครื่อง และมุ่งเน้นการตรวจสอบข้อมูลนำเข้า
- HTTP/SSE ระยะไกล: ใช้การตรวจสอบสิทธิ์ TLS การจำกัดอัตราการเรียกใช้ และการทำความสะอาดข้อมูลนำเข้าอย่างครบถ้วน
การตรวจสอบสิทธิ์ด้วยคีย์ API สำหรับเซิร์ฟเวอร์ระยะไกล
วิธีตรวจสอบสิทธิ์ที่ง่ายที่สุดสำหรับเซิร์ฟเวอร์ MCP ระยะไกลคือการตรวจสอบคีย์ API ผ่านส่วนหัว HTTP ตรวจสอบส่วนหัว Authorization: Bearer <token> ในคำขอขาเข้าทุกครั้ง และปฏิเสธคำขอที่ไม่ได้ผ่านการตรวจสอบสิทธิ์ด้วย HTTP 401 เก็บคีย์ API ที่ใช้ได้ไว้ในฐานข้อมูลพร้อมข้อมูลเมตาของผู้ใช้ เพื่อให้คุณเพิกถอนคีย์แต่ละรายการได้
# For HTTP/SSE MCP servers using FastAPI or similar:
from fastapi import FastAPI, HTTPException, Depends, Header
from typing import Optional
import secrets
app_http = FastAPI()
# In production: store in database with user_id, created_at, last_used
VALID_KEYS = {'sk-mcp-abc123': {'user': 'alice', 'scopes': ['read']},
'sk-mcp-def456': {'user': 'bob', 'scopes': ['read', 'write']}}
async def verify_api_key(authorization: Optional[str] = Header(None)) -> dict:
if not authorization or not authorization.startswith('Bearer '):
raise HTTPException(status_code=401, detail='Missing API key')
key = authorization.removeprefix('Bearer ')
if key not in VALID_KEYS:
raise HTTPException(status_code=401, detail='Invalid API key')
return VALID_KEYS[key] # Returns user context
# Use in route handlers:
# @app_http.get('/sse')
# async def sse_endpoint(user=Depends(verify_api_key)):OAuth 2.0 สำหรับเซิร์ฟเวอร์ MCP ระดับองค์กร
สำหรับการนำไปใช้งานในองค์กร ให้ใช้ OAuth 2.0 เพื่อให้ผู้ใช้ตรวจสอบสิทธิ์ด้วยผู้ให้บริการข้อมูลประจำตัวขององค์กร เช่น Okta, Azure AD และ Google Workspace ไคลเอ็นต์ MCP จะรับโทเค็นการเข้าถึง OAuth แล้วใส่โทเค็นนี้ในคำขอเรียกใช้เครื่องมือ เซิร์ฟเวอร์ของคุณจะตรวจสอบลายเซ็นโทเค็นกับคีย์สาธารณะของผู้ให้บริการข้อมูลประจำตัวโดยใช้ python-jose หรือ authlib
from jose import jwt, JWTError
import httpx
AUTH_DOMAIN = 'your-tenant.auth0.com'
AUDIENCE = 'https://api.your-mcp-server.com'
async def get_jwks():
async with httpx.AsyncClient() as client:
resp = await client.get(f'https://{AUTH_DOMAIN}/.well-known/jwks.json')
return resp.json()
async def verify_oauth_token(token: str) -> dict:
jwks = await get_jwks()
try:
payload = jwt.decode(
token,
jwks,
algorithms=['RS256'],
audience=AUDIENCE,
issuer=f'https://{AUTH_DOMAIN}/'
)
return payload # Contains sub (user ID), scope, exp, etc.
except JWTError as e:
raise ValueError(f'Invalid token: {e}')การอนุญาตตามขอบเขต
ไม่ควรให้ผู้ใช้ทุกคนใช้เครื่องมือ MCP ได้ทั้งหมด ใช้ ขอบเขต OAuth หรือข้อมูลบทบาทในโทเค็น JWT เพื่อกำหนดว่าเครื่องมือใดที่ผู้ใช้ซึ่งผ่านการตรวจสอบสิทธิ์แล้วสามารถเรียกใช้ได้ ตรวจสอบการอนุญาตตั้งแต่เริ่มต้นการเรียกใช้เครื่องมือทุกครั้ง ก่อนดำเนินการเรียกฐานข้อมูลหรือ API ใด ๆ
TOOL_REQUIRED_SCOPES = {
'list_products': ['read:products'],
'search_products': ['read:products'],
'create_order': ['write:orders'],
'delete_order': ['admin:orders']
}
def check_authorization(tool_name: str, token_payload: dict):
'''Raise ValueError if user lacks required scope for the tool.'''
required = TOOL_REQUIRED_SCOPES.get(tool_name, [])
if not required:
return # No scope required
user_scopes = set(token_payload.get('scope', '').split())
missing = [s for s in required if s not in user_scopes]
if missing:
raise ValueError(
f'Access denied. Tool "{tool_name}" requires scopes: {missing}. '
f'Your token has: {list(user_scopes)}'
)
# In call_tool handler:
# check_authorization(name, current_user_token)
# ... then execute the toolการตรวจสอบข้อมูลนำเข้าและการป้องกันการแทรกคำสั่ง
ข้อมูลนำเข้าของเครื่องมือทั้งหมดท้ายที่สุดแล้วเป็นสตริงที่สร้างโดย LLM ให้ถือว่าข้อมูลเหล่านี้ไม่น่าเชื่อถือ ตรวจสอบข้อมูลนำเข้าทุกค่ากับชนิดและรูปแบบที่คาดไว้ก่อนใช้งาน โดยเฉพาะอย่างยิ่ง ให้ป้องกัน SQL injection ด้วยการใช้คำค้นแบบมีพารามิเตอร์และไม่ใช้ SQL ที่แทรกสตริงโดยตรง ป้องกัน command injection โดยไม่ส่งข้อมูลนำเข้าของผู้ใช้ไปยังคำสั่งเชลล์ และป้องกัน path traversal ด้วยการปรับรูปแบบและตรวจสอบเส้นทางไฟล์
import re
from pathlib import Path
BASE_DATA_DIR = Path('/data/mcp-files')
def safe_file_path(user_input: str) -> Path:
'''Validate and normalize a file path to prevent traversal attacks.'''
# Remove any path traversal sequences
clean = re.sub(r'\.\./', '', user_input)
clean = re.sub(r'\.\.\\\\', '', clean)
path = (BASE_DATA_DIR / clean).resolve()
# Ensure the resolved path is still within the allowed base directory
if not str(path).startswith(str(BASE_DATA_DIR)):
raise ValueError(f'Path traversal detected: {user_input}')
return path
def safe_identifier(value: str) -> str:
'''Validate a database identifier (table/column name).'''
if not re.match(r'^[a-z_][a-z0-9_]{0,63}$', value, re.IGNORECASE):
raise ValueError(f'Invalid identifier: {value}')
return valueการจำกัดอัตราการเรียกใช้เครื่องมือ
เอเจนต์ LLM ที่ทำงานเป็นลูปอาจเรียกใช้เครื่องมือที่มีค่าใช้จ่ายสูงหลายร้อยครั้งต่อนาที จนทำให้การเชื่อมต่อฐานข้อมูล โควตา API ของบุคคลที่สาม หรืองบประมาณการประมวลผลหมดลง ใช้การจำกัดอัตราการเรียกใช้แยกตามผู้ใช้ด้วยอัลกอริทึมถังโทเค็นใน Redis ปฏิเสธการเรียกใช้เครื่องมือที่เกินขีดจำกัดพร้อมข้อผิดพลาดที่อธิบายชัดเจน เพื่อให้เอเจนต์ทราบว่าควรรอ
import redis
import time
r = redis.Redis.from_url('redis://localhost:6379')
def check_rate_limit(user_id: str, tool_name: str, limit: int = 60, window: int = 60) -> None:
'''Allow at most `limit` calls per `window` seconds per user per tool.'''
key = f'rate:{user_id}:{tool_name}'
pipe = r.pipeline()
pipe.incr(key)
pipe.expire(key, window)
count, _ = pipe.execute()
if count > limit:
retry_after = r.ttl(key)
raise ValueError(
f'Rate limit exceeded for {tool_name}. '
f'Limit: {limit} calls/{window}s. '
f'Retry after {retry_after} seconds.'
)หลักการให้สิทธิ์เท่าที่จำเป็น
ใช้ หลักการให้สิทธิ์เท่าที่จำเป็น ในทุกชั้นของเซิร์ฟเวอร์ MCP ผู้ใช้ฐานข้อมูลควรมีสิทธิ์ SELECT เท่านั้นสำหรับตารางที่เซิร์ฟเวอร์ต้องใช้ โพรเซสเซิร์ฟเวอร์ควรทำงานในฐานะผู้ใช้ OS ที่ไม่ใช่ root เครื่องมือควรขอเฉพาะสิทธิ์ที่จำเป็น คีย์ API ควรมีขอบเขตต่ำที่สุดตามวัตถุประสงค์ ทุกสิทธิ์ที่คุณไม่มอบให้คือการโจมตีที่อาจเกิดขึ้นและไม่สามารถประสบความสำเร็จได้
-- PostgreSQL: Create a dedicated read-only database user for your MCP server
CREATE ROLE mcp_reader LOGIN PASSWORD 'strong_random_password';
-- Grant SELECT on only the tables the server needs
GRANT SELECT ON products, categories, public_content TO mcp_reader;
-- Explicitly deny access to sensitive tables
REVOKE ALL ON users, api_keys, payment_methods FROM mcp_reader;
-- Never grant: INSERT, UPDATE, DELETE, TRUNCATE, or DDL permissionsTLS และความปลอดภัยของการส่งข้อมูล
เซิร์ฟเวอร์ MCP ระยะไกลต้องใช้ TLS เพื่อปกป้องข้อมูลระหว่างการส่งข้อมูล กำหนดค่าเซิร์ฟเวอร์ให้ยอมรับเฉพาะการเชื่อมต่อ HTTPS ในระบบจริง ให้ใช้พร็อกซีย้อนกลับ เช่น nginx หรือ Caddy เพื่อจัดการการสิ้นสุด TLS และอัปเดตใบรับรองให้เป็นปัจจุบันด้วยการต่ออายุอัตโนมัติ เช่น Let's Encrypt ผ่าน Certbot หรือการรองรับ ACME ในตัวของ Caddy
# Example Caddyfile for TLS-terminating MCP server at a subdomain:
#
# mcp.yourcompany.com {
# reverse_proxy localhost:8080
# encode gzip
# tls internal # Use Let's Encrypt in production
# header {
# Strict-Transport-Security 'max-age=31536000; includeSubDomains'
# X-Content-Type-Options nosniff
# X-Frame-Options DENY
# }
# }Prompt Injection ผ่าน Resource ของ MCP
ช่องทางการโจมตีที่แยบยลคือ เมื่อเซิร์ฟเวอร์ MCP อ่านเนื้อหาจากแหล่งข้อมูลภายนอก เช่น หน้าเว็บ ไฟล์ที่ผู้ใช้อัปโหลด หรือฐานข้อมูลที่ไม่น่าเชื่อถือ แล้วส่งคืนเนื้อหานั้นเป็นผลลัพธ์ของเครื่องมือ ผู้โจมตีอาจฝังคำสั่งที่เป็นปฏิปักษ์ไว้ในเนื้อหา โมเดลอาจทำตามคำสั่งที่ซ่อนอยู่ในข้อมูลที่ดึงมา ซึ่งเรียกว่า การแทรก Prompt ทางอ้อม ให้ทำความสะอาดเนื้อหาที่ดึงมา และอย่าส่งคืนข้อความดิบที่ไม่น่าเชื่อถือโดยตรงเป็นผลลัพธ์ของเครื่องมือ
import re
def sanitize_for_mcp_output(text: str) -> str:
'''Remove patterns that look like instructions to the LLM.'''
# Remove common injection patterns
dangerous_patterns = [
r'ignore previous instructions',
r'ignore all prior instructions',
r'system:',
r'<\|.*?\|>', # Special tokens
r'\[INST\]',
r'<s>',
]
for pattern in dangerous_patterns:
text = re.sub(pattern, '[FILTERED]', text, flags=re.IGNORECASE)
return text[:10000] # Also cap length to prevent context stuffingการตรวจสอบและติดตามความปลอดภัย
บันทึกเหตุการณ์ทั้งหมดที่เกี่ยวข้องกับความปลอดภัย ได้แก่ การยืนยันตัวตนที่สำเร็จและล้มเหลว การละเมิดขีดจำกัดอัตรา การปฏิเสธสิทธิ์ การตรวจสอบความถูกต้องที่ผิดพลาด และรูปแบบการเข้าถึงที่ผิดปกติ ตั้งค่าการแจ้งเตือนสำหรับกรณีต่อไปนี้: การพยายามยืนยันตัวตนที่ล้มเหลวหลายครั้ง (การโจมตีแบบเดารหัสผ่าน), ผู้ใช้รายเดียวเรียกใช้เครื่องมือที่ทำลายข้อมูลอย่างรวดเร็ว และการเรียกใช้เครื่องมือใด ๆ ที่มีข้อมูลนำเข้าขนาดใหญ่มาก ตรวจสอบบันทึกการตรวจสอบเป็นประจำ และทำให้การตรวจจับความผิดปกติทำงานโดยอัตโนมัติ
ตรวจสอบความเข้าใจอย่างรวดเร็ว
ทดสอบความเข้าใจเกี่ยวกับแนวคิดด้านความปลอดภัยและการยืนยันตัวตนของ MCP
สรุปบทเรียน
ในบทเรียนนี้ คุณได้เรียนรู้ว่า เซิร์ฟเวอร์ MCP ระยะไกลต้องใช้การยืนยันตัวตนด้วย OAuth 2.0 หรือคีย์ API ในทุกคำขอ การให้สิทธิ์ตามขอบเขตจะควบคุมว่าเครื่องมือใดที่ผู้ใช้แต่ละรายซึ่งยืนยันตัวตนแล้วสามารถเรียกใช้ได้ และ ข้อมูลนำเข้าของเครื่องมือทั้งหมดต้องผ่านการตรวจสอบความถูกต้องเพื่อป้องกันการโจมตีแบบแทรกคำสั่งและการไล่ย้อนเส้นทาง บทนี้เป็นตอนจบของโมดูล MCP — บทถัดไปเราจะสำรวจกลยุทธ์การแบ่งส่วนขั้นสูงสำหรับการค้นคืน RAG ที่มีความแม่นยำสูง
คำถามที่พบบ่อย
บทเรียน “ความปลอดภัยและการยืนยันตัวตนของ MCP” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ความปลอดภัยและการยืนยันตัวตนของ MCP” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส AI Engineering Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส AI Engineering Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ความปลอดภัยและการยืนยันตัวตนของ MCP”
เพิ่มการยืนยันตัวตนให้เซิร์ฟเวอร์ MCP ด้วยโทเค็น OAuth 2.0 ตรวจสอบข้อมูลนำเข้าเพื่อป้องกันการโจมตีแบบฉีดคำสั่ง และใช้หลักสิทธิ์เท่าที่จำเป็นกับสิทธิ์ของเครื่องมือ คุณปฏิบัติ AI Engineering Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน AI Engineering Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน AI Engineering Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “ความปลอดภัยและการยืนยันตัวตนของ MCP” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน AI Engineering Academy นี้ได้ไหม
ได้ บทเรียน AI Engineering Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- MCP คืออะไรและสำคัญอย่างไร
- การสร้างเซิร์ฟเวอร์ MCP แรกของคุณ
- การเปิดให้เข้าถึงทรัพยากรฐานข้อมูลผ่าน MCP
- ความปลอดภัยและการยืนยันตัวตนของ MCP