En İyi Canlı Ortam Pratikleri: Güvenlik
Genel Bakış
“canlı ortam” terimi, bir uygulama veya API’nin genel olarak son kullanıcıları veya tüketicileri için hazır olduğu yazılım yaşam döngüsündeki aşamayı ifade eder. Buna kıyasla, “geliştirme” aşamasında aktif olarak kod yazıyor ve test ediyorsunuz, ve uygulama dış erişime açık değildir. Bunlara karşılık gelen sistem ortamları sırasıyla canlı ortam (production) ve geliştirme (development) ortamları olarak bilinir.
Canlı ve geliştirme ortamları genel olarak farklı şekilde kurulurlar ve çok farklı gereksinimleri vardır. Geliştirme ortamında iyi olan bir şey canlı ortamda kabul edilebilir olmayabilir. Örneğin, geliştirme ortamında hata ayıklama için ayrıntılı hataların loglanmasını isteyebilirsiniz, ancak aynı şey canlı ortamda güvenlik açığı oluşturabilir. Ve geliştirme ortamında ölçeklenebilirlik, güvenilirlik ve performans hakkında endişe etmenize gerek yok iken, bu konular canlı ortamda kritikleşir.
Note
Express’te bir güvenlik açığı keşfettiğinizi düşünüyorsanız, lütfen bakınız Güvenlik Politikaları ve Prosedürleri.
Canlı ortamdaki Express uygulamaları için en iyi güvenlik pratikleri:
- Express’in kullanımdan kaldırılmış veya bakımı yapılmayan versiyonlarını kullanmayın
- TLS kullanın
- Helmet kullanın
- Çerezleri güvenli kullanın
- Otorizasyona karşı yapılan brute-force saldırılarını engelleyin
- Bağımlılıklarınızın güvende olduğundan emin olun
- Bilinen diğer güvenlik açıklarından kaçının
- Ek hususlar
Express’in kullanımdan kaldırılmış veya bakımı yapılmayan versiyonlarını kullanmayın
Express 2.x ve 3.x versiyonlarının bakımı artık yapılmıyor. Bu versiyonlardaki güvenlik ve performans sorunları çözülmeyecek. Bunları kullanmayın! 4. versiyona henüz geçmediyseniz, taşıma rehberini takip edin.
Ayrıca güvenlik güncellemeleri sayfası‘nda listelenen bakımı yapılmayan herhangi bir Express versiyonunu kullanmadığınızdan emin olun. Eğer kullanıyorsanız, stabil versiyonlardan birine geçin, tercihen en son versiyona.
TLS kullanın
Uygulamanız hassas verilerle ilgileniyor veya bunları iletiyorsa, veri ve bağlantıyı güvende tutmak için Transport Layer Security (TLS) kullanın. Bu teknoloji, verileri istemciden sunucuya gönderilmeden önce şifreler ve böylelikle bazı yaygın (ve kolay) saldırıları önler. Ajax ve POST istekleri gözle görülür şekilde açık olmayabilir ve tarayıcılarda “gizli” görünebilir, ancak bunların ağ trafiği packet sniffing ve man-in-the-middle saldırılarına karşı korumasızdır.
Secure Socket Layer (SSL) şifrelemesine aşina olabilirsiniz. TLS, SSL’nin bir sonraki geçişidir. Bir başka deyişle, daha önce SSL kullanıyorsanız TLS’e yükseltmeyi düşünün. Genel olarak, TLS kullanmak için Nginx öneririz. Nginx’te (ve diğer sunucularda) TLS’yi yapılandırmak için, bakınız Önerilen Sunucu Yapılandırmaları (Mozilla Wiki).
Ayrıca, Internet Security Research Group (ISRG) tarafından sunulan ücretsiz, otomatik, ve açık bir sertifika yetkilisi (CA - Certificate Authority) olan Let’s Encrypt ücretsiz bir TLS sertifikası alabileceğiniz araçtır.
Helmet kullanın
Helmet, HTTP başlıklarını doğru ayarlayarak uygulamanızı bazı iyi bilinen web güvenlik açıklarına karşı koruyabilir.
Helmet aslında güvenlikle ilgili HTTP yanıt başlıklarını ayarlayan, daha küçük ara yazılım (middleware) fonksiyonlarından oluşan bir koleksiyondur:
- csp siteler arası (cross-site) komut dosyası çalıştırma saldırılarını ve diğer siteler arası enjeksiyonları önlemeye yardımcı olmak için
Content-Security-Policy
başlığını ayarlar. - hidePoweredBy
X-Powered-By
başlığını kaldırır. - hsts sunucuya güvenli (SSL/TLS üzerinden HTTP) bağlantıları zorunlu kılan
Strict-Transport-Security
başlığını ayarlar. - ieNoOpen IE8+ için
X-Download-Options
başlığını ayarlar. - noCache istemci-taraflı önbelleğe alma (caching) işlevini devre dışı bırakmak için
Cache-Control
ve Pragma başlıklarını ayarlar. - noSniff tarayıcıların bildirilen içerik türünden farklı, bir sunucu yanıtına MIME-sniffing uygulanmasını önlemek için
X-Content-Type-Options
başlığını ayarlar. - frameguard clickjacking koruması sağlamak için
X-Frame-Options
başlığını ayarlar. - xssFilter siteler arası komut çalıştırma (Cross-site scripting (XSS)) filtresini en yeni tarayıcılarda etkinleştirmek için
X-XSS-Protection
başlığını ayarlar.
Helmet’ı diğer herhangi bir modül gibi kurun:
$ npm install --save helmet
Daha sonra kodunuzda kullanmak için:
// ...
const helmet = require('helmet')
app.use(helmet())
// ...
En azından, X-Powered-By başlığını devre dışı bırakın
Eğer Helmet kullanmak istemiyorsanız, o zaman en azından X-Powered-By
başlığını devre dışı bırakın. Saldırganlar, Express çalıştıran uygulamaları tespit etmek ve ardından özel olarak hedeflenen saldırılar başlatmak için bu başlığı (varsayılan olarak etkindir) kullanabilir.
Bu yüzden, app.disable()
metodunu kullanarak bu başlığı devre dışı bırakmak en iyi pratiktir:
app.disable('x-powered-by')
Eğer helmet.js
kullanıyorsanız, bunu sizin için halleder.
Note
X-Powered-By başlığının devre dışı bırakılması, tecrübeli bir saldırganın bir uygulamanın Express çalıştırdığını belirlemesini önlemez. Bu, sıradan bir istismarı engelleyebilir, ancak bir uygulamanın Express çalıştırdığını belirlemenin başka yolları da var.
Çerezleri güvenli kullanın
Çerezlerin uygulamanızı istismarlara açmamasını sağlamak için, varsayılan oturum çerez adını kullanmayın ve çerez güvenlik seçeneklerini uygun şekilde ayarlayın.
İki ana ara yazılım çerez oturum modülü var:
- express-session, Express 3.x versiyonlarında yer alan
express-session
yerleşik (built-in) ara yazılımının yerini alır. - cookie-session, Express 3.x versiyonlarında yer alan
express.cookieSession
yerleşik ara yazılımının yerini alır.
Bu iki modülün arasındaki ana fark, çerez oturum verisinin nasıl kaydedildiğidir. express-session ara yazılımı oturum verisini sunucuda tutar; sadece oturum ID’sini çerezde tutar, oturum verisini değil. Varsayılan olarak, iç-bellek depolamayı kullanır ve canlı ortam için tasarlanmamıştır. Canlı ortamda, ölçeklenebilir bir oturum depolamayı kurmanız gerekecektir; uyumlu oturum depolarını‘nı görmek için bakınız.
Buna kıyasla, cookie-session ara yazılımı çerez-destekli depolamayı uygular: sadece bir oturum anahtarı yerine, tüm oturumu çerezde serileştirir. Bunu yalnızca oturum verileri nispeten küçük olduğunda ve ilkel (primitive) değerler (objeler yerine) olarak kolayca kodlandığında kullanın. Tarayıcıların çerez başına en az 4096 baytı desteklemesine rağmen, limiti aşmamanızdan emin olmak için domain başına 4093 baytı aşmayın. Ayrıca, çerez verilerinin istemciye açık olacağını unutmayın, bu yüzden verilerin güvenli veya gizli olması için herhangi bir neden var ise, express-session daha iyi bir seçenek olabilir.
Varsayılan oturum çerez adını kullanmayın
Varsayılan oturum çerez adı uygulamanızı saldırılara açık bırakabilir. Ortaya çıkan güvenlik sorunu X-Powered-By
sorununa benzer: potansiyel bir saldırgan, sunucunun parmak izini almak ve saldırıları buna göre hedeflemek için kullanabilir.
Bu problemi önlemek için, jenerik çerez adlarını kullanın; örnek olarak express-session ara yazılımının kullanımı:
const session = require('express-session')
app.set('trust proxy', 1)
app.use(session({
secret: 's3Cur3',
name: 'sessionId'
}))
Çerez güvenlik seçeneklerini ayarlayın
Güvenliği artırmak için aşağıdaki çerez seçeneklerini ayarlayın:
secure
- Tarayıcının çerezi yalnızca HTTPS üzerinden göndermesini sağlar.httpOnly
- Çerezin JavaScript istemcisinden değil, yalnızca HTTP(S) üzerinden gönderilmesini sağlar ve böylelikle siteler arası komut dosyası çalıştırma saldırılarına karşı korumaya yardımcı olur.domain
- çerezin alan adını belirtir; URL’nin istendiği sunucunun alan adıyla karşılaştırmak için kullanın. Eğer eşleşiyorsa, ardından yol (path) alanını kontrol edin.path
- çerezin yolunu belirtir; bunu istek yoluyla karşılaştırmak için kullanın. Eğer bu ve alan adı eşleşiyorsa, istekte çerezi gönderebilirsiniz.expires
- kalıcı çerezler için son kullanma tarihini ayarlamak için kullanın.
cookie-session ara yazılımını kullanan bir örnek:
const session = require('cookie-session')
const express = require('express')
const app = express()
const expiryDate = new Date(Date.now() + 60 * 60 * 1000) // 1 saat
app.use(session({
name: 'session',
keys: ['key1', 'key2'],
cookie: {
secure: true,
httpOnly: true,
domain: 'example.com',
path: 'foo/bar',
expires: expiryDate
}
}))
Otorizasyona karşı yapılan brute-force saldırılarını engelleyin
Özel verileri daha güvenli hale getirmek için giriş uç noktalarının (endpoint) korunduğundan emin olun.
Basit ve güçlü bir teknik olarak iki ölçüm kullanarak yetkilendirme girişimlerini engellemektir:
- Birincisi, aynı kullanıcı adı ve IP adresi ile art arda başarısız denemelerin sayısı.
- İkincisi, uzun bir süre boyunca bir IP adresinden başarısız denemelerin sayısıdır. Örneğin, bir IP adresi bir günde 100 başarısız deneme yaparsa engelleyin.
rate-limiter-flexible paketi bu tekniği kolay ve hızlıca uygulamak için gerekli araçları sağlar. brute-force korumasına bir örneği bu dökümantasyonda bulabilirsiniz.
Bağımlılıklarınızın güvende olduğundan emin olun
Uygulamanızın bağımlılıklarını yönetmek için npm kullanmak güçlü ve kullanışlıdır. Ancak kullandığınız paketler, uygulamanızı da etkileyebilecek kritik güvenlik açıkları içerebilir. Uygulamanızın güvenliği, bağımlılıklarınızdaki “en zayıf halka” kadar güçlüdür.
npm@6’dan beri npm otomatik olarak her yükleme isteğini inceler. Ayrıca ‘npm audit’ komutunu kullanarak bağımlılık ağacınızı analiz edebilirsiniz.
$ npm audit
Daha fazla güvenli kalmak istiyorsanız, Snyk aracını gözden geçirebilirsiniz.
Bağımlılıklarınızdaki bilinen tüm güvenlik açıkları için Synk’in açık kaynak güvenlik açığı veritabanı‘na karşı uygulamanızı kontrol eden bir komut satırı aracı ve de Github integrasyonu sunar.
$ npm install -g snyk
$ cd your-app
Uygulamanızı güvenlik açıklarına karşı test etmek için bu komutu kullanın:
$ snyk test
Bilinen diğer güvenlik açıklarından kaçının
Express’i veya uygulamanızın kullandığı diğer modülleri etkileyen Snyk ve Node Security Project tavsiyelerini takipte kalın. Genel olarak, bu veritabanları Node güvenliği hakkında bilgi ve araçlar için mükemmel kaynaklardır.
Son olarak, Express uygulamaları - diğer web uygulamaları gibi - çeşitli web tabanlı saldırılara karşı savunmasız olabilir. Web güvenlik açıkları hakkında kendinizi bilgilendirin ve onlardan kaçınmak için önlemler alın.
Ek hususlar
İşte mükemmel Node.js Güvenlik Kontrol Listesi‘nden bazı ek öneriler. Bu önerilerle ilgili tüm ayrıntılar için o blog gönderisine bakın:
- Siteler arası komut dosyası oluşturma (XSS) ve komut enjeksiyon saldırılarına karşı korumak için kullanıcı girişini her zaman filtreleyin ve sanitize edin.
- Parametreli sorgular veya hazırlanmış ifadeler kullanarak SQL enjeksiyon saldırılarına karşı savunma yapın.
- Uygulamanızdaki SQL enjeksion güvenlik açıklarını tespit etmek için açık kaynak olan sqlmap aracını kullanın.
- Sertifikanızın geçerliliğini kontrol etmenin yanında SSL şifrelerinin ve anahtarlarının konfigürasyonunu test etmek için nmap ve sslyze araçlarını kullanın.
-
Use safe-regex to ensure your regular expressions are not susceptible to Regular expression Denial of Service (ReDoS) attacks.
- RegExp kodlarınızın Regular expression Denial of Service (ReDoS) saldırılarına açık olmadığını sağlamak için safe-regex paketini kullanın.