Python pathlib.full_match: ตรวจ Path ทั้งเส้นโดยไม่เผลอรับไฟล์นอกกฎ
การ validate path ด้วย substring หรือ suffix อย่างเดียวมักรับเส้นทางเกินกฎ PurePath.full_match ตรวจ glob pattern กับ path ทั้งเส้น เหมาะกับ allowlist ที่ต้องการพูดว่า “ไฟล์ Python ใต้ src เท่านั้น” ครับ
ต่างจาก match ที่รองรับการจับจากด้านขวาในบางรูปแบบ full_match ต้องให้ pattern ครอบ path ทั้งหมด และเพราะใช้ PurePath ตัวอย่างนี้ไม่อ่าน filesystem จึงทดสอบกฎได้อย่าง deterministic
from __future__ import annotations
import unittest
from pathlib import PurePosixPath
def is_source_file(raw: str) -> bool:
path = PurePosixPath(raw)
return path.full_match("src/**/*.py") and ".." not in path.parts
class FullMatchTests(unittest.TestCase):
def test_accepts_nested_python_source(self):
self.assertTrue(is_source_file("src/app/main.py"))
def test_rejects_other_roots_and_suffixes(self):
self.assertFalse(is_source_file("tests/app/main.py"))
self.assertFalse(is_source_file("src/app/main.py.bak"))
def test_rejects_parent_traversal(self):
self.assertFalse(is_source_file("src/../secrets/key.py"))
if __name__ == "__main__":
unittest.main()
glob matching ไม่ใช่ security sandbox: มันไม่ resolve symlink และไม่ได้พิสูจน์ว่า path จริงอยู่ใต้ root สำหรับ input ที่จะใช้เปิดไฟล์ ต้อง resolve กับ base directory แล้วตรวจ containment อีกชั้น รวมถึงกำหนด flavor ให้ตรงระบบ (PurePosixPath หรือ PureWindowsPath)
Recap
- ใช้
full_matchเมื่อ policy ต้องครอบ path ทั้งเส้น - ทดสอบ root ผิด, suffix หลอก และ
.. - เลือก path flavor ให้ตรงรูปแบบ input
- resolve และตรวจ containment ก่อนเปิดไฟล์ที่ไม่เชื่อถือ