นโยบายความปลอดภัยสำหรับการเรียกใช้โค้ด
การจำกัดความสามารถ การแยกเครือข่าย ข้อจำกัดระบบไฟล์ และระยะหมดเวลา
นโยบายความปลอดภัยสำหรับการเรียกใช้โค้ด เป็นบทเรียน AI Agents ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน AI Agents และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส AI Agents มีบทเรียนทั้งหมด 4 บทเรียน
เหตุใดนโยบายจึงไม่เพียงพอด้วยตัวเอง
การบอก LLM ว่า «อย่าเข้าถึงเครือข่าย» ไม่ใช่การควบคุมความปลอดภัย แต่เป็นเพียงคำแนะนำ LLM อาจเพิกเฉย ถูกเจลเบรก หรือโค้ดที่สร้างขึ้นอาจละเมิดกฎทางอ้อม
นโยบายความปลอดภัยที่แท้จริงต้องบังคับใช้ที่ ชั้นการทำงาน ไม่ใช่บังคับใช้เฉพาะในพรอมต์เท่านั้น
ภาพรวมข้อจำกัดด้านความสามารถ
ข้อจำกัดด้านความสามารถจะจำกัดสิ่งที่กระบวนการในแซนด์บ็อกซ์ทำได้ในระดับ OS ความสามารถของลินุกซ์จะแบ่งสิทธิ์ของผู้ดูแลระบบออกเป็นความสามารถย่อย ๆ ซึ่งสามารถยกเลิกได้ทีละรายการ
การยกเลิกความสามารถทั้งหมด ยกเว้นความสามารถขั้นต่ำที่จำเป็น เรียกว่า หลักสิทธิ์น้อยที่สุด
import docker
client = docker.from_env()
# Drop all Linux capabilities
output = client.containers.run(
'python:3.12-slim',
'python -c "print(\"safe run\")"',
cap_drop=['ALL'],
network_disabled=True,
mem_limit='256m',
auto_remove=True
)
print(output.decode())การบล็อกการเขียนดิสก์นอก /tmp
ใช้ระบบไฟล์รากแบบอ่านอย่างเดียว และเมานต์เฉพาะ /tmp ให้เขียนได้ วิธีนี้จะป้องกันไม่ให้โค้ดแก้ไขไฟล์ระบบหรือเก็บข้อมูลไว้นอกพื้นที่ชั่วคราวที่กำหนด
import tempfile, docker
client = docker.from_env()
with tempfile.TemporaryDirectory() as tmpdir:
output = client.containers.run(
'python:3.12-slim',
'python -c "open(\"/tmp/ok.txt\",\"w\").write(\"ok\"); print(open(\"/tmp/ok.txt\").read())"',
read_only=True,
tmpfs={'/tmp': 'size=64m,mode=1777'},
network_disabled=True,
mem_limit='128m',
auto_remove=True
)
print(output.decode()) # 'ok' — /tmp write allowed
# Writing anywhere else raises ReadOnlyFileSystemโปรไฟล์ซีคอมป์: การกรองการเรียกระบบ
ซีคอมป์ (โหมดการประมวลผลที่ปลอดภัย) ช่วยให้คุณระบุรายการอนุญาตของการเรียกระบบที่ยอมรับได้ การเรียกระบบใดก็ตามที่ไม่อยู่ในรายการจะทำให้กระบวนการถูกยุติด้วย SIGSYS
ด็อกเกอร์มีโปรไฟล์ซีคอมป์เริ่มต้นให้ คุณสามารถระบุโปรไฟล์เจสันที่กำหนดเองเพื่อเพิ่มความเข้มงวดได้
import json, docker
client = docker.from_env()
# Minimal seccomp profile: only allow read, write, open, close, exit
seccomp_profile = json.dumps({
'defaultAction': 'SCMP_ACT_ERRNO',
'architectures': ['SCMP_ARCH_X86_64'],
'syscalls': [
{'names': ['read', 'write', 'open', 'openat', 'close',
'fstat', 'mmap', 'mprotect', 'munmap', 'brk',
'exit', 'exit_group', 'rt_sigaction',
'rt_sigprocmask', 'futex'],
'action': 'SCMP_ACT_ALLOW'}
]
})
output = client.containers.run(
'python:3.12-slim',
'python -c "print(1+1)"',
security_opt=[f'seccomp={seccomp_profile}'],
auto_remove=True
)
print(output.decode())ขีดจำกัดทรัพยากร: CPU หน่วยความจำ และเวลา
ขีดจำกัดทรัพยากรสามรายการที่แซนด์บ็อกซ์ทุกแห่งควรบังคับใช้:
- หน่วยความจำ:
mem_limit— ป้องกันการโจมตีแบบ OOM - CPU:
nano_cpusหรือcpu_quota— ป้องกันการใช้ CPU จนหมด - เวลา: การหมดเวลาการทำงาน — ป้องกันลูปไม่สิ้นสุด
output = client.containers.run(
'python:3.12-slim',
'python -c "import time; time.sleep(100)"',
mem_limit='128m',
nano_cpus=500_000_000, # 0.5 CPU
network_disabled=True,
auto_remove=True,
timeout=10 # kill after 10 seconds
)
# Raises ReadTimeout after 10 secondsการอนุญาตการนำเข้าไพธอนตามรายการ
ก่อนเรียกใช้โค้ด ให้สแกน AST เพื่อค้นหาคำสั่งนำเข้า ปฏิเสธการนำเข้าทุกรายการที่ไม่อยู่ในรายการอนุญาต วิธีนี้เป็นชั้นการป้องกันเพิ่มเติม ไม่ใช่สิ่งทดแทนการควบคุมระดับ OS แต่มีประโยชน์สำหรับตรวจจับการละเมิดนโยบายที่เห็นได้ชัดตั้งแต่เนิ่น ๆ
import ast
ALLOWED_IMPORTS = {'math', 'statistics', 'json', 'csv', 'datetime', 'collections', 're'}
def check_imports(code: str) -> list[str]:
tree = ast.parse(code)
blocked = []
for node in ast.walk(tree):
if isinstance(node, ast.Import):
for alias in node.names:
if alias.name.split('.')[0] not in ALLOWED_IMPORTS:
blocked.append(alias.name)
elif isinstance(node, ast.ImportFrom):
if node.module and node.module.split('.')[0] not in ALLOWED_IMPORTS:
blocked.append(node.module)
return blocked
print(check_imports('import socket; print(1)')) # ['socket']
print(check_imports('import math; print(math.pi)')) # []การตรวจหารูปแบบโค้ดอันตราย
นอกเหนือจากการนำเข้า ให้ตรวจสอบรูปแบบที่หลีกเลี่ยงข้อจำกัดการนำเข้า เช่น __import__, exec(), eval(), compile() และ open() ที่ใช้เส้นทางนอก /tmp
import ast
DANGEROUS_CALLS = {'exec', 'eval', 'compile', '__import__', 'breakpoint'}
def check_dangerous_calls(code: str) -> list[str]:
tree = ast.parse(code)
found = []
for node in ast.walk(tree):
if isinstance(node, ast.Call):
if isinstance(node.func, ast.Name):
if node.func.id in DANGEROUS_CALLS:
found.append(node.func.id)
elif isinstance(node.func, ast.Attribute):
if node.func.attr in DANGEROUS_CALLS:
found.append(node.func.attr)
return found
print(check_dangerous_calls('exec("import os")')) # ['exec']ขีดจำกัดขนาดผลลัพธ์
ลูปการพิมพ์ที่ทำงานไม่หยุดอาจสร้างผลลัพธ์ได้หลายกิกะไบต์ ให้จำกัดเอาต์พุตมาตรฐานและเอาต์พุตข้อผิดพลาดมาตรฐานให้อยู่ในขนาดที่เหมาะสม เช่น 1MB และตัดทอนหรือหยุดคอนเทนเนอร์หากเกินขนาดที่กำหนด
MAX_OUTPUT_BYTES = 1 * 1024 * 1024 # 1 MB
def run_with_output_limit(client, code: str) -> dict:
container = client.containers.run(
'python:3.12-slim',
f'python -c "{code}"',
mem_limit='256m',
network_disabled=True,
detach=True
)
try:
container.wait(timeout=30)
logs = container.logs(stdout=True, stderr=True)
if len(logs) > MAX_OUTPUT_BYTES:
return {'success': False, 'error': 'Output too large'}
return {'success': True, 'output': logs.decode(errors='replace')}
finally:
container.remove(force=True)
if __name__ == '__main__':
class FakeContainer:
def wait(self, timeout=30): pass
def logs(self, stdout=True, stderr=True): return b'Analysis complete: 42 rows processed.'
def remove(self, force=True): pass
class FakeContainers:
def run(self, *args, **kwargs): return FakeContainer()
class FakeClient:
containers = FakeContainers()
result = run_with_output_limit(FakeClient(), 'print(42)')
print('Success:', result['success'])
print('Output :', result['output'])
แฟล็กป้องกันการเพิ่มสิทธิ์
ออปชันความปลอดภัย no-new-privileges ป้องกันไม่ให้กระบวนการได้รับสิทธิ์เพิ่มเติมผ่านไบนารี setuid หรือ sudo แม้โค้ดจะเปิดเชลล์ ก็ไม่สามารถยกระดับสิทธิ์ได้
output = client.containers.run(
'python:3.12-slim',
'python -c "import os; print(os.getuid())"',
user='nobody', # run as non-root
security_opt=['no-new-privileges:true'], # no privilege escalation
cap_drop=['ALL'], # no capabilities
network_disabled=True,
mem_limit='128m',
auto_remove=True
)
print(output.decode()) # numeric UID of 'nobody'การรวมทุกนโยบาย
แซนด์บ็อกซ์ระดับใช้งานจริงจะรวมการป้องกันทุกชั้นเข้าด้วยกัน ได้แก่ การถอดความสามารถของระบบปฏิบัติการ โพรไฟล์ seccomp ระบบไฟล์แบบอ่านอย่างเดียว no-new-privileges การปิดเครือข่าย การจำกัดทรัพยากร และการกำหนดเวลาหมดอายุ การป้องกันหลายชั้นช่วยให้การหลีกเลี่ยงชั้นหนึ่งถูกหยุดไว้ด้วยอีกชั้นหนึ่ง
import tempfile, json, docker
client = docker.from_env()
def maximum_security_run(code: str) -> dict:
with tempfile.TemporaryDirectory() as tmpdir:
try:
out = client.containers.run(
'python:3.12-slim',
f'python -c "{code}"',
user='nobody',
security_opt=['no-new-privileges:true'],
cap_drop=['ALL'],
network_disabled=True,
read_only=True,
tmpfs={'/tmp': 'size=32m,mode=1777'},
mem_limit='128m',
nano_cpus=500_000_000,
auto_remove=True,
timeout=15
)
return {'success': True, 'output': out.decode()}
except Exception as e:
return {'success': False, 'error': str(e)}การบันทึกการละเมิดนโยบาย
เมื่อพบการละเมิดนโยบาย เช่น การนำเข้าที่ถูกบล็อก การเรียกใช้ที่เป็นอันตราย หรือการหมดเวลา ให้บันทึกเหตุการณ์พร้อม ID เซสชันของเอเจนต์ แฮชของส่วนโค้ด และประเภทการละเมิด ข้อมูลนี้จะถูกส่งไปยังแดชบอร์ดความปลอดภัยและช่วยปรับแต่งนโยบายให้ดีขึ้นในระยะยาว
import hashlib, logging, time
logging.basicConfig(level=logging.INFO)
security_logger = logging.getLogger('sandbox.security')
def policy_check_and_run(code: str, session_id: str) -> dict:
violations = check_imports(code) + check_dangerous_calls(code)
code_hash = hashlib.sha256(code.encode()).hexdigest()[:16]
if violations:
security_logger.warning(
'POLICY_VIOLATION session=%s hash=%s violations=%s',
session_id, code_hash, violations
)
return {'success': False, 'error': f'Blocked: {violations}'}
result = maximum_security_run(code)
security_logger.info(
'EXEC session=%s hash=%s success=%s',
session_id, code_hash, result['success']
)
return resultการตั้งค่า 'defaultAction: SCMP_ACT_ERRNO' ในโพรไฟล์ seccomp ทำหน้าที่อะไร
โพรไฟล์ seccomp ควบคุมว่ากระบวนการจะเรียกใช้การเรียกระบบใดได้บ้าง ฟิลด์ defaultAction จะกำหนดว่าจะเกิดอะไรขึ้นกับการเรียกระบบที่ไม่ได้ระบุไว้อย่างชัดเจนในโพรไฟล์
สรุปนโยบายความปลอดภัย
การรักษาความปลอดภัยในการเรียกใช้โค้ดที่มีประสิทธิผลจำเป็นต้องมี หลายชั้น: การถอดความสามารถของ Linux การกรองการเรียกระบบด้วย seccomp ระบบไฟล์แบบอ่านอย่างเดียวพร้อมพื้นที่ชั่วคราวแบบ tmpfs no-new-privileges การปิดเครือข่าย การจำกัดหน่วยความจำ/CPU/เวลา และการตรวจสอบการนำเข้าระดับ AST
ไม่มีชั้นใดเพียงชั้นเดียวที่เพียงพอ — การป้องกันหลายชั้นหมายความว่าแต่ละชั้นจะช่วยชดเชยจุดที่ชั้นอื่นอาจถูกหลีกเลี่ยงได้
คำถามที่พบบ่อย
บทเรียน “นโยบายความปลอดภัยสำหรับการเรียกใช้โค้ด” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “นโยบายความปลอดภัยสำหรับการเรียกใช้โค้ด” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส AI Agents ให้อัปเกรดเป็น CoddyKit PRO คอร์ส AI Agents มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “นโยบายความปลอดภัยสำหรับการเรียกใช้โค้ด”
การจำกัดความสามารถ การแยกเครือข่าย ข้อจำกัดระบบไฟล์ และระยะหมดเวลา คุณปฏิบัติ AI Agents ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน AI Agents หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน AI Agents บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “นโยบายความปลอดภัยสำหรับการเรียกใช้โค้ด” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน AI Agents นี้ได้ไหม
ได้ บทเรียน AI Agents ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- แซนด์บ็อกซ์เอเจนต์บน Docker
- การแยก VM สำหรับเอเจนต์รันโค้ดความปลอดภัยสูง
- บริการแซนด์บ็อกซ์ E2B และระบบคลาวด์
- นโยบายความปลอดภัยสำหรับการเรียกใช้โค้ด