dexter has uploaded this change for review. ( https://gerrit.osmocom.org/c/pysim/+/42625?usp=email )
Change subject: osmo-smdpp.py: fix path Traversal Bypass in SM-DP+ (CWE-22) ......................................................................
osmo-smdpp.py: fix path Traversal Bypass in SM-DP+ (CWE-22)
Root Cause: os.path.commonprefix() compares strings character-by-character, NOT by path components. This is a well-known Python antipattern (Python docs explicitly warn: "this function may return invalid paths because it works a character at a time").
Attack Context: The matchingId parameter is received from a network client via the GSMA ES9+ authenticateClient API endpoint (POST to /gsma/rsp2/es9plus/authenticateClient). The SM-DP+ server is a Twisted web application listening on port 443. An unauthenticated eUICC client sends the matchingId in the ctxParamsForCommonAuthentication ASN.1 structure.
Fix: Replace os.path.commonprefix() with proper path component checking:
Change-Id: I7a42b40aa2bbcd5f0ec99f172503354c6eaa9828 --- M osmo-smdpp.py 1 file changed, 2 insertions(+), 1 deletion(-)
git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/25/42625/1
diff --git a/osmo-smdpp.py b/osmo-smdpp.py index d1d6fd7..74d9ab6 100755 --- a/osmo-smdpp.py +++ b/osmo-smdpp.py @@ -117,6 +117,7 @@ import uuid # noqa: E402 import os # noqa: E402 import functools # noqa: E402 +import pathlib from typing import Optional, Dict, List # noqa: E402 from pprint import pprint as pp # noqa: E402
@@ -640,7 +641,7 @@ # look up profile based on matchingID. We simply check if a given file exists for now.. path = os.path.join(self.upp_dir, matchingId) + '.der' # prevent directory traversal attack - if os.path.commonprefix((os.path.realpath(path),self.upp_dir)) != self.upp_dir: + if not pathlib.Path(path).resolve().is_relative_to(self.upp_dir): raise ApiError('8.2.6', '3.8', 'Refused') if not os.path.isfile(path) or not os.access(path, os.R_OK): raise ApiError('8.2.6', '3.8', 'Refused')