
Apache Spark 4.2.0 - عالي - عن بُعد - كتابة ملف - جلسة Connect SET copyFromLocalToFs.allowDestLocal
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · spark-connect-copy-local
الفئة: كتابة ملفات (بقايا SPARK-58531؛ ثابتة على 4.3.0 فقط) الوصول: عن بُعد
Apache Spark 4.2.0 (32f72996) - Apache Software Foundation
لا يزال spark.sql.artifact.copyFromLocalToFs.allowDestLocal على buildConf (قابل للضبط من الجلسة) عند هذه النسخة. نقل SPARK-58531 هذا الإعداد إلى StaticSQLConf في 4.3.0. يمكن لجلسة Connect ضبط بوابة الوجهة المحلية الخاصة بالاختبار فقط، ثم يقوم copyFromLocalToFs / AddArtifacts forward_to_fs/<abs> بالكتابة فوق مسار محلي على السائق بصلاحيات Spark UID.
جلسة Connect تضبط الإعداد ثم forward_to_fs يكتب ملفات محلية على السائق. يجب أن تكون الوجهة LocalFileSystem. ليست RCE.
| المعرّف | لا يوجد CVE بعد (بقايا SPARK-58531) |
| الفئة | كتابة ملفات (بقايا SPARK-58531؛ ثابتة على 4.3.0 فقط) |
| الوصول | عن بُعد (Spark Connect Config + AddArtifacts) |
| CWE | CWE-22، CWE-732 |
| CVSS | مرتفع: 8.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H |
| المنتج | Apache Spark (ASF) |
| المتأثر | Apache Spark 4.2.0 (32f7299601108917fb01920a54e084595b7b3bf8). الإصدار 4.3.0 ثابت. |
| المصادقة | عميل Connect قادر على ConfigRequest.SET و AddArtifacts. Connect الافتراضي بلا PSK. |
| الترخيص | GNU Affero GPL v3.0 |
| المختبر | 127.0.0.1:18920 فقط |
يمكن لعميل Spark Connect قادر على الوصول إلى gRPC (منفذ الربط الافتراضي 15002، بلا PSK ما لم يضبط المشغّل spark.connect.authenticate.token) أن يقلب بوابة اختبارية بدأ بها السائق إلى وضع الإيقاف، ثم يكتب فوق مسار محلي مختار على السائق بصلاحيات Spark UID.
| الطريقة | الهدف | الصلاحية |
|---|---|---|
gRPC Config SET spark.sql.artifact.copyFromLocalToFs.allowDestLocal=true (أو SQL SET) | SparkConnectConfigHandler.handleSet -> RuntimeConfig.set -> SQLConf.setConfString | السلامة (إعداد الجلسة، مُثبت مختبريًا): يقلب بوابة الوجهة المحلية لكل جلسة. لا يكتب ملفًا بحد ذاته. لا يغيّر الجلسات الأخرى. المختبر: SET HTTP 200، modifiable=True. |
gRPC AddArtifacts باسم forward_to_fs + وجهة مطلقة، CRC سليم | ArtifactManager.uploadArtifactToFs -> LocalFileSystem.copyFromLocalFile(delSrc=false, overwrite=true) | السلامة (الكتابة فوق ملف، مُثبت مختبريًا): كتابة/كتابة فوق مسار محلي على السائق بصلاحيات Spark UID، خارج artifactRootDirectory/<sessionUUID>/. المختبر: الوجهة /oracle/SPARK-CONNECT-COPY-LOCAL-WITNESS، uid 185، المحتوى WITNESS. |
| نفس AddArtifacts إلى وجهة HDFS/S3/ABFS | copyFromLocalToFs الموثّق | السلامة (نظام ملفات العنقود، بحكم التصميم): ليست هذه البقايا. الوجهة التي ليست LocalFileSystem لا تتحقق من علم الاختبار أبدًا. |
مُثبت مختبريًا مقابل مُستنتج: ضبط الجلسة لمفتاح buildConf، ثم الكتابة إلى وجهة LocalFileSystem بصلاحيات uid 185 خارج صندوق حماية الـ artifacts، مُثبت مختبريًا. الكتابة فوق مسار بصلاحيات Spark UID يمكن للعملية الكتابة إليه (دليل عمل السائق، مجلد قابل للكتابة للجميع، سكربت قابل للتنفيذ يشغّله المشغّل لاحقًا) مُستنتج. لا تحكّم بـ RIP. لا تضخّم كتابة الملفات إلى RCE.
يتطلب: Spark Connect في وضع الاستماع. عميل قادر على SET لإعداد SQL للجلسة و AddArtifacts. يجب أن تكون الوجهة Hadoop LocalFileSystem. Connect الافتراضي بلا PSK؛ إذا ضبط المشغّل رمزًا، فلا تزال البقايا تحتاج ذلك الـ Bearer المشترك. إنها تجاوز لضبط الوجهة المحلية، وليست تجاوزًا لـ PSK.
| السطح | المختبر |
|---|---|
| النسخ بدون SET | 400 _LEGACY_ERROR_TEMP_3161، الوجهة غائبة |
SET للمفتاح الثابت القديم spark.connect.copyFromLocalToFs.allowDestLocal | 400 CANNOT_MODIFY_STATIC_CONFIG |
اسم الـ artifact .. / staging مطلق (ArtifactUtils.concatenatePaths) | INVALID_ARTIFACT_PATH |
artifacts غير forward_to_fs | تبقى تحت artifactRootDirectory/<sessionUUID>/ |
| وجهة HDFS/سحابية بدون العلم | API موثّق، وليست هذه البقايا |
SQL غير مُصادق / Python UDF / Scala UdfPacket على Connect مفتوح | إرسال مهمة وفق أسئلة المورّد الشائعة؛ DROP |
| SPARK-52122 ML DefaultParamsReader | قائمة سماح + safeMLClassLoader عند هذه النسخة |
لا shell. لا heap dump. لا تجاوز لـ Connect PSK. لا تزال الوجهة يجب أن تكون LocalFileSystem. الكتابة بصلاحيات Spark UID، وليست بصلاحيات root.
يرفض uploadArtifactToFs وجهة LocalFileSystem ما لم يكن علم الاختبار مفعّلًا، مع تعليق صريح بأنه بخلاف ذلك يكتب المستخدم فوق ملف عشوائي على السائق:
if (fs.isInstanceOf[LocalFileSystem]) {
val allowDestLocalConf =
session.sessionState.conf.getConf(SQLConf.ARTIFACT_COPY_FROM_LOCAL_TO_FS_ALLOW_DEST_LOCAL)
.getOrElse(
session.conf.get("spark.connect.copyFromLocalToFs.allowDestLocal").contains("true"))
if (!allowDestLocalConf) {
throw new SparkUnsupportedOperationException("_LEGACY_ERROR_TEMP_3161")
}
}
fs.copyFromLocalFile(false, true, new FSPath(localPath.toString), destFSPath)
مفتاح 3.5 ثابت، والافتراضي false. بديل 4.0 هو buildConf اختياري:
val ARTIFACT_COPY_FROM_LOCAL_TO_FS_ALLOW_DEST_LOCAL =
buildConf("spark.sql.artifact.copyFromLocalToFs.allowDestLocal")
.internal()
...
.booleanConf
.createOptional
لا يستدعي buildConf الدالة registerStaticConfigKey. وisModifiable تساوي containsConfigKey && !isStaticConfigKey. وRuntimeConfig.set يرفض المفاتيح الثابتة فقط. يبقى Internal قابلًا للضبط. بعد SET، تُرجع getConf(ARTIFACT_...) القيمة Some(true) ويُتخطّى الرجوع الاحتياطي getOrElse إلى الإعداد الثابت القديم.
تم حل SPARK-58531 / PR 57730 "Convert spark.sql.artifact.copyFromLocalToFs.allowDestLocal to a static conf" في 2026-08-05، إصدار الإصلاح 4.3.0. JIRA: الإعداد "يتحكم فيما إذا كان بإمكان المستدعي الكتابة إلى مسار عشوائي على نظام الملفات المحلي للسائق، لذا يُقصد به أن يضبطه من يشغّل السائق." الإصدار 4.2.0 مُدرج ضمن المتأثرين. لا تزال هذه النسخة تحتوي على إعداد وقت التشغيل.
المنعطفات الخاطئة المسجّلة مسبقًا: التعامل مع Connect SQL كاكتشاف (الأسئلة الشائعة)؛ SET للمفتاح الثابت القديم (CANNOT_MODIFY_STATIC_CONFIG)؛ الادعاء بأن وجهة Unix مطلقة تتجاهل الأصل (فهي تُدمج تحت الجذر)؛ تضخيم كتابة الملفات إلى RCE؛ تثبيت 4.3.0 RC لأن الـ JIRA محلول.
cd lab
./run.sh
Loopback 127.0.0.1:18920. أداة استغلال بوابة إعداد الجلسة ونسخ وجهة LocalFileSystem (النسخة v4.2.0 32f72996). UID الخادم 185. ضبط التحكم بدون SET: 400 _LEGACY_ERROR_TEMP_3161، الوجهة غائبة. ضبط التحكم للمفتاح الثابت القديم: CANNOT_MODIFY_STATIC_CONFIG. ضبط الجلسة لمفتاح buildConf ثم النسخ: الوجهة /oracle/SPARK-CONNECT-COPY-LOCAL-WITNESS خارج /opt/spark/work/artifacts/<sessionUUID>/، uid 185، المحتوى WITNESS.