
Apache Spark 4.2.0 - उच्च - रिमोट - विशेषाधिकार अवशेष - प्रक्रिया-वैश्विक Python डेटा स्रोत मैप
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · spark-python-ds-static
वर्ग: विशेषाधिकार अवशेष पहुँच: रिमोट
Apache Spark 4.2.0 (32f72996) - Apache Software Foundation
DataSourceManager.dataSourceBuilders एक JVM-व्यापी first-wins मैप है। SPARK-45917 lookup worker के sys.path से pyspark_* Python Data Sources को स्वतः-पंजीकृत करता है। Connect session isolation कलाकृतियों को SparkFiles/<sessionUUID>/ के अंतर्गत रखता है, और प्रति-सत्र registerPython runtimeDataSourceBuilders पर ही रहता है। पहला lookup फिर भी ट्रिगर करने वाले सत्र की SparkFiles डायरेक्टरी को sys.path पर डालता है, प्रत्येक DefaultSource को पिकल करता है, और उन क्लासों को companion object में कैश करता है। बाद में Connect SQL (या Hive Thrift SQL) read.format(name) / USING name उस क्लास को Spark UID के रूप में चलाता है, बिना Python proto भेजे।
रोपणकर्ता एक Connect Python tenant है जिसे पहले से ही Python की अनुमति है। शिकार उसी Connect driver पर एक SQL-only tenant है। Java aliases (parquet, csv, json, orc, jdbc) Java ServiceLoader पथ पर ही रहते हैं। मैप भर जाने के बाद के बाद के रोपण रीफ्रेश नहीं होते। AC:H पहला-lookup है साथ ही एक नाम जो Java alias नहीं है।
| ID | अभी तक कोई CVE नहीं |
| वर्ग | विशेषाधिकार अवशेष (क्रॉस-सत्र Python Data Source as Spark UID; unauth job submit नहीं) |
| पहुँच | रिमोट (साझा Spark Connect driver) |
| CWE | CWE-269, CWE-502 |
| CVSS | High: 8.8 CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:H |
| उत्पाद | Apache Spark |
| प्रभावित | 4.2.0 (32f7299601108917fb01920a54e084595b7b3bf8) Python Data Source static registry |
| प्रमाणीकरण | Connect Python tenant (रोपणकर्ता) साथ ही बाद में एक SQL-only Connect / Hive Thrift SQL उपयोगकर्ता (शिकार) |
| लाइसेंस | GNU Affero GPL v3.0 |
| लैब | केवल 127.0.0.1:18970। Witness फ़ाइल। companion map का Gadget। |
एक साझा driver पर Spark Connect Python सत्र रखें। pyfiles/pyspark_<name>.py रोपें जिसका DefaultSource.name() एक अनुपस्थित connector short name (delta, iceberg, hudi, ...) हो। उस सत्र पर पहला Python Data Source lookup ट्रिगर करें। उसी JVM में बाद का प्रत्येक सत्र जो read.format(name) या SQL USING name करता है, उस पिकल किए गए क्लास को driver planner worker पर और executors पर Spark UID के रूप में इंस्टैंशिएट करता है।
यही पूरा विशेषाधिकार सेट है। रोपणकर्ता पहले से ही Python चलाता है। अवशेष यह है कि एक SQL-only tenant, जिसने कभी REGISTER_DATA_SOURCE / Python UDF proto नहीं भेजा, फिर भी उस क्लास को निष्पादित करता है।
| विधि | Sink | विशेषाधिकार |
|---|---|---|
रोपणकर्ता: AddArtifacts नाम pyfiles/pyspark_<name>.py फिर पहला format(name) / lookup | companion DataSourceManager.dataSourceBuilders (DataSourceManager.scala object) साथ ही lookup_data_sources.py का iter_modules of pyspark_* | ट्रिगर करने वाले सत्र के पिकल किए गए DefaultSource को JVM-व्यापी कैश करें। लैब: layer='static' trigger='attacker' first-wins=yes। |
शिकार: SQL USING <name> / spark.read.format(name) उस सत्र पर जिसने कभी रोपण नहीं किया | PythonDataSourceV2 createDataSourceInPython | उस क्लास को Spark UID के रूप में चलाएँ। लैब: planted_by='attacker' witness_written=True static-cross-session=yes। Oracle फ़ाइल में SPARK-PYTHON-DS-STATIC-WITNESS होता है। |
| विधि | Sink | परिणाम |
|---|---|---|
| मैप भर जाने के बाद दूसरे नाम का बाद का रोपण | वही static map | बंद। First-wins। लैब: later-lookup found=False, companion अभी भी केवल delta। |
प्रति-सत्र registerPython("alpha") | runtimeDataSourceBuilders | पृथक। Clone केवल runtime की प्रतिलिपि करता है। लैब: runtime-isolated=yes। alpha का शिकार पठन found=False है। |
Java alias parquet | Java DataSourceRegister ServiceLoader | बंद। लैब: java-alias-closed=yes layer='java'। csv/json/orc/jdbc के लिए भी वही। |
| विधि | Sink | विशेषाधिकार |
|---|---|---|
रोपण के बाद शिकार USING | driver + executor Python workers | Spark UID के रूप में क्लस्टर-व्यापी कोड। लैब payload के बजाय एक witness फ़ाइल लिखता है। |
| वही पथ | worker crash / spin | Spark UID के रूप में उपलब्धता। High नहीं। High कोड exec है। |
साझा SparkSession पर Hive Thrift SQL USING | वही static map | वही अवशेष यदि Thrift और Connect driver JVM साझा करते हैं। अभ्यास नहीं किया गया। |
parquet / csv / json / orc / jdbc hijack। ServiceLoader जीतता है।concatenatePaths .. और absolute नामों को अस्वीकार करता है)।pythonExec। Connect planner सर्वर PYSPARK_PYTHON / python3 का उपयोग करता है।registerPython का क्रॉस-सत्र लीक। Runtime map प्रति DataSourceManager इंस्टेंस है।pyspark एक सत्र के साथ। कोई अन्य tenant नहीं है।मैंने apache/spark v4.2.0 (32f7299601108917fb01920a54e084595b7b3bf8) पिन किया। अट्ठाईस स्रोत खोजें। उपयोगकर्ता कोड निष्पादित करने वाला job submit डिज़ाइन से है। History Jackson, UI shell, PySpark local impersonation, और standalone RPC receive-path इस peel पर बंद हैं। Connect artifacts pyfiles को एक session UUID के अंतर्गत पृथक करते हैं। Runtime registerPython प्रति सत्र है। Companion object नहीं है।
SPARK-45917 PYTHONPATH से pyspark_* पैकेजों को स्वतः-पंजीकृत करता है। यह ऑपरेटर-स्थापित connectors के लिए अभिप्रेत है। अवशेष यह है कि lookup worker ट्रिगर करने वाले सत्र की SparkFiles डायरेक्टरी को भी sys.path.insert करता है (worker_util.setup_spark_files), फिर जो भी pyspark_* DefaultSource मिलता है उसे एक प्रक्रिया-व्यापी मैप में पिकल करता है जो कभी रीफ्रेश नहीं होता।
गलत मोड़: registerPython isolation को पूरा tenant bar मानना। Runtime पृथक है। Static नहीं है।
cd lab
./run.sh
Loopback 127.0.0.1:18970। Compose प्रोजेक्ट spark-python-ds-static। Witness SPARK-PYTHON-DS-STATIC-WITNESS। object DataSourceManager का Python gadget साथ ही प्रति-सत्र runtime maps। pyspark_delta.py केवल attacker SparkFiles में रोपें। Attacker lookup companion भरता है। iceberg का बाद का रोपण रीफ्रेश नहीं करता। delta का शिकार read oracle लिखता है। registerPython("alpha") लीक नहीं करता। Java parquet Java ही रहता है।
अंतिम पंक्ति:
SUCCESS SPARK-PYTHON-DS-STATIC static-cross-session=yes runtime-isolated=yes first-wins=yes java-alias-closed=yes SPARK-PYTHON-DS-STATIC-WITNESS
static map भरते समय lookup worker sys.path पर session SparkFiles न रखें। केवल ऑपरेटर PYTHONPATH पैकेज लोड करें (SPARK-45917 जैसा डिज़ाइन किया गया)। या static map को session / JobArtifactSet UUID द्वारा key करें, जैसे artifacts पहले से हैं। First-wins खाली fill को driver के जीवनकाल के लिए किसी अन्य tenant की क्लासों को पिन नहीं करना चाहिए।
तब तक, एक Connect driver को Python tenant और SQL-only tenant के बीच साझा न करें जिसे आप पहले से driver Python के साथ नहीं भरोसा करते।