Yayına almak
Güvenlik
collage'ın request forgery'ye, open redirect'lere, path hilelerine, cache sızıntılarına ve aşırı büyük body'lere karşı yaptıkları ve size bıraktıkları.
Bir framework'teki bug, onunla kurulan her sitedeki bir bug'dır. Bu yüzden collage, her sitenin aksi hâlde hatırlaması gerekecek güvenlik işlerini kendisi yapar. Bu sayfa, collage'ın sizin için yaptıklarını tek bir yerde toplar ve her birinin anlatıldığı yere link verir. Yapmadıkları ise sonda yer alır.
Form'lar sahte olarak gönderilemez
Unsafe bir method'a sahip her action, handler'ı çalışmadan önce imzalı bir token'ı
kontrol eder. {{csrfToken}} içeren bir page yine de cache'lenir: her okuyucuya
kendi token'ı gönderilir. Token tek başına kontrol edilmez. Tarayıcının başka bir
origin'den geldiğini işaretlediği bir gönderim (Sec-Fetch-Site ile ya da Host'a
karşı Origin ile) ne taşırsa taşısın reddedilir. Kardeş subdomain'ler de buna
dahildir, bu yüzden yerleştirilmiş bir cookie içeri girmenin yolu değildir. Buraya
post etmesi amaçlanan bir origin Security.CSRFTrustedOrigins'te belirtilir.
Ayrıntılar için Form'lar ve action'lar
sayfasına bakın.
Deploy etmeden önce Security.CSRFKey'i ayarlayın: üretilen bir key her process'te
farklıdır.
Redirect'ler sitede kalır
collage'ın yazdığı hiçbir redirect, okuyucuyu başka bir siteye gönderemez:
/a/./bya da/a//b'yi temiz yazımına gönderen redirect, path'i escape ederek yazar. Böylece/./%5Cevil.com,/\evil.com'a değil/%5Cevil.com'a gider. Tarayıcı/\evil.com'u//evil.comolarak okur.- Locale ve trailing slash redirect'leri hiçbir zaman
//ile başlamaz. //hostya da/\host'a giden register edilmiş bir redirect, register sırasında reddedilir. Yakaladığı bir değer de düştüğü yere göre escape edilir: path'te ya da tek bir query değeri olarak. Böylece/login?next={slug}'a ikinci birnextverilemez.
Bir action'ın Location'ı ve bir guard'ınki sizindir: collage onları sizin
ayarladığınız gibi yazar. Bu yüzden request'ten, kontrol etmeden bir Location
oluşturmayın.
Bir path tek bir anlama gelir
Middleware decode edilmiş r.URL.Path'i okur, router ise escape edilmiş olanı. İkisi
arasında bir fark çıkabilecek her yerde request hiçbir yere ulaşmaz:
- Dot segment'ler ya da çift slash içeren bir path, middleware çalışmadan önce temiz
yazımına redirect edilir. Böylece
/admin/üzerindeki bir kontrol/x/../adminile hiç karşılaşmaz. - Encode edilmiş bir slash (
%2F) içeren bir path 404 döner./public%2Fsecret, bir middleware için iki segment'tir, router için ise tek segment'ti. - Bozuk bir escape 500 değil 400 döner.
Ayrıntılar için Path'ler önce temizlenir bölümüne bakın.
Private page'ler private kalır
Bir guard, page'in render'ları,
URL'sindeki action'lar ve fragment path'leri için cache okunmadan önce çalışır.
Guard'lı bir page private, no-cache ile, bir guard'ın kendi cevabı ise no-store
ile gider. Böylece bir CDN, bir okuyucunun page'ini ya da aldığı reddi hiçbir zaman
sonrakine vermez. Static export guard'lı page'leri hiç yazmaz.
Cache'lenmiş bir page kimseye özel değildir
Cache'te saklanan bir render, request'i aynı key'e sahip her okuyucuya sunulur. Bu
yüzden render'a yalnızca key'in içerdikleri verilir: path, host, key'deki query
parametreleri, collage.Vary ile bildirilen header'lar. Bir okuyucunun cookie'leri,
credential'ları ya da adresi hiçbir zaman verilmez. Host key'de yer aldığı için
başka bir host adı veren bir request, diğer herkesin aldığı kopyayı zehirleyemez.
Degraded bir render, bir error page ve development'taki bir page hiçbir zaman public
olarak cache'lenemez. Ayrıntılar için
Paylaşılan bir render neyi görür
bölümüne bakın.
Body'ler sınırlıdır
Bir request body'si, middleware'iniz çalışmadan önce, yönlendirildiği action'ın limitiyle sınırlanır. Aksini söylemediğiniz sürece bu limit 4 MiB'tır. Diske taşan multipart dosyalar action cevap verdiğinde silinir. Forgery kontrolünün hiç imzalamadığı bir cookie ise body daha hiç okunmadan reddedilir. Ayrıntılar için Request body'leri sınırlıdır bölümüne bakın.
Bir dosya, uzantısının söylediği şeydir
Bir asset mount, bir dosyanın tipini uzantısına göre belirler. Adı
bir tip belirtmeyen dosyanın tipi içeriğinden çıkarılır; böylece uzantısız yüklenen
bir görsel yine görsel olarak gider. Ama hiçbir zaman çalıştırılabilen bir tipe
dönüşmez: HTML ya da XML'e benzeyen bir dosya text/plain olur ve nosniff
sayesinde tarayıcı buna uyar. Böylece markup içeren bir upload bir page olarak
sunulmaz. Mount hiçbir zaman bir dizini listelemez; .well-known dışında bir
dotfile'ı (.env, .git/) hiçbir zaman sunmaz ya da export etmez. collage serve
de aynısını yapar.
Hatalar production'da hiçbir şey söylemez
Production'da collage'ın kendi error page'i status'tan başka bir şey göstermez: hata
metni yok, stack yok, path yok. Development overlay'i ve reload kanalı yalnızca
development'ta vardır. collage dev de yalnızca bu makineyi adlandıran bir Host'a
cevap verir. Bu yüzden başka bir sitedeki bir page, DNS rebinding yoluyla onları
okuyamaz. Bir log satırındaki request path'i control character içerdiğinde tırnak
içine alınır. Böylece sahte bir satır oluşturamaz ya da terminalinizi yeniden
yazamaz.
Size kalanlar
- Security header'ları. collage hiçbir
Content-Security-Policy, HSTS ya daX-Frame-Optionsayarlamaz. elagoht/secure plugin'i bunları ayarlar. Production'daki bir page hiçbir framework script'i taşımadığı için sıkı bir policy nonce gerektirmez. - TLS,
X-Forwarded-Proto'yu ve tarayıcınınHost'unu ileten bir proxy'de. Ayrıntılar için Deployment sayfasına bakın. - Rate limit'ler: elagoht/ratelimit.
app.Handleile mount edilmiş bir handler tamamen sizindir: forgery kontrolü, body limiti ve cache yoktur.- Bir data handler'ın okudukları. Middleware'in context'e koyduğu bir değer
cache'lenmiş bir render'a da ulaşır. Okuyucudan okuyucuya değişen bir değer
collage.Varyile de bildirilmelidir.
Bir güvenlik açığını bildirmek için collage repository'sinde GitHub'ın private reporting özelliğini kullanın.