
Apache Spark 4.2.0 - عالي - عن بُعد - كتابة ملف - جلسة Connect SET copyFromLocalToFs.allowDestLocal
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · spark-connect-copy-local
المقال التقني: https://abraxaslabs.tech/research/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 أن تضبط بوابة الوجهة المحلية المخصّصة للاختبار فقط عبر SET، ثم يقوم copyFromLocalToFs / AddArtifacts forward_to_fs/<abs> بالكتابة فوق مسار محلي على السائق (driver) بصلاحيات مستخدم Spark UID.
جلسة Connect تضبط عبر SET ثم يكتب 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 عبر SET في الجلسة، ثم الكتابة إلى وجهة LocalFileSystem بصلاحيات uid 185 خارج صندوق حماية القطع الأثرية (artifact sandbox)، هو أمر مُثبت مختبريًا. أما الكتابة فوق مسار بصلاحيات مستخدم Spark UID يستطيع العملية الكتابة إليه (دليل عمل السائق، مجلد قابل للكتابة للجميع، سكربت قابل للتنفيذ مسبقًا يشغّله المشغّل لاحقًا) فهو مُستنتج. لا تحكّم في RIP. لا تُضخّم كتابة الملفات إلى RCE.
يتطلب: Spark Connect في حالة استماع. عميل قادر على تنفيذ SET لإعداد SQL للجلسة وAddArtifacts. يجب أن تكون الوجهة LocalFileSystem من Hadoop. لا يحتوي Connect الافتراضي على PSK؛ وإذا كان المشغّل قد عيّن رمزًا (token)، فإن ما تبقّى لا يزال بحاجة إلى ذلك Bearer المشترك. إنه تجاوز لضابط الوجهة المحلية، وليس تجاوزًا لـ PSK.
| السطح | المختبر |
|---|---|
| نسخ بدون SET | 400 _LEGACY_ERROR_TEMP_3161، الوجهة غائبة |
تعيين spark.connect.copyFromLocalToFs.allowDestLocal الثابت القديم عبر SET | 400 CANNOT_MODIFY_STATIC_CONFIG |
اسم الأثر .. / التجهيز المطلق (ArtifactUtils.concatenatePaths) | INVALID_ARTIFACT_PATH |
الأثر غير forward_to_fs | يبقى تحت artifactRootDirectory/<sessionUUID>/ |
| وجهة HDFS/السحابة بدون العلامة | واجهة برمجية موثّقة، وليست هذه البقايا |
SQL غير موثّق / Python UDF / Scala UdfPacket على Connect مفتوح | إرسال مهمة وفق الأسئلة الشائعة للمورّد؛ DROP |
| SPARK-52122 ML DefaultParamsReader | قائمة السماح + safeMLClassLoader على هذا التثبيت |
لا shell. لا تفريغ للذاكرة (heap dump). لا تخطٍّ لـ Connect PSK. لا تزال الوجهة يجب أن تكون LocalFileSystem. تتم الكتابة بصلاحية UID الخاص بـ Spark، وليس بصلاحية root.
يرفض uploadArtifactToFs وجهة LocalFileSystem ما لم تكن علامة الاختبار مفعّلة، مع تعليق صريح مفاده أنه بخلاف ذلك يقوم المستخدم بالكتابة فوق ملف عشوائي على السائق (driver):
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 يرفض فقط المفاتيح الثابتة. الداخلي لا يزال قابلاً للتعيين. بعد SET، يُرجع getConf(ARTIFACT_...) القيمة Some(true) ويتم تخطي احتياطي getOrElse إلى conf الثابت القديم.
SPARK-58531 / PR 57730 "Convert spark.sql.artifact.copyFromLocalToFs.allowDestLocal to a static conf" تم حله في 2026-08-05، إصدار الإصلاح 4.3.0. JIRA: إن conf "يتحكم فيما إذا كان بإمكان المستدعي الكتابة إلى مسار عشوائي على نظام ملفات السائق المحلي، لذا يُقصد أن يتم تعيينه من قبل من يشغّل السائق." 4.2.0 مدرج ضمن Affects. لا يزال هذا التثبيت يحتوي على conf وقت التشغيل.
المنعطفات الخاطئة المسجلة بالفعل: التعامل مع Connect SQL كاكتشاف (FAQ)؛ SET للمفتاح الثابت القديم (CANNOT_MODIFY_STATIC_CONFIG)؛ الادعاء بأن وجهة Unix المطلقة تتجاهل الأصل (فهي تنضم تحت الجذر)؛ تضخيم كتابة الملف إلى RCE؛ تثبيت 4.3.0 RC لأن JIRA تم حله.
cd lab
./run.sh