1 पॉइंट द्वारा GN⁺ 3 시간 전 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • gokrazy/rsync Go में लिखा गया एक minimal rsync implementation है, जिसकी समीक्षा जनवरी 2025 और मई 2026 में सार्वजनिक हुई rsync की 12 vulnerabilities के आधार पर की गई
  • Go की bounds checking और zero initialization heap overflow और stack information leak को panic या harmless value में बदल देती हैं, लेकिन panic फिर भी denial of service बन सकता है
  • path traversal और TOCTOU श्रेणी के मामलों में Go 1.24 की os.Root जैसी traversal-resistant file API मुख्य सुरक्षा बनती है, और gokrazy/rsync को पूरी तरह इस पर migrate किया गया है
  • minimal implementation strategy --inc-recursive, compression, --safe-links, proxy, hostname ACL जैसी unimplemented features से जुड़ी vulnerabilities से बचाती है और attack surface घटाती है
  • ज़्यादातर vulnerabilities validation की कमी और अत्यधिक complexity से आईं, और simple use case के लिए simple implementation अधिक उपयुक्त हो सकती है

पृष्ठभूमि और दायरा

  • जनवरी 2025 में कई security researchers ने upstream Samba rsync में कुल 6 security vulnerabilities सार्वजनिक कीं, जिनमें कुछ arbitrary code execution और file exfiltration की अनुमति देती थीं
  • Go में लिखे compatible, minimal implementation gokrazy/rsync के बारे में यह मुख्य समीक्षा की गई कि क्या वह वास्तव में ऐसी vulnerability families से बच सकता है
  • विश्लेषण का दायरा जनवरी 2025 batch और मई 2026 batch को मिलाकर कुल 12 vulnerabilities का है
  • अगर आप production में upstream rsync चला रहे हैं, तो आपको 3.4.3 या उससे ऊपर पर upgrade करना चाहिए, और gokrazy/rsync को v0.3.3 या उससे ऊपर पर ले जाना चाहिए
  • gokrazy/rsync को Linux distribution research project distri के software packages को router7 पर उपलब्ध कराने के लिए लिखा गया था, और router7 Go appliance platform gokrazy पर आधारित है
  • शुरुआत में इसमें केवल rsync server था, लेकिन अब यह सभी दिशाओं को support करता है और Go programs में link की जा सकने वाली rsync की बुनियादी functionality के रूप में कई gokrazy/rsync servers में इस्तेमाल हो रहा है

जनवरी 2025 की कमजोरियाँ

  • CVE-2024-12084: heap buffer overflow, गंभीरता 9.8

    • rsync ने नेटवर्क से मिली checksum लंबाई की तुलना MAX_DIGEST_LEN से की, लेकिन internal data structure हमेशा 16-byte buffer char sum2[SUM_LENGTH] का उपयोग करता था
    • MAX_DIGEST_LEN को SHA256 या SHA512 checksum support के साथ compile करने पर बड़ा किया जा सकता था, इसलिए हमलावर sum2 buffer की सीमा से अधिकतम 48 bytes तक लिख सकता था
    • यह समस्या सितंबर 2022 के commit ae16850 में आई, जिसमें SHA256/SHA512 checksum support जोड़ा गया था
    • upstream fix ने sum2 को dynamically allocated sum2_array से बदला और transfer algorithm की checksum लंबाई xfer_sum_len के आधार पर allocation और validation की
    • Go में गलत boundary check heap buffer overflow तक नहीं पहुँचती, बल्कि runtime boundary check से panic होता है
    • gokrazy/rsync में भी sum header validation गायब थी, लेकिन यह size confusion नहीं था, और ChecksumLength को 512 पर बदलने से Go runtime panic: runtime error: slice bounds out of range [:512] with length 16 देता है
    • पूरे server का crash होना वांछनीय failure mode नहीं है, इसलिए missing boundary check जोड़कर panic को error में बदला गया
  • CVE-2024-12085: stack information leak से ASLR bypass, गंभीरता 7.5

    • CVE-2024-12084 जैसी ही validation की कमी के कारण हमलावर छोटा checksum algorithm चुनकर यह दावा कर सकता था कि उसने लंबा checksum भेजा है
    • Google Security report के अनुसार, heap buffer overflow और information leak को मिलाकर केवल anonymous read access वाला client भी rsync server machine पर arbitrary code execute कर सकता है
    • hash_search() stack पर char sum2[MAX_DIGEST_LEN] में chunk digest बनाकर memcmp() से compare करता था, लेकिन local sum2 stack buffer initialize नहीं होता था, इसलिए बचे हुए bytes में stack contents रह सकते थे
    • malicious client हर file download पर 1 byte leak कर सकता था, और leaked data में heap object pointers, stack cookie, local variables, global variable pointers, और return pointer शामिल हो सकते थे
    • “Some checksum buffer fixes” ने यह सुनिश्चित किया कि attacker-controlled s->s2length transfer checksum length से बड़ा न हो सके, और “prevent information leak off the stack” ने sum2 memory को 0 से initialize किया
    • Go सभी variables को zero value से initialize करता है, इसलिए यह vulnerability उस पर लागू नहीं होती, और gokrazy/rsync protocol version 30 नहीं बल्कि protocol version 27 implement करता है, जिसमें MD4 के अलावा checksum selection नहीं जोड़ा गया था
  • CVE-2024-12087: symbolic link का उपयोग कर path traversal, गंभीरता 7.5

    • Google Security report के अनुसार, जब -l या -a(--archive) के साथ symbolic link synchronization enabled हो, तो malicious server client से destination directory के बाहर arbitrary files लिखवा सकता है
    • हमला --inc-recursive mode में कई file lists भेजकर किया जाता है: पहली list में symlink को directory की तरह दिखाया जाता है, और अगली list में उसी नाम को destination directory के बाहर इंगित करने वाले symbolic link में बदल दिया जाता है
    • Go अपने-आप इस vulnerability को नहीं रोकता; कारण यह logic error है कि कई file lists को merge करने के बाद दोबारा validation नहीं की गई
    • upstream fix ने missing validation जोड़ी
    • gokrazy/rsync incremental recursion mode (--inc-recursive) implement नहीं करता, इसलिए यह प्रभावित नहीं है
    • incremental recursion पूरे file set को transfer शुरू होने से पहले scan किए बिना “windowed” तरीके से process करने देता है, लेकिन इसमें implementation complexity और resource usage के बीच trade-off है
  • CVE-2024-12088: --safe-links bypass, गंभीरता 7.5

    • Google Security report के अनुसार, --safe-links एक feature है जो server से मिले symbolic links को validate करता है कि वे destination directory के अंदर ही point करें
    • bypass इसलिए हुआ क्योंकि symbolic link target path के बीच में मौजूद दूसरे symbolic links को ध्यान में नहीं रखा गया
    • उदाहरण के लिए, अगर {DESTINATION}/a -> . और {DESTINATION}/foo -> a/a/a/a/a/a/../../ हों, तो foo वास्तव में destination directory के बाहर point करता है, लेकिन unsafe_symlink() a/ को directory मानकर उसे safe समझता है
    • upstream fix ने unsafe_symlink() को अधिक सख्त बनाया ताकि path की शुरुआत को छोड़कर बाकी जगह ../ की अनुमति न हो
    • Go अपने-आप गलत validation function को नहीं रोकता, और gokrazy/rsync ने अभी तक --safe-links feature implement नहीं किया है, इसलिए यह vulnerable नहीं है
  • CVE-2024-12086: arbitrary file leak, गंभीरता 6.8

    • client mode में rsync receiver ने rsync sender द्वारा दिए गए file names को sanitize नहीं किया, और destination tree के बाहर की files खुलने से नहीं रोका
    • malicious sender receiver को destination tree के बाहर किसी arbitrary file के checksums compare करने का निर्देश दे सकता था, और 1-byte checksum पर receiver की प्रतिक्रिया देखकर arbitrary file leak कर सकता था
    • Google Security report के अनुसार, अगर client malicious server से connect करे, तो server client machine की arbitrary files की contents leak कर सकता है
    • upstream fix ने sender-provided paths को validate करके destination tree के बाहर files खुलने से रोका
    • Go में इसे रोकने के लिए API मौजूद है, और संबंधित defense के रूप में Go का os.Root बताया गया है
    • gokrazy/rsync protocol version 29 नहीं बल्कि protocol version 27 implement करता है, जिसमें fuzzy matching feature जोड़ा गया था, इसलिए यह vulnerable नहीं है
  • CVE-2024-12747: symbolic link race condition, गंभीरता 5.6

    • Red Hat Security Advisory के अनुसार, यह rsync की symbolic link handling के दौरान race condition से पैदा हुई खामी है
    • rsync का default behavior symbolic links मिलने पर उन्हें skip करना है, लेकिन हमलावर सही समय पर सामान्य file को symbolic link में बदलकर इस default behavior को bypass कर सकता था, जिससे symbolic link traversal संभव हो जाता था
  • upstream सुधार ने rsync sender की open() कॉल को O_NOFOLLOW विकल्प इस्तेमाल करने के लिए बदला

    • gokrazy/rsync commit 1b1fbf6 से पहले तक प्रभावित था, और इस commit ने upstream rsync जैसी O_NOFOLLOW mitigation जोड़ी
    • Damien Neil का मानना था कि gokrazy का CVE-2024-12747 fix पर्याप्त नहीं था, और उनके अनुसार O_NOFOLLOW केवल आखिरी path component में symbolic link traversal को रोकता है
    • उदाहरण के लिए, os.Open("dir/passwd") में अगर पहले वाले path component dir को /etc की ओर जाने वाले symbolic link से बदल दिया जाए, तो इसे अब भी bypass किया जा सकता है
    • इस समस्या की रिपोर्ट अप्रैल 2025 में rsync security contact को की गई थी, और इसके परिणामस्वरूप CVE-2026-29518 सामने आया, जिसे 2026-05-20 को सार्वजनिक किया गया

मई 2026 की vulnerabilities

  • CVE-2026-29518: symbolic link race condition, गंभीरता 7.0

    • rsync 3.4.3 NEWS entry के अनुसार, यह chroot के बिना daemon mode में local privilege escalation की अनुमति देने वाली TOCTOU symbolic link race condition है
    • use chroot = no पर configured rsync daemon parent path component के लिए time-of-check/time-of-use race के संपर्क में आता है
    • मॉड्यूल पर write access वाला local attacker receiver की जांच और open() के बीच parent directory component को symbolic link से बदल सकता है, जिससे read में basis-file disclosure और write में module के बाहर file overwrite हो सकता है
    • डिफ़ॉल्ट use chroot = yes इससे प्रभावित नहीं है
    • upstream fix Go के os.Root API जैसा secure_relative_open() इस्तेमाल करता है
    • gokrazy/rsync sender और receiver को traversal-resistant os.Root API पर स्विच करने से पहले vulnerable था
  • CVE-2026-43618: integer overflow से remote memory disclosure, गंभीरता 8.1

    • rsync receiver का compression token decoder 32-bit signed counter को overflow check के बिना accumulate करता है, जिससे malicious sender process memory content leak कर सकता है
    • leak होने वाले data में environment variables, passwords, heap और library pointers शामिल हो सकते हैं, जिससे ASLR कमजोर पड़ सकता है और आगे के exploits आसान हो सकते हैं
    • प्रभाव का दायरा compression enabled authenticated daemon connections तक सीमित है, और protocol 30 या उससे ऊपर में अगर दोनों peers compression advertise करते हैं तो यह डिफ़ॉल्ट रूप से enabled होता है
    • workaround के तौर पर rsyncd.conf में refuse options = compress से daemon compression disable किया जा सकता है
    • upstream fix missing checks जोड़ता है
    • gokrazy/rsync compression implement नहीं करता, इसलिए यह प्रभावित नहीं है, और compression support ऊपर से सरल दिखने के बावजूद इसके non-trivial कारण gokrazy/rsync issue #35 में संक्षेपित हैं
  • CVE-2026-43620: out-of-bounds read के बाद denial of service, गंभीरता 6.5

    • 2025 में send_files() में जोड़ा गया parent_ndx<0 guard देखने में समान recv_files() block पर लागू नहीं किया गया, इसी से यह समस्या हुई
    • malicious rsync server अगर CF_INC_RECURSE compatibility flag और malformed flist भेजे, तो receiver dir_flist->files[-1] को पढ़ और dereference कर सकता है, जिससे deterministic SIGSEGV हो सकता है
    • इसका प्रभाव attacker-controlled URL से सामान्य pull करने वाले सभी rsync clients पर पड़ता है, और protocol 30+ में default inc_recurse के कारण victim side पर किसी special option की जरूरत नहीं होती
    • client पर --no-inc-recursive इस्तेमाल करना workaround है, और upstream fix recv_files() में भी parent_ndx<0 guard जोड़ता है
    • gokrazy/rsync --inc-recursive incremental recursive mode implement नहीं करता, इसलिए CVE-2024-12087 की तरह यह भी प्रभावित नहीं है
  • CVE-2026-43619: अतिरिक्त symbolic link race condition, गंभीरता 6.3

    • receiver के open() call के लिए symbolic link race condition fix (CVE-2026-29518) chmod, lchown, utimes, rename, unlink, mkdir, symlink, mknod, link, rmdir, lstat जैसे दूसरे path-based system calls पर लागू नहीं किया गया था
    • use chroot = no से configured rsync daemon में local attacker receiver की जांच और system call के बीच parent directory component को symbolic link से बदलकर exported module के बाहर redirect कर सकता है
    • डिफ़ॉल्ट use chroot = yes इससे प्रभावित नहीं है
    • upstream fix Linux 5.6+ पर openat2, FreeBSD 13+ और macOS 15+ पर O_RESOLVE_BENEATH, और बाकी environments में component-by-component O_NOFOLLOW traversal जैसे kernel-enforced restrictions के तहत खुले parent dirfd के जरिए प्रभावित path-based system calls को संभालता है
    • gokrazy/rsync पूरे तौर पर Go के os.Root API का इस्तेमाल करता है, इसलिए यह प्रभावित नहीं है
  • CVE-2026-43617: hostname-based ACL bypass, गंभीरता 4.8

    • global daemon chroot = /X rsyncd.conf setting वाले rsync daemon में connecting client की reverse DNS lookup daemon के /X पर chroot होने के बाद की जाती थी
    • अगर /X में glibc resolution के लिए जरूरी /etc/resolv.conf, /etc/nsswitch.conf, /etc/hosts, NSS service modules न हों, तो lookup fail हो जाती है और connecting hostname "UNKNOWN" पर सेट हो जाता है
    • hosts deny = *.evil.example जैसे hostname-based deny rules match नहीं होते, जिससे PTR record नियंत्रित करने वाला attacker उस hostname से connect कर सकता है जिसे admin block करना चाहता था
    • IP-based ACL प्रभावित नहीं हैं, और per-module use chroot settings का इस vulnerability से कोई संबंध नहीं है
    • upstream fix DNS lookup को protocol के शुरुआती चरण में ले जाता है
    • gokrazy/rsync hostname-based allow/deny lists implement नहीं करता और सिर्फ IP-based allow/deny lists implement करता है, इसलिए यह vulnerable नहीं है
  • CVE-2026-45232: stack out-of-bounds write, गंभीरता 3.1

    • rsync client के HTTP CONNECT proxy support में establish_proxy_connection() में off-by-one stack out-of-bounds write है
    • proxy या man-in-the-middle attacker अगर पहली response line में '\n' के बिना 1023 bytes या उससे अधिक लौटाए, तो बाद का code 1024-byte buffer के ठीक बाद '\0' लिख सकता है, जिससे पास का stack slot corrupt हो सकता है
    • AddressSanitizer establish_proxy_connection frame के socket.c:95 पर stack-buffer-overflow report करता है
    • upstream fix attacker-provided data को validate करता है
    • gokrazy/rsync ऐसा proxy support implement नहीं करता, इसलिए यह vulnerable नहीं है

Go और gokrazy/rsync ने वास्तव में क्या रोका

  • Go runtime की boundary checks ज़्यादा गंभीर security issues को panic में बदल देती हैं, और panic अभी भी denial-of-service का जोखिम है, लेकिन इसे बेहतर failure mode माना जाता है
  • Go memory को 0 से initialize करता है, जिससे CVE-2024-12085 जैसे information leak असंभव हो जाते हैं
  • Go का os.Root API बची हुई ज़्यादातर vulnerabilities को रोकता है
  • 12 vulnerabilities में से सिर्फ CVE-2026-43617 को ऐसा application logic bug माना गया जिसे Go इस्तेमाल करने भर से नहीं रोका जा सकता
  • gokrazy/rsync और official upstream rsync के बीच मुख्य अंतर सिर्फ यह नहीं है कि यह Go में लिखा गया है, बल्कि यह भी है कि इसका implementation minimal रखा गया है
  • gokrazy/rsync --inc-recursive, --safe-links, compression, proxy, hostname ACL जैसी कई problem-causing features को implement नहीं करता, इसलिए यह कई vulnerabilities से बच जाता है
  • सभी wire protocol-compatible rsync implementations की तरह gokrazy/rsync protocol version 27 को target करता है, और इसके बाद के protocol versions काफ़ी complexity जोड़ते हैं
  • प्रकाशन के समय के आधार पर CVE के अनुसार gokrazy/rsync की स्थिति:
    • 2024-12084: implementation मौजूद था और panic हुआ
    • 2024-12085: protocol 30 feature होने के कारण implement नहीं किया गया, इसलिए vulnerable नहीं
    • 2024-12086: protocol 29 feature होने के कारण implement नहीं किया गया, इसलिए vulnerable नहीं
    • 2024-12087: inc-rec implement नहीं किया गया, इसलिए vulnerable नहीं
    • 2024-12088: safe-links implement नहीं किया गया, इसलिए vulnerable नहीं
    • 2024-12747: implementation मौजूद था और vulnerable था
    • 2026-29518: implementation मौजूद था और patch किया गया
    • 2026-43617: host deny list implement नहीं की गई, इसलिए vulnerable नहीं
    • 2026-43618: compression implement नहीं किया गया, इसलिए vulnerable नहीं
    • 2026-43619: implementation मौजूद था और patch किया गया
    • 2026-43620: inc-rec implement नहीं किया गया, इसलिए vulnerable नहीं
    • 2026-45232: proxy implement नहीं किया गया, इसलिए vulnerable नहीं
  • gokrazy/rsync की सभी ज्ञात vulnerabilities ठीक कर दी गई हैं, और ऊपर दी गई स्थिति वह है जो हर CVE के public होने के समय लागू थी
  • जनवरी 2025 में vulnerabilities के public होने के समय gokrazy/rsync में CVE-2024-12084 पर panic होता था और यह CVE-2024-12747 TOCTOU race condition के प्रति vulnerable था
  • TOCTOU issue को ठीक करने की प्रक्रिया में CVE-2026-29518 मिला, और यह CVE public होने से पहले ही gokrazy/rsync में ठीक कर दिया गया
  • CVE-2026-43619 बाद में मिला, लेकिन Go के os.Root के पूर्ण उपयोग वाले उसी fix से यह gokrazy/rsync में पहले ही सुलझ चुका था

भूमिकाओं का विभाजन और vulnerabilities के नाम

  • कई vulnerability reports में “server” और “client” शब्दों का उपयोग किया गया, लेकिन rsync transfer में rsync client और server दोनों ही sender (फ़ाइल upload) या receiver (फ़ाइल download) की भूमिका निभा सकते हैं
  • daemon mode में filesystem access को पहले से configured module path तक सीमित किया जा सकता है, लेकिन command mode में ऐसा नहीं होता
  • 4 configurations और role/protocol layer को rsync combinations diagram में देखा जा सकता है
  • Arbitrary File Leak vulnerability (CVE-2024-12086) का मूल शीर्षक “Server leaks arbitrary client files” आसानी से भ्रम पैदा कर सकता है
  • ज़्यादा सटीक अभिव्यक्ति यह है कि rsync receiver malicious sender को arbitrary files leak करता है
  • command mode over SSH जैसे माहौल में एक malicious client sender unpatched remote rsync से target tree के बाहर की files खुलवा सकता है, जैसे /etc/shadow system password database
  • daemon mode में server अतिरिक्त path sanitization enable करके इस attack को रोकता है
  • Symlink Path Traversal vulnerability (CVE-2024-12087) को भी “malicious server” कहा जाता है, लेकिन सही अर्थ में यह malicious sender होता है, जो client या server कोई भी हो सकता है

OpenBSD openrsync से तुलना

  • OpenBSD project security पर फ़ोकस के लिए जाना जाता है, और openrsync checksum length को validate करता है तथा checksum size/algorithm के लिए सिर्फ MD4 को support करता है, इसलिए यह Heap Buffer Overflow (CVE-2024-12084) और Stack Info Leak (CVE-2024-12085) से प्रभावित नहीं होता
  • openrsync, gokrazy/rsync की तरह, संबंधित features implement नहीं करता, इसलिए यह CVE-2024-12086, CVE-2024-12087, CVE-2024-12088 से प्रभावित नहीं होता
  • अगर यह vulnerable भी होता, तो OpenBSD पर चलते समय OpenBSD unveil(2) और pledge(2) के ज़रिए filesystem access को सीमित करने वाली defense in depth सफल exploitation को रोक सकती थी
  • openrsync symbolic link support implement करते ही O_NOFOLLOW का उपयोग करता आया है, इसलिए यह CVE-2024-12747 से प्रभावित नहीं होता
  • लेकिन O_NOFOLLOW इस समस्या के लिए पर्याप्त fix नहीं है, इसलिए openrsync CVE-2026-29518 से प्रभावित होता है
  • मई 2026 वाले bundle के मामले में भी स्थिति मिलती-जुलती है, क्योंकि ज़्यादातर संबंधित features implement नहीं किए गए थे
  • openrsync validation को सावधानी से implement करता है, attack surface को सीमित रखता है, और defense in depth लागू करता है, इसलिए reported vulnerabilities में से अधिकांश का इस पर असर नहीं पड़ता

Defense in depth और os.Root

  • Linux mount namespace

    • gokrazy/rsync प्रोजेक्ट शुरू करने के कुछ ही हफ्तों के भीतर, फ़ाइलसिस्टम ऑब्जेक्ट एक्सेस को सीमित करने के लिए Linux में privilege dropping और mount/pid namespace के उपयोग का समर्थन करने वाली सुविधा जोड़ी गई
    • यह तरीका path traversal attacks को कम करने में अच्छी तरह काम करता है, लेकिन इसके लिए privileges चाहिए, इसलिए इसे root के रूप में चलाना पड़ता है या यदि distro/system में सक्षम हो तो Linux user namespace के अंदर चलाना पड़ता है
    • mount namespace server configuration के लिए उपयुक्त है, लेकिन आम यूज़र अकाउंट से चलने वाले interactive one-off transfers में इसे अक्सर इस्तेमाल नहीं किया जा सकता
  • systemd hardening

    • Linux mount/pid namespace support लाने वाले उसी commit में एक systemd service file भी शामिल थी, जो फ़ाइलसिस्टम एक्सेस को home directory तक सीमित करती थी, और README में use case के अनुसार फ़ाइलसिस्टम एक्सेस को और सीमित करने की सिफारिश की गई थी
    • जब ऐसे फ़ाइलसिस्टम restrictions सही तरह से configure किए जाएँ, तो वे File Leak (CVE-2024-12086) और Path Traversal (CVE-2024-12087) vulnerabilities को कम करते हैं
    • Symlink Race Condition (CVE-2024-12747) rsync process के जरिए privilege escalation पर निर्भर करता है, लेकिन DynamicUser फीचर की वजह से process के पास दूसरे users की तुलना में कम privileges होते हैं
    • mount namespace की तरह, यह server configuration के लिए अच्छा है, लेकिन interactive one-off use के लिए configure करना झंझटभरा है
  • Linux Landlock

    • Porting OpenBSD pledge() to Linux (2022) के जरिए यह फिर याद आया कि Linux में भी OpenBSD के unveil(2) जैसा बिना privilege वाला, per-process access control Landlock API मौजूद है
    • मूल विचार यह है कि एक बार प्रोग्राम को पता हो कि वह किस directory पर काम करेगा, तो unveil("/home/michael/backups", "rw"); जैसी call के जरिए उसे उस path के बाहर की फ़ाइलसिस्टम locations तक पहुँचने से रोका जा सकता है
    • मार्च 2025 में फ़ाइलसिस्टम एक्सेस को सीमित करने के लिए Landlock support implement किया गया
    • configuration तय हो जाने के बाद, बिना privilege वाले gokrazy/rsync execution में भी rsync transfer को source पर read-only और destination directory पर read-write permissions तक सीमित किया जा सकता है
    • इसकी कमी यह है कि Landlock process level पर काम करता है
    • Landlock policy में वे files भी शामिल करनी पड़ती हैं जिनकी program को ज़रूरत होती है; उदाहरण के लिए gokrazy/rsync को user ID lookup के लिए /etc/passwd पढ़ना पड़ता है, इसलिए अगर attacker /etc/passwd को target करे तो Landlock मदद नहीं करेगा
  • Go का os.Root

    • फरवरी 2025 में Go 1.24 ने path traversal के प्रति resistant os.Root API पेश किया, और इसकी पृष्ठभूमि Damien Neil की The Go Blog: Traversal-resistant file APIs में संक्षेपित है
    • os.Root, Landlock की तुलना में, हर फ़ाइलसिस्टम operation पर अधिक granular control देता है
    • अगस्त 2025 में जारी Go 1.25 ने os.Root में और methods जोड़े, जिससे यह अधिकतर फ़ाइलसिस्टम usage के लिए एक सुविधाजनक विकल्प बन गया
    • gokrazy/rsync के सभी फ़ाइलसिस्टम usages को os.Root में migrate कर दिया गया, और यह उस मॉडल के लिए अच्छी तरह उपयुक्त है जिसमें यूज़र input/output directories configure करता है, लेकिन network से मिले filenames पर भरोसा नहीं किया जा सकता
    • mknod(2) जैसे system calls, जिन्हें API से सीधे बनाना संभव नहीं लगता, उन्हें भी सुरक्षित रूप से इस्तेमाल किया जा सकता है
    • Damien Neil बताते हैं कि os.Root.OpenFile से target की parent directory खोलकर, File.Fd से उस directory का file descriptor लेकर, फिर golang.org/x/sys/unix#Mknodat से file बनाई जा सकती है
    • इसका वास्तविक उपयोग उदाहरण internal/receiver/generatormknod_linux.go, line 15-29 में है
    • Linux में mknodat(2) तो है, लेकिन Linux 7.0 के अनुसार bind(2) के अनुरूप bindat नहीं है
    • Lennart Poettering ने सुझाव दिया कि bindat के बिना path resolution को bypass करने की एक तरकीब के रूप में /proc/self/<fd>/foobar पर bind किया जा सकता है
    • ज्ञात रूप से सुरक्षित /proc/self/<fd> के बाद path नहीं बल्कि basename, यानी आख़िरी path component ही निर्दिष्ट किया जाए, तो path resolution bypass हो जाता है; संबंधित code line 49-56 में है
    • इन दो tips की मदद से gokrazy/rsync v0.3.1 और उसके बाद के versions os.Root का पूरी तरह उपयोग करते हैं, और सभी फ़ाइलसिस्टम accesses में path traversal safety होती है

मुख्य सीख

  • TOCTOU vulnerabilities (CVE-2024-12747, CVE-2026-29518, CVE-2026-43619) को छोड़कर बाकी सभी vulnerabilities input validation की कमी या गलत input validation से पैदा हुईं
  • तीन मामलों में शुरू से validation था ही नहीं, और CVE-2024-12088 में फ़ाइलसिस्टम path resolution का विषय इतना पेचीदा था कि मौजूदा validation सभी edge cases को कवर नहीं कर पाया
  • सबसे मूल्यवान structural fixes वे हैं जो हमेशा चालू रहने वाली validation, जैसे bounds checks, और Go के os.Root जैसी safe-by-default APIs उपलब्ध कराएँ
  • कुछ vulnerabilities rsync protocol के evolution से पैदा हुईं; मूल रूप से पर्याप्त validation करने वाले code में नई features जुड़ती गईं, लेकिन validation को सही तरह से update नहीं किया गया
  • checksum algorithm negotiation और incremental recursion protocol version 30 में जोड़े गए थे, और मौजूदा validation को नई features की handling के हिसाब से update नहीं किया गया
  • gokrazy/rsync और openrsync 12 security vulnerabilities में से 8 के प्रति सिर्फ इसलिए vulnerable नहीं थे क्योंकि उन्होंने vulnerable features implement ही नहीं किए थे
  • वे features किसी समय किसी के लिए उपयोगी रहे होंगे, तभी rsync में जोड़े गए; इसका मतलब यह नहीं है कि software development रोक देना चाहिए
  • आदर्श विकल्प यह है कि use case की complexity के अनुरूप implementation complexity चुनी जाए—साधारण use cases के लिए साधारण implementation, और केवल ज़रूरत पड़ने पर full-featured implementation चुना जाए

1 टिप्पणियां

 
GN⁺ 3 시간 전
Lobste.rs की टिप्पणियाँ
  • बेहतरीन लेख है। यह इतना अच्छा है कि हर भाषा की standard library में os.Root जैसी API होनी चाहिए
    SecureDrop में कुछ बार path traversal vulnerability झेलने के बाद मैंने इसका एक बहुत सरल version इस्तेमाल किया, और अब सही API का उपयोग करने पर vulnerabilities की एक पूरी श्रेणी ही खत्म हो जाती है
    • सही बात। लगता है इस ब्लॉग पोस्ट का असली नायक Go नहीं, बल्कि os.Root है