FlawOpen

flawopen.com/पथ ट्रैवर्सल/Python os.path.join()

क्या Python का os.path.join() Path Traversal रोकता है?

CWE-22: Path Traversalसंदर्भ पृष्ठ
संक्षिप्त उत्तर

नहीं। आधार डायरेक्टरी को कमरा मानें: .. अभिभावक कमरों से बाहर ले जाता है; निरपेक्ष पथ नया पता है, जिससे os.path.join() शुरुआती कमरा हटा देता है। फ़ाइल खोलने से पहले अंतिम पथ resolve करें और अनुमत डायरेक्टरी के भीतर होने की पुष्टि करें।

VULNERABLE
import os

base_dir = "/srv/uploads"
user_filename = "../../outside/demo.txt"
path = os.path.join(base_dir, user_filename)
# Relative traversal can leave the base.

path = os.path.join(base_dir, "/outside/demo.txt")
# An absolute segment discards base_dir.
SECURE — resolve and check containment
import os

def resolve_under_base(base_dir, user_filename):
    if not isinstance(user_filename, str) or not user_filename:
        raise ValueError("Invalid filename")

    base = os.path.realpath(base_dir)
    candidate = os.path.realpath(
        os.path.join(base, user_filename)
    )

    try:
        inside = os.path.commonpath((base, candidate)) == base
    except ValueError:  # e.g. different Windows drives
        inside = False

    if not inside or candidate == base:
        raise ValueError("Invalid filename")
    return candidate

पथ जोड़ने के दो व्यवहार

.. सापेक्ष पथ को निर्धारित डायरेक्टरी से बाहर ले जा सकता है। Python दस्तावेज़ के अनुसार निरपेक्ष घटक आने पर os.path.join() पिछले घटक हटा देता है; Windows के ड्राइव और root नियम POSIX से अलग हैं। pathlib.Path(base) / user_input भी ऐसा ही करता है। जोड़ना या normalize करना अनुमति-जाँच नहीं है।

commonpath() स्ट्रिंग prefix से सुरक्षित क्यों है

तुलना से पहले विश्वसनीय आधार और उम्मीदवार resolve करें। os.path.commonpath() अक्षर-prefix नहीं, पथ-घटक जाँचता है और असंगत root या drive पर ValueError देता है; ऐसे मामले अस्वीकार करें। realpath() जाँच के समय के symbolic link resolve करता है, बाद के बदलाव नहीं रोकता। यदि दूसरे लोग ट्री बदल सकते हैं, तो उचित descriptor access और no-follow नियंत्रण अपनाएँ।

अक्सर पूछे जाने वाले प्रश्न

क्या pathlib भी ऐसा ही करता है?

हाँ। Path का / निरपेक्ष अगला पथ आने पर पिछले घटक हटा देता है। परिणाम resolve करें और अनुमत आधार के भीतर जाँचें।

क्या realpath() race रोकता है?

नहीं। यह सत्यापन के समय के लिंक resolve करता है; दूसरा process फ़ाइल खुलने से पहले उन्हें बदल सकता है। लिखने की अनुमति सीमित करें या उपलब्ध होने पर no-follow descriptor-relative ऑपरेशन अपनाएँ।

संदर्भ

यह भी देखें पाथ ट्रैवर्सल (CWE-22): यह कैसे काम करता है और हर भाषा में इसे कैसे रोकें — flawopen.com Zip Slip भेद्यता क्या है? Node.js path.join() Path Traversal नहीं रोकता PHP include() और उपयोगकर्ता-नियंत्रित पथ