audit-ci ile JavaScript Bağımlılıklarında Zafiyet Taraması Yapmak

Tuğsan Ünlü
Akbank Teknoloji
Published in
5 min readSep 13, 2023

--

Motivasyon

Platform veya teknoloji fark etmeksizin, geliştirdiğimiz projelerde üçüncü parti paketlere sıklıkla başvuruyoruz. Bunu yaparken, kod tekrarını önlemek, geliştirilen birden fazla proje için benzer/aynı araçları kullanmak, genel ihtiyaçlar için özel çözümler üretmek yerine, uzun süredir canlı ortamlarda sorunsuz şekilde çalışan, topluluk desteği olan muadil çözümleri tercih etmek gibi farklı amaçlarımız olabiliyor.

Projemize dâhil ettiğimiz bu bağımlılıkları ve beraberindeki alt bağımlılıklarını düzenli olarak veya bir uyaran sonrasında güncellemediğimiz takdirde, o bağımlılıklardan doğacak tüm riskleri peşinen kabul etmiş oluyoruz. İdeali, düzenli olarak yapacağımız yükseltmelerle bağımlılıklarımızı güncel tutmak olsa da maalesef gerçek hayat şartlarında bu her zaman mümkün olmayabiliyor. Kullandığımız üçüncü parti paketlerin birbirleriyle uyumu, majör sürüm değişiklikleri sonrasındaki gerekecek kod değişiklikleri, değişiklikler sonrasında oluşacak regresyon test maliyetleri sebebiyle sürüm yükseltmeleri bilinmez bir ileri tarihe ötelenebiliyor.

Bu durumda, kullandığımız paketleri belli kriterlere uymadıkları koşullarda güncellemek alternatif bir yöntem olarak karşımıza çıkıyor.

Zafiyetli Paketin Yaşam Döngüsü

Bir gerçek hayat örneği üzerinden açıklarsak, geliştirmek istediğimiz yönetim paneli projesinde React ile sıfırdan bir mimari kurgulamak istemedik ve react-admin framework’ünü kullanmaya karar verdik diyelim. Bu kararı aldığımızda react-admin’in en güncel sürümü olan 4.0.0'ı projemize dahil ettik ve kullanmaya başladık.

Aradan aylar geçti, react-admin’i geliştiren topluluk, framework’deki güvenlik zafiyetlerini bir bir bulup kapatmaya başladı. Bunlardan bir tanesi de RichTextField isimli arayüz component’inde XSS (Cross-Site Scripting)’e neden olan zafiyetti. Topluluk zafiyeti fark edince hızlıca harekete geçip 4.7.6 sürümünde zafiyeti kapattı. Fakat bizim bu zafiyetin varlığından dahi haberimiz yok henüz. Halbuki tüm bu süreç şeffaf bir şekilde yaşandı. Peki ne oldu?

Zafiyeti fark eden Francois Zaninotto isimli geliştirici, GitHub’daki projede zafiyeti kapatacak geliştirmeyi yapıp bir PR (pull request) açtı. Bu PR’da zafiyetin ne olduğunu, nasıl çözdüğünü ve zafiyetsiz halinin paketin hangi sürümüyle birlikte yayımlanacağını belirtti. Kodu diğer arkadaşları tarafından incelendi ve kabul edildi.

https://github.com/marmelab/react-admin/pull/8644

Akabinde, Francois Zaninotto topluluğa duyurmak üzere yine projenin GitHub sayfasında bir güvenlik duyurusu yayımladı. Burada PR’dakilerin yanı sıra zafiyetten hangi sürüm aralıklarının etkilendiği ve öncelik seviyeleri gibi detay bilgileri de paylaştı. GitHub bu aşamada zafiyete özel, eşsiz bir ID ataması (Üstteki zafiyet için GHSA-5jcr-82fh-339v) yapıyor. Bu ID ile de zafiyetin durumu takip edilebiliyor.

https://github.com/marmelab/react-admin/security/advisories/GHSA-5jcr-82fh-339v

Tabii projemizde kullandığımız yüzlerce bağımlılık için bu duyuruları tek tek takip edip harekete geçmemiz mümkün değil. Onun yerine paket yöneticilerinin sağladığı audit araçlarıyla projemizin belli koşullardan alarm oluşturmasını sağlayabiliriz.

audit-ci

audit-ci, ufak ve pratik bir CLI (Command Line Interface) aracı. JavaScript ekosistemindeki projelerde kullandığımız üçüncü parti paketlerdeki bilinen güvenlik zafiyetlerini taramamızı sağlıyor.

Aslında her paket yöneticisinin npm-audit, yarn audit gibi bir zafiyet denetim aracı bulunuyor. Fakat audit-ci, hem farklı paket yöneticileriyle çalışabilmesi hem de sağladığı diğer kullanışlı özelliklerden dolayı tercih ediliyor.

Kullanmaya başlamak için audit-ci’ı bir geliştirme ortamı bağımlılığı olarak kuruyoruz.

Kurulum

Akabinde hiçbir yapılandırmaya ihtiyaç duymadan, yalnızca bağımlılıklarımızdaki hangi seviyedeki zafiyetleri yakalamak istediğimizi belirtiyoruz. Önem derecesine göre sırasıyla low, moderate, high ve critical değerlerini kullanabiliyoruz.

CLI argümanlarıyla çalıştırma

Bunun sonrasında audit-ci, projemizdeki tüm bağımlılıkları tarayacak ve moderate ve üstü seviyede bir zafiyet tespit ettiği takdirde bizi aşağıdaki gibi bir çıktıyla uyaracak.

Sonuç çıktısı

Yapılandırma Dosyası Oluşturmak

Üstteki gibi CLI argümanlarını kullanmak yerine bir yapılandırma dosyası oluşturup audit-ci’ın ona bakmasını da sağlayabiliriz. Bunun için .jsonc uzantılı bir dosya oluşturuyoruz. .jsonc, bildiğimiz JSON veri formatının içerisine yorum satırları da yazılabilen bir versiyonu.

audit-ci.jsonc
Yapılandırma dosyasıyla çalıştırma

Sonrasındaki tüm taramalarımızı — config argümanına oluşturduğumuz yapılandırma dosyasının yolunu vererek yapabiliriz.

İstisna Tanımlamak

audit-ci’ın en kullanışlı özelliklerinden birisi de bir paketin tamamına veya paket içerisindeki bir zafiyete süreli veya süresiz olarak istisna tanımlayabilmek. Özellikle CI (Continuous Integration) entegrasyonlarında ihtiyaç duyulan bu özellik sayesinde sorumluluğunu kabul ederek iş akışlarınızın kesilmemesini sağlayabiliyoruz.

Zafiyet istisnası

Bunun için doğrudan zafiyetin eşsiz ID’sini kullanabiliyoruz.

Belli tarihli paket istisnası

Ayrıca paketin tamamının belirli bir tarihe kadar audit-ci tarafından göz ardı edilmesini de sağlayabiliyoruz.

output-format

audit-ci, varsayılan olarak metin bazlı bir çıktı veriyor. Fakat çıktının gözle okunması yerine farklı araçlarca işlenmesine ihtiyaç duyulduğunda JSON çıktısını da kullanabiliyoruz.

retry-count

Zaman zaman kesintiler sebebiyle paket yöneticilerinden veya zafiyet taramalarından istenilen bilgilerin alınamadığı durumlarda iş akışlarımız durabiliyor. Bu gibi sorunlar yaşamamak için herhangi bir hata alınması durumunda retry-count ile işlemin kaç defa daha tekrar edileceğini belirleyebiliyoruz.

skip-dev

Yukarıdaki örneklerde uygulamamız içerisindeki tüm bağımlılıklarda zafiyet taraması yaptırdık. Fakat kimi durumlarda geliştirme ortamındaki bağımlılıkların es geçilip yalnızca canlı ortamdaki bağımlılıklarda zafiyet taraması yapılmasını skip-dev ile sağlayabiliyoruz.

Sonuç

audit-ci, projelerin özellikle CI (Continuous Integration) süreçlerine ve Git hook’larıyla geliştirme ortamlarına dahil edildiğinde, insan kaynaklı ihmalleri olabildiğince ortadan kaldıran ve üçüncü parti paket kullanımında hakimiyet sağlayan bir CLI aracı. Kurulum ve yapılandırmasının pratikliğinden dolayı tak-çalıştır şeklinde geliştirmesi devam eden mevcut projelere eklenebilmesi, alarm kurallarının esnetilebilmesi, çıktıları sayesinde farklı güvenlik araçlarıyla iletişim kurabilmesi ise diğer iyi özelliklerinden bazıları.

Bir sonraki yazımızda görüşmek üzere…

Kaynaklar

--

--