Apache için ModSecurity Kullanıcı Kılavuzu

Kılavuz Sürümü 1.9 / Düzeltme 1 (6 Kasım 2005)


İçerik Tablosu

Giriş

Lisans

Teşekkür

İletişim

Kurulum

CVS Erişim

Gecelik snapshot İndirme

Sabit (Stable) dağıtım İndirme

Kaynaktan (Source) kurma

İkiliden (Binary) kurma

Yapılandırma

Filtre (Filter) açma/kapama

POST tarama

Tamponlamayı (Buffering) dinamik olarak kapama

ModSecurity'i dinamik olarak kontrol etme

Bölünmüş transfer kodlama (Chunked transfer encoding)

Varsayılı (Default) erişim listesi

Örtülü (Implicit) denetim

Filtre kalıtımı (inheritance)

Çok kullanıcılı sistemlerde filtre kalıtımı

URL Kodlama Denetimi

Evrensel Kodlama (Unicode) Denetimi

Bayt aralığı kontrolü

Diğerlerinin ModSecurity görmesine izin verme

Kurallar

Basit filtreleme

Yol (Path) normalizasyonu

Boş (Null) bayt saldırı önlemi

Düzenli ifadeler (Regular Expressions)

Tersine çevrilmiş ifadeler

İleri filtreleme

Arguman filtreleme istisnaları

Cookieler

Çıktı (output) filtreleme

İşlemler

İşlemleri Belirtme

Kural başına işlemler 

Kural başına işlem listesinde görülecekleri kısıtlama

Kurulumla gelen işlemler

mod_security tarafından eklenen istek başlıkları

İstek içeriği (body) kayıt tutma

ErrorDocument kullanarak kural eşleşmelerini karşılama

ModSecurity'i güvenlik duvarınızla konuşturma

Özel özellikler

Karşıdan dosya yükleme desteği

Sunucu kimliği maskeleme

Chroot desteği

Kayıt tutma

Ayıklama kaydı

Denetleme kaydı

Guardian kaydı

Özel yapım (custom) kayıt

Diğer

(Impedance mismatch) Uyumsuzluklar

Test

Yaygın güvenlik problemlerini çözme

PHP

Performans

Önemli notlar

mod_security'nin koştuğu Apache kancasını (hook) değiştirme

Örnekler

Parametre kontrolü

Karşıdan dosya yükleme

FormMail'i güvenli hale getirme

Ekler A: Önerilen yapılandırma

Giriş

ModSecurity, web uygulamaları için açık kaynak kodlu saldırı tespit ve önleme motorudur (engine). ModSecurity aynı zamanda web uygulama güvenlik duvarı olarak da adlandırılabilir. ModSecurity web sunucunun içine gömülmüş bir şekilde, güçlü bir şemsiye gibi davranarak uygulamaları saldırılardan korumaya çalışır.

ModSecurity web saldırıları ile başa çıkma gücünüzü arttırarak web sunucu ile bütünleşir. Bahsetmeye değer bazı özellikleri:

·         İstek filtreleme; gelen istekler, web sunucusu veya diğer başka bir modül tarafından alınmadan önce, anında analiz edilir. (Daha kesin olarak, ModSecurity’e ulaşmadan önce istekler üzerinde bazı işlemeler yapılır ama bu gömülü olarak çalışmanın gerekliliğindendir.)

·         Anti-atlatma teknikleri: yollar (paths) ve parametreler, atlatma teknikleri ile savaşmak için analiz edilmeden önce normalize edilirler.

·         HTTP protokolü; motor HTTP’den anladığı için, çok spesifik ve detaylı seviyede filtreleme yapar. Örnek olarak, bireysel parametrelere veya isimli cookie değerlerine bakmak mümkündür.

·         POST veri analizi; ModSecurity motoru (engine) POST metodu kullanılarak gönderilen içerikleri de yakalar.

·         Denetleme kaydı; her istekğin (POST dahil olmak üzere) bütün detayları sonradan adli analiz için kullanılabilir.

·         HTTPS filtreleme; motor web sunucusuna gömüldüğü için, veriye şifre çözme işlemi uygulandıktan sonra erişir.

·         Sıkıştırılmış içerik filtreleme; yukarıdaki gibi, motor, istek verisine şifre çözme işlemi uygulandıktan sonra erişir.

ModSecurity saldırıları saptamada veya önlemede kullanılabilir.

Lisans

ModSecurity iki lisans altında kullanılabilir. Kullanıcılar, Açık Kaynak Kodlu / Bedava Yazılım ürünü olarak GNU General Public License (http://www.gnu.org/licenses/gpl.html) gerekleri altında yazılımı kullanmayı tercih edebilirler. Alternatif olarak: bireysel veya site-boyu üretim için son kullanıcı lisansları, uygulamalar, web sunucuları veya güvenlik araçları ile kapalı kaynak dağıtımı için OEM ticari lisansları kullanılabilir. Ticari lisanslar ile alakalı daha fazla bilgi için lütfen Thinking Stone ile bağlantıya geçin.

Thinking Stone Tel: +44 20 8141 2161 Fax: +44 87 0762 3934 http://www.thinkingstone.com/ <[email protected]>

Teşekkür

Bu modül, Apache web sunucusunu üreten ve Apache modül programlamayı öğrendiğim, saatlerini Apache modüllerini yapmak için harcayan güzel insanlar olmasaydı mümkün olmazdı.

İletişim

ModSecurity, Ivan Ristic ve Thinking Stone tarafından geliştirilmiştir. Yorumlar ve özellik isteklerinizi iletebilirsiniz. Lütfen e-maillerinizi <[email protected]>’a yollayın.

Not

Lütfen destek isteklerinizi kişisel e-mail adresime yollamayın. Destek isteklerini cevaplamaya zaman harcıyorum ama artık özel olarak yanıtlamıyorum. Çünkü bu diğer kullanıcıların cevapları bulmak için mail arşivlerini kullanmalarını engelliyor. Eğer cevaplara çabucak ihtiyacınız varsa veya garantili cevap zamanlarına ihtiyacınız varsa Thinking Stone’dan ticari destek almayı düşünün.

Çeviri bedirhan urgun, e-mailleriniz için: urgunb@hotmail.com. İnteraktif bir web uygulama güvenliği sözlüğü için: http://sozluk.enderunix.org/webappsec.

Kurulum

Kuruluma başlamadan önce, tercih ettiğiniz kurulum metodunu seçmeniz gerekecektir. İlk olarak, CVS’ten ModSecurity’nin en yeni versiyonunu (en iyi özelliklerle ama daha kararsız) mu kuracağınızı veya en son kararlı dağıtımı mı kullanacağınızı seçmeniz gerekir. Eğer bir kararlı dağıtım seçerseniz, ModSecurity’i ikiliden (binary) kurmanız mümkün olabilir. Yine de her zaman kaynak kodundan derlemeniz mümkündür.

Aşağıdaki bir kaç sayfa, bir metodu diğerine seçmenizdeki avantajları hakkında size bilgiler verecek.

CVS Erişimi

Eğer modülün en son verisyonuna erişmek istiyorsanız, CVS deposundan almanız gerekir. En son kararlı dağıtımından sonra yapılan değişiklikler listesi genellikle web sitesinden (ve CHANGES adlı dosyadan) ulaşılabilir. ModSecurity için CVS deposunu SourceForge (http://www.sf.net/) sunar. Direk olarak veya kullanıyorsanız webden şu adresi kullanarak ulaşabilirsiniz: http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/mod-security/

Bilgisayarınıza kaynak kodunu indirmek için aşağıdaki iki komutu çalıştırmanız gerekir:

$ cvs -d:pserver:[email protected]:/cvsroot/mod-security login
$ cvs -z3 -d:pserver:[email protected]:/cvsroot/mod-security \
> co mod_security

İlk satır sizin anonim kullanıcı olarak girişinizi sağlayacak, ve ikinci depodaki bütün mevcut dosyaları indirecektir.

Gecelik SnapShot İndirme

Eğer CVS’i istemiyor ama hala en yeni sürümü istiyorsanız, gecelik tarball’ı aşağıdaki adresten indirilebilirsiniz:

http://www.modsecurity.org/download/snapshot/mod_security-snapshot.tar.gz

Yeni özellikler mod_security’e, her yeni değişiklikten sonra doğrulama testleri uygulanarak bir bir eklenir. Bu, CVS’teki her sürümün her zaman kullanılabilir olmasını sağlar.

Sabit (Stable) Dağıtım İndirme

Sabit (kararlı) dağıtımları indirmek için http://www.modsecurity.org/download/ adresine gidin. İkili (binary) dağıtımlar her zaman hazır değildir. Eğer hazırsa, indirme sayfasında listelenirler. Eğer hazır değilse, kaynak kodu dağıtımını indirin.

Kaynaktan Kurma

Kaynaktan kurarken iki seçeneğiniz vardır: modülü web sunucusuna kurmak, mod_security.c’yi dinamik paylaşılan nesnesine (DSO) derlemek.

DSO

DSO olarak kurmak daha kolaydır, ve prosedür bütün Apache dalları için aynıdır. İlk olarak, dağıtımı bir yere açın (her hangi bir yer olur), ve modülle beraber derleyin:

# /apachehome/bin/apxs -cia mod_security.c

Bundan sonra Apache’yi durdurup ve başlatmanız gerekir (Eğer yeniden başlatmaya (restart) çalışırsanız bir segfault alabilirsiniz).

# /apachehome/bin/apachectl stop
# /apachehome/bin/apachectl start

Not

apxs aracının kurulu olmadığı platformlar hakkında insanlardan şikayet e-postaları almıştım. Bazı Unix dağıtımlarında bu araç (apxs) ayrı bir pakette dağıtılmaktadır. Problem bu paketin kurulum ile gelmediğinde ortaya çıkmaktadır. Bu problemi çözmek için sağlayıcınızın verdiği ve kendi özel yapım modülünüzü nasıl ekleyeceğinizi açıklayan dokümanını okuyun. (Bazı RedHat platformlarında apxs aracına erişmek için http-devel paketini kurmanızı gerekir.)

Apache 1.x ile Statik Kurulum

Bir modül statik olarak derlendiğinde, web sunucunun gövdesine gömülür. Bu metod bir miktar daha hızlı bir çalıştırılabilir (executable) üretir ama derleme metodu (ve daha sonra yönetimi) biraz daha karmaşıktır.

$ cd <apache1-source>
$ cp <modsecurity-source>/apache1/mod_security.c ./src/modules/extra
$ ./configure \
> --activate-module=src/modules/extra/mod_security \
> --enable-module=security

Normal olarak yaptığınız gibi web sunucusunu derleyin, kurun ve başlatın.

Apache 2.x ile Statik Kurulum

Apache 2.x ile statik derleme için tek yapmanız gereken modülün kaynak kodunu Apache kaynak kodu ağacına kopyalamanız ve Apache’i yeniden yapılandırmanızdır:

$ cd <apache2-source>
$ cp <modsecurity-source>/apache2/mod_security.c ./modules/proxy
$ ./configure \
> -enable-security \
> --with-module=proxy:mod_security.c

Apache 2.x Kurulumuna Entegre Etmek

mod_security’i Apache 2.x kurulumuna entegre etmeyi seçebilirsiniz.

$ cd <modsecurity-source>/apache2
$ mkdir -r <apache2-source>/modules/security
$ cp mod_security.c Makefile.in config.m4 <apache2-source>/modules/security
$ cd <apache2-source>
$ ./buildconf

Bu noktadan sonra mod_security, Apache’iye kurulum ile beraber gelen diğer modüller gibi görünecektir ama varsayılı olarak (by default) derlenmeyecektir. Çalışır duruma getirmek için aşağıdakileri uygulayın:

$ ./configure --enable-security

İkiliden (binary) Kurulum

Bazı durumlarda, modülü ikili (binary) olarak kurmak isteyeceksinizdir. Şu an itibariyle indirmek için sadece Windows ikililerini bulunduruyorum. İkiliden kurarken, dağıtımda büyük ihtimalle her iki Apache dalına ait iki DSO kütüphanesine sahip olacaksınız. Kullandığınız sürüm için uygun olanı seçin. Sonra aşağıdaki gibi devam edin:

Apache 1.x

mod_security.so (Unix için) veya mod_security.dll (Windows için) dosyalarını libexec/ dizinine (bu dizin Apache kurulumuna bağıldır, kaynak ağacına değil) kopyalayın. Daha sonra httpd.conf dosyasına aşağıdaki satırı ekleyin.

LoadModule security_module    libexec/mod_security.so

Hali hazırdaki yapılandırmanıza bağlı olarak (modül yükleme sırasını açık olarak belirtmiş olabilirsiniz) AddModule direktifi ile modülü kullanmayı aktive etmeniz gerekebilir.

AddModule mod_security.c

Çoğu durumunda satırı nereye eklediğiniz önemlidir. mod_security’i modül zincirinde son olarak çalıştırmanız önerilir (ve aslında dahili chroot özelliğini kullanmayı amaçlıyorsanız bu adım gereklidir).  Daha fazla bilgi için “chroot desteği için gerekli modül sıralaması (Apache 1.x)” bölümünü okuyun.

Apache 2.x

mod_security.so (Unix için) veya mod_security.dll (Windows için) dosyalarını modules/ dizinine (bu dizin Apache kurulumuna bağıldır, kaynak ağacına değil) kopyalayın. Daha sonra httpd.conf dosyasına aşağıdaki satırı ekleyin.

LoadModule security_module    modules/mod_security.so

Yapılandırma

ModSecurity yapılandırma direktifleri yapılandırma dosyanıza (tipik olarak httpd.conf) direk olarak eklenir. Web sunucu çalışmaya başladığında, modülün çalışıp çalışmayacağının belli olmadığı (modülün var olup olmadığı) durumlarda geleneksel olarak modülün yapılandırma direktifleri <IfModule> kap etiketlerinin (container tag) içine eklenir. Bu Apache’nin, modül aktif olmadığı zamanlarda yapılandırma direktiflerini görmezden gelmesini sağlar.

<IfModule mod_security.c>
    # mod_security configuration directives
    # ...
</IfModule>

Apache, yapılandırma verilerinin birden fazla dosyada bulunmasına izin verdiği için ModSecurity yapılandırma direktiflerini tek bir dosyada (mesela modsecurity.conf) gruplamak ve httpd.conf ‘dan Include direktifi ile içermek mümkündür.

Include conf/modsecurity.conf

Filtrelemeyi Açma/Kapama

Varsayılı olarak filtreleme motoru kapalıdır. İstekleri gözlemek için aşağıdakini yapılandırma dosyanıza ekleyin:

SecFilterEngine On

Bu parametre için desteklenen parametre değerleri:

·         On - her isteği analiz et

·         Off - hiçbirşey yapma

·         DynamicOnly - Sadece yürütme esnasında dinamik olarak üretilen istekleri analiz et. Bu seçeneği kullanarak web sunucunuzun değerli CPU çevrimlerini (cycle) statik dosyalar için gönderilen istekleri kontrol etmek için harcamasına engel olabilirsiniz. ModSecurity’nin, bir isteğin dinamik olarak üretilip üretilmediğine nasıl karar verdiğini anlamak için "Neyin kaydedileceğini seçme" bölümünü okuyun.

POST tarama

İstek gövde verisi (veya POST verisi) tarama özelliği varsayılı olarak (by default) kapalıdır. Kullanmak için açmanız gerekir:

SecFilterScanPOST On

mod_security, istek gövdesi için iki kodlama tipini destekler:

·         application/x-www-form-urlencoded - form verisini iletmek için kullanılır

·         multipart/form-data - dosya iletmek için kullanılır

Diğer kodlamalar çoğu web uygulamaları tarafından kullanılmazlar. Sadece bu kodlama tiplerinin web sunucusu tarafından kabul edilmesini sağlamak için aşağıdaki satırı yapılandırma dosyanıza ekleyin:

SecFilterSelective HTTP_Content-Type \
"!(^$|^application/x-www-form-urlencoded$|^multipart/form-data;)"

Tamponlamayı (Buffering) dinamik olarak durdurma

İstek bazında POST verisi tarama özelliğini kapatmak mümkündür. Eğer ModSecurity, MODSEC_NOPOSTBUFFERING çevre değişkeninin tanımlı olduğunu görürse POST veri taramasını yapmayacaktır. Mesela, karşıdan dosya yüklemeleri için POST veri tamponlama özelliğini kapatmak için aşağıdakini kullanın:

SetEnvIfNoCase Content-Type \
"^multipart/form-data;" "MODSEC_NOPOSTBUFFERING=Do not buffer file uploads"

Neden tamponlamanın kapatıldığını açıklamak için MODSEC_NOPOSTBUFFERING değişkenine atanan değer, hata ayıklama (debug) kaydına yazılacaktır.

ModSecurity’i dinamik olarak kontrol etme

İstek bazında ModSecurity’i açmak veya kapatmak da mümkündür. Bu da MODSEC_ENABLE çevre değişkeni ve SetEnvIf ve SetEnvIfNoCase direktifleri ile mümkündür. Eğer MODSEC_ENABLE tanımlı değilse SecFilterEngine ile belirlenen yapılandırma kullanılacaktır. Eğer MODSEC_ENABLE tanımlı ise SecFilterEngine direktifinin değeri görmezden gelinecektir. MODSEC_ENABLE değerler aynı SecFilterEngine direktifindeki gibidir: On, Off, veya DynamicOnly.

Bölünmüş transfer (Chunked transfer) kodlama

HTTP protokolü, veri boyutunun önceden bilinmediği hallerde kullanılan bir istek transfer metodunu destekler. İsteğin gövdesi (body) parçalar halinde ulaştırılır. Ve metodun ismi (bölünmüş transfer kodlama) de buradan gelir. ModSecurity şimdilik parçalanmış transfer isteklerini desteklemez; parçalanmış kodlama kullanılan bir istek yapıldığında isteğin gövdesini (body) görmezden gelir. Apache bu kodlama metodunu desteklese de çoğu modül (mesela, Apache 1.3.x PHP modülü) desteklemez.

Açık bırakıldığında bu metod saldırgana kötü amaçlı verileri gizleyerek yollama imkanı tanır. Saldırganların bu zayıflığı gerçeklemelerini önlemek için aşağıdaki satırı yapılandırma dosyanıza ekleyin:

SecFilterSelective HTTP_Transfer-Encoding "!^$"

Bu durum, parçalanmış (bölünmüş) transfer kodlama kullanma yoluyla cevap yollama kabiliyetinizi etkilemez.

Varsayılı (Default) İşlem Listesi

Ne zaman bir kural bir istekle eşleşse, bir veya daha fazla işlem uygulanır. Bireysel filtreler kendi işlemlerini içerebilir ama bütün filtreler için varsayılı bir işlem kümesi tanımlamak daha kolaydır. (İsterseniz her kural için işlem de koyabilirsiniz.) Varsayılı işlemleri SecFilterDefaultAction direktifi ile tanımlarsınız. Mesela, aşağıdaki satır, motoru her kural eşleşmesinde kayıt tutacak ve isteği 404 durum kodu ile reddecek şekilde yapılandıracaktır.

SecFilterDefaultAction "deny,log,status:404"

SecFilterDefaultAction  direktifi sadece bir parametre kabul eder; virgül işaretiyle ayrılmış işlemler. Burada tanımladığınız işlemler, kendi işlemleri olan kurallar hariç, her filtre eşleşmesinde kullanılacaktır.

Not

1.8.6’dan itibaren, eğer hayati olmayan (non-fatal) varsayılı işlem listesi (istekleri reddetmeyen bir liste, mesela log,pass) tanımlarsanız böyle bir işlem listesi ilklendirme (initialization) safhasında görmezden gelinecektir. İlklendirme safhası istek hakkında bilgi edinmek için dizayn edilmiştir. Hayati olmayan işlemlere izin vermek, isteğin bazı bölümlerinin kaybolmasına neden olacaktır. Bu bilgiler dahili süreç için gerekli olacağından bu tür işlemler kabul edilemez. Eğer ModSecurity’nin “sadece algıla” modunda çalışmasını istiyorsanız bütün örtülü denetlemeleri kapatmalısınız (URL kodlama denetlemesi, Evrensel kod -Unicode- kodlama denetlemesi, cookie format denetlemesi, ve bayt aralığı kısıtlaması).

Not

Bazı işlemler varsayılı listede bulunamaz. Bunlar; id, rev, skipnext, chain, chained.

Örtülü Denetim

1.8.6. ile birlikte örtülü istek denetimi (yapılandırıldığı takdirde) sadece istek işleminin başlangıcında yapılacaktır. Örtülü denetim istek satırına ve başlıklarına yapılacak kontrollerden oluşur.

Not

1.9dev4 ile beraber evrensel kod denetimi ilk örtülü istek denetiminin parçası olduğunda Referer başlığına uygulanmaz. Bunun nedeni, bu başlığın çoğunlukla diğer web sitelerinden bilgiler içermesidir, ve bu sitelerdeki kodlamanın korunan sitenin kodlamasından farklı olmasıdır.

Filtre Kalıtımı

Üst dizinlerde tanımlanan filtreler normal olarak içiçe yazılan Apache yapılandırma kapsamı tarafından kalıtılırlar. Bu davranış çoğu durumda kabul edilebilir (ve bazen gereklidir), ama her zaman değil. Bazen bu kontrolleri sitenin bazı bölümlerinde gevşetmek gerekir. SecFilterInheritance direktifi kullanılarak:

SecFilterInheritance Off

ModSecurity’e üst filtrelerini görmezden gelmesini ve kurallara yeni baştan başlamasını söyleyebilirsiniz. Bu direktif sadece kuralları etkiler. Yapılandırma, her zaman üst kapsamdan kalıtılır ama bunu uygun yapılandırma direktiflerini kullanarak istediğiniz gibi değiştirebilirsiniz.

Not

Yapılandırma ve kural kalıtımı varsayılı olarak (by default) her zaman açıktır. Eğer kalıtım özelliği kapatılan kapsam altında alt kapsamınız varsa ve eğer bu alt kapsamda da kalıtımı kapatmak istiyorsanız kalıtımı tekrar doğrudan, direktif yardımı ile, kapatmanız gerekecektir.

Üst kapsamdan gelen kuralları kalıtım yoluyla almak istemiyorsanız, yeni kapsam için yeni kurallar yazabilirsiniz veya basitçe Include direktifini kullanarak aynı kuralları diğer bir çok kapsama dahil edebilirsiniz.

Bazen alt kapsamda sadece küçük değişiklikler gerekebilir. Bu tür durumlarda seçici kalıtım seçeneğini kullanmayı seçebilirsiniz. Bunu, aşağıdaki iki direktif yardımıyla başarabilirsiniz:

·         SecFilterImport - üst kapsamdan tek bir kural dahil etmek için. Bu direktif alt kapsamda baştan başlamak için ve üst kapsamdan sadece seçilen kuralları dahil etmek için faydalıdır.

·         SecFilterRemove - hali hazırdaki kapsamdan bir kural çıkarmak için. Bu direktif üst kapsamdaki ile aynı kural kümesi ile başlamak ve sadece seçilen kuralları silmek istediğiniz zaman faydalıdır.

SecFilterImport ve SecFilterRemove direktiflerinin her ikisi de bir kural ID’leri listesi kabul ederler. Hedef kuralların ID’leri olmak zorundadır (bu, ID işlemi kullanılarak yapılır). Bu direktifler yapılandırma dosyasında bulundukları sıra ile çalıştırılırlar. Bu nedenle, SecFilterRemove direktifi ile kural çıkarmak ve sonra SecFilterImport direktifi ile kural eklemek mümkündür. Aşağıda, aynı yapılandırma kurallarını farklı yollarla üreten iki örnek bulabilirsiniz.

Not

Eğer bir hedef kural ID’si zincirin bir parçası olan kuralı gösterirse, import ve remove direktifleri sadece ID’inin gösterdiği kuralı değil bütün zinciri etkileyecektir.

Örnek 1: üst kapsamındaki kurallar kalıtılmaz, ama sadece bir kural dahil edilir.

SecFilter XXX id:1001
SecFilter YYY id:1002
SecFilter ZZZ id:1003
 
<Location /subcontext/>
    SecFilterInheritance Off
    SecFilterImport 1003
</Location>

Örnek 2: iki kural çıkarılarak, kurallar üst kapsamdan kalıtılır (dahil edilir).

SecFilter XXX id:1001
SecFilter YYY id:1002
SecFilter ZZZ id:1003
 
<Location /subcontext/>
    SecFilterRemove 1001 1002
</Location>

Not

Apache web sunucusu çok çeşitli kapsamları destekler (mesela, <Directory>, <Location>, <Files>, ...). Kapsamların birleştirildikleri sıra önemlidir. Kalıtımı ve çeşitli kapsamları birleştirmeyi denememelisiniz. Eğer birleştirmek zorundaysanız, düşündüğünüz gibi çalıştığını doğrulamak için yapılandırmayı test edin ve Apache kapsam birleştirme dokümanlarını dikkatlice okuyun: http://httpd.apache.org/docs-2.0/sections.html#mergin.

Çok kullanıcılı ortamlarda filtre kalıtımı

Çok kullanıcılı ortamlarda ModSecurity çalıştırıdığınızda, ve kullanıcılarınızın .htaccess dosyalarında kurallar kullanmalarına izin verildiğinde, üst kapsamdan kural dahil etmelerine izin vermeyebilirsiniz. Bunu başarmak için iki yol vardır.

Not

Kullanıcılarınıza güvenmiyorsanız (mesela, web hizmeti veriyorsanız), ModSecurity’e ulaşmalarına asla izin vermemelisiniz. .htaccess olanağı ModSecurity yapılandırmasını uygulama kodunda tuttuğundan, kısıtlı yönetim kontrol yetki dağıtımı için faydalıdır. Ama kullanıcıların yapılandırmayı değiştirme olasılıkları olan durumlarda değil. Eğer kötü niyetli (güvensiz) bir ortamdaysanız, .htaccess özelliğini ModSecurity’i -DDISABLE_HTACCESS_CONFIG sekmesi ile derleyerek tamamen kapatmalısınız.

Öncelikle, bazı kuralları zorunlu kılmak için zorunlu işlem zincirini kullanabilirsiniz. Bu tür kurallar alt kapsam tarafından her zaman kalıtılacaktır.

Diğer bir yöntem SecFilterInheritanceMandatory direktifini kullanarak kapsamdaki bütün kuralları alt kapsam için zorunlu hale getirmektir.

SecFilterInheritanceMandatory On

Not

SecFilterInheritance özelliğinin kapsamda açık olması gibi, SecFilterInheritanceMandatory özelliği de, üst kapsamda kullanılan değerler ne olursa olsun, bir kapsamda her zaman kapalıdır.

Bu tür bir durumda ne olacağını merak ediyor olabilirsiniz:

SecFilter XXX id:1001
SecFilterInheritanceMandatory On
<Location /subcontext/>
    SecFilterInheritance Off
    SecFilter YYY id:1002
    SecFilter ZZZ id:1003,mandatory
</Location>
 
<Location /subcontext/another/>
    SecFilterRemove 1001 1002 1003
    SecFilter QQQ id:1004
</Location>

Ana kapsamda kural kalıtımı zorunlu olduğundan, /subcontext/ kapsamı 1001 numaralı kuralı, SecFilterInheritance Off kuralına rağmen, kalıtacaktır. Bu alt kapsam önce 1001 kuralını, daha sonra 1002 ve 1003 numaraları koşacaktır.

Ana kapsamdan, zorunlu kural 1001, silme çabalarına rağmen /subcontext/another/ kapsamına da iletilecektir. Bu, mandatory işlemi kullanılarak kalıtım için zorunlu hale getirilen kural 1003 için de geçerlidir. SecFilterRemove 1001 1002 1003 direktifi, öte yandan, 1002 numaralı kuralı silmekte başarılı olacaktır çünkü kalıtım /subcontext/ kapsamında zorunlu değildir. Bu nedenle, bu kapsam ilk olarak 1001 ve 1003 daha sonra 1004 kurallarını koşacaktır.

Not

skip işlemini kullanan kurallarını içermeden veya silmeden kaçınmalısınız. Eğer çok dikkatli değilseniz, istediğinizin dışında bir şeyler yapan bir yapılandırma ile karşılaşabilirsiniz.

URL Kodlama Denetimi

Özel karakterler URL içerisinde gönderilmeden kodlanmalıdırlar. Her karakter üç karakterden oluşan ve XY’nin bir hexadecimal karakter kodunu temsil ettiği %XY kombinasyonu ile değiştirilebilir. (daha fazla detay için http://www.rfc-editor.org/rfc/rfc1738.txt)  Hexadecimal sayılar sadece A’dan F’ye olan harfleri içerir, ama saldırganlar kod çözme algoritmasını kandırmak için diğer harfleri de kullanırlar. ModSecurity verilen bütün kodlamaları doğru olduklarını anlamak için kontrol eder.

URL kodlama denetimini aşağıdaki satır ile açabilirsiniz:

SecFilterCheckURLEncoding On

Not

Bu direktif multipart/form-data (dosya yükleme) kullanıldığında bir POST verisindeki kodlamayı kontrol etmez. Gerekmez çünkü bu kodlamada URL kodlama kullanılmaz.

Evrensel Kodlama Denetimi

Diğer bir çok özellik gibi Evrensel kodlama denetlemesi varsayılı olarak kapalıdır. Eğer uygulamanız veya alttaki işletim sisteminiz evrensel kodu kabul ediyor veya anlıyorsa bu özelliği açmalısınız.

Not

Evrensel kod ve UTF-8 kodlama hakkında daha fazla bilgi RFC 2279’da bulunabilir (http://www.faqs.org/rfcs/rfc2279.html).

SecFilterCheckUnicodeEncoding On

Bu özellik UTF-8 kodlamanın kullanıldığını varsayar ve üç tip hatayı kontrol eder:

·         Yetersiz bayt.  UTF-8 iki, üç, dört, beş ve altı baytlık kodlamaları destekler. ModSecurity bir veya daha fazla baytın eksik olduğu durumları bulur.

·         Geçersiz kodlama. Bir çok karakterin ilk iki bitlerinin 0x80 olması gerekmektedir. Saldırganlar bunu kullanarak evrensel kod çözücülerini alt etmek için kullanabilirler.

·         Çok uzun karakterler. ASCII karakterleri evrensel kod uzayına direk olarak eşlenirler ve bu nedenle sadece 1 bayt ile gösterilirler. Ama, bir çok ASCII karakterleri iki, üç, dört, beş ve altı karakterler şeklinde de kodlanabilir ve böylece kod çözücüleri bu karakterlerin farklı karakterler olduğuna inandırabilirler (ve böylece güvenlik kontrollerini geçebilirler).

Bayt Aralığı Kontrolü

İsteklerin içerisindeki baytların sadece belli bir aralıkta olmalarını sağlayabilirsiniz. Bu yığıt taşması (stack overflows) saldırılarını önlemekte faydalı olabilir (çünkü bu saldırılar genelde rasgele ikili -binary- içerik içerirler). Sadece 32’den 126’ya kadar (kapsayacak şekilde) bayt değerlerine izin vermek için, aşağıdaki direktifi kullanın:

SecFilterForceByteRange 32 126

Varsayılı aralık değerleri 0 ve 255’tir. Yani bütün bayt değerleri kabul edilir.

Not

Bu direktif POST içerisindeki bayt aralıklarını multipart/form-data kodlama kullanıldığında (karşıdan dosya yükleme) kontrol etmez. Bu şekilde ikili (binary) dosyaların karşıdan yüklenmesi bir problemle karşılanmaz. Ama, bu tür bir istekten parametreler alındıktan sonra geçerli bayt aralıkları kontrol edilir.

Diğerlerinin ModSecurity’i Görmesine İzin Verilmesi

1.9’dan önce ModSecurity SecServerResponseToken direktifini desteklerdi. Kullanıldığında, bu direktif web sunucusu imzasında modülün var olup olmadığını kontrol ederdi. Bu direktif 1.9’da artık çalışmıyor. Kullanıldığında, hata kaydına bir uyarı mesajı düşecektir.

Kurallar

Filtreleme motoru çalışır hale getirildiğinde, her gelen istek yakalanır ve işlemden geçirilmeden önce analiz edilir. Analiz istek formatını denetlemek için dizayn edilen bir seri kontrollerle başlar. Bu kontroller yapılandırma direktifleri kullanılarak kontrol edilebilir. İkinci aşamada, istek, kullanıcı tarafından tanımlanan ve eşlenen filtrelerden geçer. Bu eşleşmenin sonucu pozitif olursa, belli işlemler uygulanır.

Basit filtreleme

Filtrelemenin en basit formu, isminden de anlaşılacağı gibi basittir. Şuna benzer:

SecFilter KEYWORD

Bunun gibi her basit filtre istek içerisinde anahtar sözcüğü arar. Arama çok geniş yapılır; isteğin ilk satırına (GET /index.php?parameter=value HTTP/1.0 gibi) uygulanır. POST isteklerinde, isteğin gövdesi de aranır (tabi ki istek gövdesi tamponlaması -buffering- desteklenirse).

Yol (path) normalizasyonu

Filtreler işlenmemiş istek verilerine uygulanmaz, normalize edilmiş kopyalarına uygulanır. Bunu, saldırganların farkedilmemek için kullandıkları bir çok değişik atlatma tekniklerini önlemek için yaparız. Örneğin, komut satırı çalıştırma saldırısını yakalayacak bir filtre yazdığınızı düşünün:

SecFilter /bin/sh

Ama saldırgan /bin/./sh şeklinde (aynı anlama gelen) bir dizgi kullanabilir.

ModSecurity aşağıdaki değişiklikleri otomatik olarak uygular:

·         Sadece Windows’da, \ işaretini / işaretine çevirir.

·         /./ işaretlerini / işaretine çevirir.

·         // işaretlerini / işaretine çevirir.

·         URL kodlanmış karakterleri çözer.

Aşağıdaki kontrolleri açıp kapamayı seçebilirsiniz:

·         URL kodlamayı denetleme

·         Belli aralıktaki baytları kullanmayı

Boş (Null) bayt saldırı önleme

Boş (null) bayt saldırıları C/C++ tabanlı yazılımların aklını karştırmaya ve onları dizginin bittiğine (bitmediği halde) inandırmaya çalışır. Bu çeşit bir saldırı aslında tipik olarak düzgün bir SecFilterByteRange filtresi ile engellenir. Ama, bunu yapmazsanız boş bayt ModSecurity’nin işlemini karıştırabilir. Bununla savaşmak için, ModSecurity çözme (decoding) sırasında boş baytları arar ve onları boşluğa dönüştürür. Yani,aşağıdaki filtre daha önce:

SecFilter hidden

aşağıdaki istek içerisindeki saklanmış kelimeyi bulamazdı:

GET /one/two/three?p=visible%00hidden HTTP/1.0

Ancak şimdi beklendiği çalışmaktadır.

Düzenli İfadeler (Regular expressions)

Daha önce bahsettiğim en basit filtreleme metodu aslında biraz daha karmaşıktır. Tam yazılım şekli (syntax) aşağıdaki gibidir:

SecFilter KEYWORD [ACTIONS]

İlk olarak, KEYWORD basit bir dizgi (text) değildir. Düzenli bir ifadedir (regular expression). Düzenli bir ifade, yazı içinde örüntü eşlemede (pattern matching) kullanılan mini bir programlama dilidir. Bu güçlü aracı, hakkını vererek kullanmak için düzenli ifadeleri çok iyi anlamanız gerekir. Aşağıdaki kaynaklar ile başlamanızı öneririm:

·         Perl-uyumlu düzenli ifadeler yardım sayfası, http://www.pcre.org/pcre.txt

·         Perl Düzenli İfadeler, http://www.perldoc.com/perl5.6/pod/perlre.html

·         Düzenli İfadelere Hakim Olma, http://www.oreilly.com/catalog/regex/

·         Düzenli İfadeler için Google araması, http://www.google.com/search?q=regular%20expressions

·         Wikipedia girişi, http://en.wikipedia.org/wiki/Regular_expression

·         POSIX düzenli ifadeleri, http://www.wellho.net/regex/posix.html

Not

Apache 1.x ve Apache 2.x için iki farklı düzenli ifade motoru (regular expression engine) kullanılmıştır. Apache 1.x’in düzenli ifade motoru POSIX uyumludur. Apache 2.x’in düzenli ifade motoru PCRE uyumludur. Ana kural olarak, Apache 1.x’de çalışan düzenli ifadeler Apache 2.x’de de çalışır, ama diğer şekilde değil. Eğer her ikisinde de çalışması gereken kurallar yazmanız gerekirse, iyi test etmeniz gerekir.

İkinci parametre, kuralın eşleşmesi durumunda yapılacak işlem listesi tanımıdır. İşlemler bu kılavuzda daha sonra açıklanacaktır.

Tersyüz ifadeler

Ünlem işareti bir düzenli ifadenin ilk karakteri ise, filtre düzenli ifadeyi tersyüz edilmiş olarak görür. Örneğin, aşağıdaki ifade:

SecFilter !php

php kelimesini içermeyen her isteği reddeder.

İleri (Advanced) filtreleme

Her ne kadar SecFilter’ı kullanmak kolay gelse de, er ya da geç çok geniş bir kapsamı olduğunu ve bu nedenle çok iyi çalışmadığını anlayacaksınız. Diğer direktif:

SecFilterSelective LOCATION KEYWORD [ACTIONS]

aramanın tam olarak nerede yapabileceğiniz seçeneğini size sunar. KEYWORD ve ACTIONS bölümleri SecFilter ile aynıdır. LOCATION bölümü daha detaylı bir açıklama gerektirir.

LOCATION parametresi bir hatla (pipe) ayrılmış bir seri yer belirtecinden oluşur.

Aşağıdaki örneğe bakın:

SecFilterSelective "REMOTE_ADDR|REMOTE_HOST" KEYWORD

Düzenli ifadeyi sadece istemcinin IP adresine ve sunucu ismine uygulayacaktır. Mümkün olan yer belirteçlerinin listesi bütün CGI değişkenlerini ve daha fazlasını kapsar. İşte bütün liste:

·         REMOTE_ADDR

·         REMOTE_HOST

·         REMOTE_USER

·         REMOTE_IDENT

·         REQUEST_METHOD

·         SCRIPT_FILENAME

·         PATH_INFO

·         QUERY_STRING

·         AUTH_TYPE

·         DOCUMENT_ROOT

·         SERVER_ADMIN

·         SERVER_NAME

·         SERVER_ADDR

·         SERVER_PORT

·         SERVER_PROTOCOL

·         SERVER_SOFTWARE

·         TIME_YEAR

·         TIME_MON

·         TIME_DAY

·         TIME_HOUR

·         TIME_MIN

·         TIME_SEC

·         TIME_WDAY

·         TIME

·         API_VERSION

·         THE_REQUEST

·         REQUEST_URI

·         REQUEST_FILENAME

·         IS_SUBREQ

Extra yer belirteçleri de vardır:

·         POST_PAYLOAD - POST isteğinin gövdesini filterele

·         ARGS - filtre argümanları, QUERY_STRING|POST_PAYLOAD ile aynı

·         ARGS_NAMES - sadece değişken/parametre isimleri

·         ARGS_VALUES - sadece değişken/parametre değerleri

·         COOKIES_NAMES - sadece cookie isimleri

·         COOKIES_VALUES - sadece cookie değerleri

·         SCRIPT_UID

·         SCRIPT_GID

·         SCRIPT_USERNAME

·         SCRIPT_GROUPNAME

·         SCRIPT_MODE

·         ARGS_COUNT

·         COOKIES_COUNT

·         HEADERS

·         HEADERS_COUNT

·         HEADERS_NAMES

·         HEADERS_VALUES

·         FILES_COUNT

·         FILES_NAMES

·         FILES_SIZES

Ve daha da fazlası:

·         HTTP_header - istek başlığı "header"’ı  ara (1.9 ile beraber HEADER_header’de kullanılabilir)

·         ENV_variable - variable çevre değişkenini ara

·         ARG_variable - variable istek değişkeni/parametresini ara

·         COOKIE_name - name ismindeki cookie’yi ara

·         FILE_NAME_variable - variable isminde karşıdan yüklenen dosyayı ara

·         FILE_SIZE_variable - variable isminde karşıdan yüklenen dosyayının büyüklüğünü ara

Sadece Apache 2 için (çıktı tamponlaması -output buffering- açık olduğunda) kısıtlı sayıda çıktı-tabanlı (output) değişkenler de mevcuttur:

·         OUTPUT – bütün cevap gövdesi

·         OUTPUT_STATUS – cevap durum kodu

Argüman filtreleme istisnaları

ARG_variable yer belirteci isimleri ARGS ile beraber kullanıldığında tersyüz kullanımı da destekler. Örneğin:

SecFilterSelective "ARGS|!ARG_param" KEYWORD

isimlendirilmiş parametre dışında diğer bütün argümanları arayacaktır.

Cookieler

ModSecurity cookieler için tam destek sunar. Varsayılı olarak, cookieler sürüm 0 formatına (Netscape stili cookieler) sahip olacak şekilde işlem görür. Ancak sürüm 1 cookieler (RFC 2965’te tanımlandığı şekilde) de desteklenir. Sürüm 1 cookie desteğini açmak için SecFilterCookieFormat direktifini kullanın:

# enable version 1 (RFC 2965) cookies
SecFilterCookieFormat 1

Varsayılı olarak, ModSecurity cookie isimlerini ve değerlerini normalize etmez. Ancak, bazı uygulamalar ve platformlar (mesela PHP) cookie içeriğini kodladığından, cookielere normalize tekniklerinin uygulanmasını seçebilirsiniz. Bu SecFilterNormalizeCookies direktifi kullanılarak yapılabilir.

SecFilterNormalizeCookies On

Not

Sürüm 1.8.7’e kadar ModSecurity SecFilterCheckCookieFormat direktifini desteklerdi. 1.8.7’de yapılan yeni değişiklikler sebebiyle bu direktif şu an yürürlükten kaldırılmıştır. Yapılandırmada hala kullanılabilir ancak bir etkisi yoktur. Bu direktif 1.9.x sürümlerinde tamamen kaldırılacaktır.

Çıktı filtreleme

ModSecurity çıktı filtrelemeyi Apache 2 sürümünde destekler. Varsayılı olarak (by default) kapalıdır, bu nedenle önce aşağıdaki gibi açmalısınız:

SecFilterScanOutput On

Bundan sonra, özel değişken OUTPUT’u seçici filtrelerde kullanabilirsiniz:

SecFilterSelective OUTPUT "credit card numbers"

Beni http://www.webkreator.com/php/

 deki sütunumdan tanıyanlar PHP’nin hayati hata mesajlarını önleme eksikliğine olan saplantımı bilirler. Bu hayati hataları önlemek için hataların son kullanıcılara ulaşmasını engellemekten (http://www.webkreator.com/php/configuration/handling-fatal-and-parse-errors.html) başlayarak epey uğraştım, ama artık, sonunda, bu konu hakkında daha fazla endişelenmiyorum. Aşağıdaki, PHP çıktı hatalarını cevap gövdesinde yakalayacak ve başka bir hata mesajı ile cevap gönderecektir.

SecFilterSelective OUTPUT "Fatal error:" deny,status:500
ErrorDocument 500 /php-fatal-error.html

Çıktı filtrelerini ile girdi filtrelerini beraber kullanabilirsiniz ama aynı anda çalışmayacaklarını bilmeniz gerekir. Girdi filtreleri Apache tarafından herhangi bir istek işlemden geçirilmeden çalıştırılırlar, öte yandan çıktı filtreleri Apache istek işlemlerini bitirdikten sonra çalışır.

Not

skipnext ve chain işlemleri çıktı filtreleri olmadan çalışmazlar.

Çıktı filtreleme sadece düz yazı ve HTML çıktıları için kullanışlıdır. İkili (binary) içeriğe düzenli ifadeler (regular expressions) uygulamak sadece sunucuyu yavaşlatacaktır. Varsayılı olarak ModSecurity içerik tipi (content type) olmayan veya içerik tipi text/plain veya text/html olan cevap çıktılarını tarayacaktır. Bu durumu SecFilterOutputMimeTypes direktifini kullanarak değiştirebilirsiniz.

SecFilterOutputMimeTypes "(null) text/html text/plain"

Aşağıdaki örnek gibi yapılandırıldığında ModSecurity çıktı filtrelerini düz yazı dosyalarına, HTML dosyalarına ve mime tipi "(null)" olarak belirtilen dosyalara uygulayacaktır.

Not

Çıktı tamponlaması (biriktirmesi, buffering) kullanılması ModSecurity’nin bütün sayfa çıktısını, ne kadar büyük olursa olsun, hafızada tutmasını sağlayacaktır. Bu nedenle hafıza tüketimi sayfa büyüklüğünün iki katından fazladır.

Bazı durumlarda çıktı gözetlemesi ne kadar kullanışlı olsa da, %100 güvenli olmadığının farkında olmalısınız. Eğer saldırgan istek işleme işine tamamen hükmediyorsa, çıktı gözetlemeyi iki şekilde atlatabilir:

1.      Gözetlenmeyen bir Content-Type kullanabilir. (Performans nedenlerinden ötürü, bütün içerik tiplerinin gözetlenmesi mümkün değildir.)

2.      Çıktıyı bir şekilde kodlar. Basit bir kodlama bile gözetleme işini atlatacaktır.

1.9 ile beraber diğer çıktı değişkeni de desteklenmektedir- OUTPUT_STATUS. Bu değişken cevap durum kodunu içerir.

İşlemler

Bir çok işlem tipi vardır:

·         Ana işlem isteğin kabul edilip edilmeyeceğine karar verir. Sadece bir ana işlem bulunabilir. Eğer birden fazla ana işlem yazarsanız, sadece en son işlem çalıştırılacaktır. Ana işlemler şunlardır: deny, pass, and redirect.

·         İkincil işlemler filtre eşleşmesi sonucu ana işlemlerden bağımsız olarak çalıştırılarlar. Birden fazla ikincil işlem bulunabilir. Örnek olarak, exec ikincil bir işlemdir.

·         Akış işlemleri kuralların akışını değiştirebilir ve böylece filtrelemenin bir kuraldan diğer kurala atlamasını veya bir veya bir kaç kural atlamasına sebep olabilir. Akış işlemleri şunlardır: chain ve skip

·         Parametreler tam olarak işlem değillerdir. Onlar filtrelere parametre ekleme metodudur. Bu parametrelerden bazıları gerçek işlemler tarafından da kullanılabilirler. Örnek olarak status ana işlem olan deny’a cevap kodunu bildirir.

İşlemleri belirtmek

İşlemleri belirteceğiniz üç yer vardır. Bunlardan bir tanesi ondan sonra gelen kuralların işlemleri olarak çalışmasını istediğiniz SecFilterDefaultAction’dir.

SecFilterDefaultAction "deny,log,status:500"

Bu örnek üç işlemden oluşan bir işlem listesi tanımlar. Virgüller listedeki işlemleri ayırmakta kullanılır. İlk iki işlem tek kelimeden oluşur. Ama üçüncü işlem bir parametre ister. Parametreyi işlemden ayırmak için iki nokta üst üste kullanın. İşlem parametreleri etraflarını tek tırnak ile çevirmediğiniz takdirde boşluklar içeremez (parametrede tek tırnağı ters bölü işareti ile kurtarın -kaçırın, escape-).

SecFilterDefaultAction "deny,log,status:'Hello World!'"

Not

1.8.6 ile birlikte, eğer hayati olmayan bir işlem (log,pass gibi) belirtirseniz ilklendirme fazında görmezden gelineceklerdir. İlklendirme fazı, istek hakkında bilgi edinmek için dizayn edilmiştir. Hayati olmayan işlem belirtmek, isteklerin bazı kısımlarının kaçırılmasını (ModSecurity’nin dahili çalışması için) sağlardı. Bu nedenle ModSecurity’nin “sadece bul” modunda çalışmasını isterseniz bütün örtülü denetlemeleri (URL kodlama, evrensel kod, cookie formatı, bayt aralığı denetimleri) kapatmalısınız.

Not

Yardımcı veri (meta-data) işlemleri (id, rev, msg, severity) ve kuralların akışını kontrol eden işlemler (skip/skipnext, chain) SecFilterDefaultAction direktifinde bulunamazlar.

Kural başına işlemler

Kural başına da işlemler belirtebilirsiniz. Her iki filtreleme direktifleri de (SecFilter ve SecFilterSelective) işlemleri opsiyonel parametreler olarak kabul ederler. Kural başına işlemler en güncel SecFilterSignatureAction direktifindeki işlemlerle (varsayılı değer log,deny,status:403) birleştirilirler. Aşağıdaki kurallar birleştirme işleminde uygulanırlar:

1.      İşlem listesi başına sadece bir ana işleme izin verilir. Bir “kural başına işlem” varsayılı listedeki ana işlemi iptal eder.

2.      Kural başına yapılandırmasında belirtilen işlemler varsayılı işlem listesindeki eş işlemleri iptal eder.

3.      Kısıtlı mod (SecFilterActionsRestricted direktifini görün) açıkken sadece yardımcı veri işlemleri kural başına işlem listesinde bulunabilirler.

4.      Kurallar yapılandırma zamanında (sezgisel olarak tercih edilen) veya yürütme zamanında (sezgisel olarak daha az tercih edilen) birleştirilebilirler. Aradaki farklar için okumaya devam edin.

SecFilterSignatureAction

1.9RC1’dan bu yana kullanılan SecFilterSignatureAction direktifi kural kümelerini yönetmeyi kolaylaştırır. 1.9RC1’dan önce eğer birisi kural başına işlem listesi kullanmak isteseydi bütün işlem listeleri tam olmalıydı, yani her işlem listesi ana işlemi, durum kodunu, vb. belirtmeliydi. Bu durum kuralların yapılandırma politikasından ayrılmasını çok zor kılıyordu. SecFilterSignatureAction direktifi tek bir yapılandırma kapsamında birden fazla yerde belirtilebilir ve hemen onu izleyen bütün kurallara uygulanır. Tutarlı olması açısından özel yapım işlemleri içermeyen kurallar bu direktiften işlem listelerini kalıtır. Örnek olarak:

SecFilterDefaultAction log,deny,status:500
 
# Aşağıdaki kural çalıştırıldığı kapsamdaki 
# işlemler ile yanıt verir
# Bir kuralın çalıştırıldığı kapsam 
# yazıldığı kapsam olmayabileceğine dikkat etmelisiniz.
# Kalıtım yolu ile bir kural birden fazla 
# kapsamda çalıştırılabilir.
SecFilter 000
 
# Uyarı kuralları
SecFilterSignatureAction log,pass
SecFilter 111 id:1
SecFilter 222 id:2
 
# Hata kuralları
SecFilterSignatureAction log,deny,status:403
SecFilter 333 id:3
SecFilter 444 id:4
# Aşağıdaki kural da, 403 durum kodu ile reddeder
SecFilter 555

SecFilterActionsRestricted ile beraber kullanıldığında bu direktif yapılandırmaya üçüncü parti kural kümelerinin konulmasını kolaylaştırır.

Not

SecFilterSignatureAction direktifinin değeri alt kapsamlar tarafından kalıtılmaz.

Kural başına işlem listesinde belirebilecekleri kısıtlama

Bazen, yapılandırmanıza üçüncü parti kuralları koymak istediğinizde, içlerinde hangi işlemlerin bulunması gerektiğini belirtmek isteyebilirsiniz. Bunu SecFilterActionsRestricted direktifinin yardımı ile yapabilirsiniz:

SecFilterSignatureAction log,deny,status:403
SecFilterActionsRestricted On
Include conf/third-party-rules.conf

Kısıtlı mod açıldığında kural başına yapılandırmada izin verilecek işlemler sadece yardımcı veri (meta-data) kurallarıdır: id, msg, rev, ve severity. Diğer kurallar sessizce görmezden gelinir.

Kurulum ile gelen işlemler

pass

Filtre eşleşmesinde isteğin devam etmesini sağlar. Bu işlem, eşleşmeyi sadece kaydetmek (başka bir işlem yapmamayı) istediğinizde kullanışlıdır.

SecFilter KEYWORD "log,pass"

allow

Bu bir önceki filtrenin daha güçlü versiyonudur. Bu işlem uygulandıktan sonra istek diğer hiçbir filtre uygulanmadan devam edecektir:

# filtreleme işlemini yöneticinin bilgisayarından
# gelen istekler için durdur
SecFilterSelective REMOTE_ADDR "^192\.168\.2\.99$" allow

deny

Filtre eşlemesinde işlemi kes. Durum kodu da kullanılmadığı takdirde, ModSecurity hemen HTTP 500 hata kodu dönecektir. Bir istek reddedildiğinde mod_security-action başlığı istek başlık listesine eklenecektir. Bu başlık kullanılan durum kodunu içerecektir.

status

İstek reddedildiğinde belirtilen HTTP durum kodunu kullan. Aşağıdaki kural:

SecFilter KEYWORD "deny,status:404"

Tetiklendiğinde "Page not found" dönecektir. Eğer yapılandırma dosyasında var ise Apache ErrorDocument direktifi tetiklenecektir. Bu nedenle eğer daha önceden belirtilen bir durum kodu için özel yapım bir hata sayfası tanımladıysanız, bu sayfa çalıştırılacak ve kullanıcıya gösterilecektir.

redirect

Filtre eşleşmesinde kullanıcıyı verilen URL’ye yönlendir. Örnek olarak:

SecFilter KEYWORD "redirect:http://www.modsecurity.org"

Bu yapılandırma direktifi her zaman HTTP durum kodunu veya deny anahtar kelimesini silecektir (override). URL virgül içermemelidir.

proxy

Filtre eşleşmesi durumunda dahili ters vekil (inverse proxy) yolu ile isteği yeniden yaz (rewrite):

SecFilter KEYWORD "proxy:http://www.example.com"

Bu işlemin çalışması için mod_proxy kurulmuş olması gerekir.

exec

Filtre eşleşmesinde bir ikili (binary) çalıştır. İkili için tam yol belirtilmelidir:

SecFilter KEYWORD "exec:/home/ivanr/report-attack.pl"

Bu direktif var olduğunda ana işlemleri etkilemez. Bu işlem, betiği bütün çevre değişken bilgilerini sağlayarak ama parametresiz çağıracaktır. Normalde bulunan bütün CGI çevre değişkenleri sağlanacaktır.

Her filtre eşleşmesinde tek bir ikili çalıştırabilirsiniz. Bu işlem mod_security-executed başlığını istek başlıklarına ekleyecektir.

Not

İş parçacıklı (kanallı, threaded) bir süreci (process) başlatmanın (forking), yeni süreçte bütün iş parçacıklarının kopyalanacağından haberdar olmanız gerekir. Bu nedenle süreç başlatma çok iş parçacıklı (multi-threaded) operasyonda büyük bir performans yükü getirir.

log

Filtre eşleşmesini Apache hata dosyasına kaydet.

nolog

Filtre eşleşmesini kaydetme. Bu aynı zamanda denetleme (audit) kaydının da olmasını engelleyecektir

skipnext

Bu işlem bir veya birden fazla kuralı atlamanıza izin verir. Bu işlemi bazı isteklerde daha fazla test gerçekleştirmeyi istemediğinizde kullanacaksınız. Varsayılı olarak (by default), işlem diğer kurala atlar. Opsiyonel parametreyi sağlamanız durumunda istediğiniz kadar kural atlayabilir.

SecFilterSelective ARG_p value1 skipnext:2
SecFilterSelective ARG_p value2
SecFilterSelective ARG_p value3

chain

Kural zincirlemesi bir çok kuralı daha büyük bir test haline getirmenize izin verir. Sadece zincirdeki en son kural zinciri etkileyecektir ama ona ulaşmak için diğer bütün kurallar da eşleşmelidir. İşte bu özelliği nasıl kullanabileceğinize bir örnek:

Yönetici hesabına sadece belli bir IP’den girilmesini istiyorum. Ama yönetici giriş paneli diğer kullanıcılar ile paylaştırılmış ve bu nedenle Apache’nin standard özelliklerini kullanamıyorum. Bu nedenle bu iki kuralı kullandım:

SecFilterSelective ARG_username admin chain
SecFilterSelective REMOTE_ADDR "!^SİZİN_IP_ADRESİNİZ_BURAYA$"

İlk kural sadece username parametresi varsa ve değeri admin ise eşleşir. Ondan sonra ikinci kural çalışır ve istekteki istemcinin adresini belli bir IP adresine eşleştirmeye çalışır. Eğer bir eşleşme olmazsa (baştaki ünlem işaretine dikkat edin) istek reddedilir.

pause

Bir isteğe cevap vermeden belli bir milisaniye kadar bekle. Bu bazı otomatik web tarayıcılarının yavaşlatmak veya tamamen kafasını karıştırmak için kullanışlıdır. Eğer bekleme süresi çok fazla ise bazı tarayıcılar taramayı bırakır.

Not

Bu opsiyonu kullanırken dikkat edin çünkü bir yan etkisi vardır. Bütün web sunucu kurulumları bir limit ile yapılandırılır, verilen herhangi bir zamanda hizmet edilecek en fazla istek sayısı. Bu seçenekle kullanılacak uzun bir bekleme zamanı açıklık tarayıcıları istekleri paralel yapıyorsa bir hizmet dışı saldırısına davetiye çıkarabilir.

auditlog

İşlem bilgisini denetleme (audit) kaydına kaydet.

noauditlog

İşlem bilgisini denetleme (audit) kaydına kaydetme.

id, rev, msg, severity

Bu dört işlemin hepsi bir parametre ister ve ModSecurity tarafından çıktı olarak üretilen her kayıt mesajında bu parametreleri koyarlar. Buradaki fikir problemleri sınıflandırmak ve hata kayıt dosyalarına daha fazla bilgi koymabilmektir.

·         id - biricik kural ID’si

·         rev - kural revizyonu; eğer yoksa “1” olarak kabul edilir; ne zaman bir kural değişse revizyon değeri arttırılmalıdır.

·         msg - hata kayıt mesajlarında çıkacak bir yazı mesajı

·         severity - tanımlanmamış özel yapım önem dizgisi (string)

Not

Bu işlemler sadece bağımsız kurallarda veya kural zincirinin başlangıç kuralında kullanılır.

Her ne kadar id işlemi her hangi bir yazıyı içerebilse de, sadece tam sayıların kullanılması önerilir. Geçerli kural ID’lerinin ilerde sadece tam sayıları içermeyeceğini kimse garanti edemez. Eğer kurallarınızı halka açmayı düşünmüyorsanız, yerel aralığı kullanmalısınız: 1-99,999. Bunlar ayrılmış aralıklardır:

·         1 - 99999 dahili ihtiyaçlarınızı için ayrılmışlardır, istediğiniz gibi kullanın ama başkalarına yaymayın.

·         100,000-199,999 motorun dahili kullanımı için ayrılmıştır, belirlenmiş ID’leri olmayan kurallara eşitlemek için

·         200,000-299,999 modsecurity.org tarafından yayınlanacak kurallar için ayrılmıştır.

Aralık rezervasyonu için Ivan Ristic ile bağlantı kurun.

mandatory

Bu işlemi bir kuralı veya bir kurallar zincirini alt kapsamlarda zorunlu kalıtılacak (inherited) şeklinde işaretlemek için kullanın. Daha detaylı bilgi için filtre kalıtımı bölümünü okuyun.

Not

mandatory işlemi sadece bağımsız kurallarda veya kural zincirinin başlangıç kuralında kullanılır.

Örnek olarak:

SecFilter 111 mandatory

veya

SecFilter 111 mandatory,chain
SecFilter 222

setenv, setnote

Bu iki işlem, Apache’nin veya çevre değişkeninin değerini değiştirir veya kaldırır. Kullanabileceğiniz üç format vardır.

İsim ve değer:

SecFilter KEYWORD setenv:name=value

Sadece isim, bir değer olarak “1” kabul edilecektir:

SecFilter KEYWORD setenv:name

Varolan bir değişkeni, değişken isminin başına bir ünlem işareti koyarak silin:

SecFilter KEYWORD setenv:!name

mod_security tarafından eklenen istek başlıkları

Mümkün oldukça, ModSecurity istek başlıklarına bilgi ekleyecektir, böylece betiklerinizin onları bulup kullanmasına izin verecektir. Tabi ki, ModSecurity’i betiklerinizin çalışması için istekleri reddetmeyecek şekilde yapılandırmanız gerekecektir. İlk bakışta çevre değişkenlerinin yerine istek başlıklarını bu sebep için kullanmam garibinize gidebilir. Çevre değişkenlerini kullanmak daha şık olabilirdi ama girdi başlıkları, ErrorDocument direktifi (aşağıda) ile çalıştırılan betiklere görünürken, çevre değişkenleri görünmez.

Bu eklenen başlıkların listesidir:

·         mod_security-executed; çalıştırılan ikiliye (binary) olan yol ile

·         mod_security-action; dönülen durum kodu ile

·         mod_security-message; tespit edilen problem hakkındaki ve hata kaydına eklenen mesajla

İstek gövdesini (body) kaydetmek

ModSecurity bir istek gövdesini mod_security-body notu ile ihraç (export) eder. Bunu kayıdetmek için kullanabilirsiniz:

LogFormat "%h %l %u %t \"%r\" %>s %{mod_security-body}n 

Not

Eğer istek multipart/request-data (karşıdan dosya yüklemek) tipindeyse, gerçek istek gövdesi taklit bir application/x-www-form-urlencoded içeriği ile değiştirilir. 

ErrorDocument kullanarak kural eşleşmelerini yönetmek

Eğer yapılandırmanız HTTP 500 durum kodunu dönüyorsa, ve bu durum oluştuğunda Apache’yi özel yapım (custom) bir betik çalıştırması için ayarlarsanız (mesela ErrorDocument 500 /error500.php), hatalara karşı, sevdiğiniz betik motorunu cevap vermesi için kullanabilirsiniz. Hata üzerindeki bilgi REDIRECT_* ve HTTP_MOD_SECURITY_* çevre değişkenleri olacaktır. (burada bahsedildiği gibi: http://httpd.apache.org/docs-2.0/custom-error.html)

ModSecurity’nin güvenlik duvarınızla konuşmasını sağlamak

Bazı durumlarda, tehlikeli saldırıları veya bir seri saldırı durumunu belirledikten sonra aynı kaynaktan daha fazla saldırı gelmesini engellemek isteyebilirsiniz. Bunu güvenlik duvarınızı belli bir IP adresinden gelen trafiği önleyecek şekilde değiştirerek yapabilirsiniz. (iptables ile çalışan yardımcı bir betik yazmıştım, buradan indirebilirsiniz: http://www.apachesecurity.net/)

Bu metot çok tehlikeli olabilir çünkü bir hizmet dışı saldırısı (DoS) ile sonuçlanabilir. Mesela, bir saldırgan saldırıyı başlatmak için bir vekil (proxy) kullanabilir. Bir vekilden gelen bütün istekleri reddetmek çok tehlikeli olabilir çünkü diğer bütün meşru kullanıcılar da bundan etkilenecektir.

Bir çok vekil, orijinal istemcileri tanımlayan bilgiler gönderdiğinden (bu konu hakkında bazı bilgilere buradan ulaşılabilir http://www.modsecurity.org/documentation/modsecurity-apache-manual-1.9.html???, "Stop hijacking" başlığı altında), akıllıca davranıp gerçek IP adresini bulabilirsiniz. Bu mümkündür, ama bir de aşağıdaki senaryoyu düşünün:

·         Saldırgan uygulamaya direk olarak erişir ama gerçek kaynak IP adresi olarak rasgele veya geçerli bir IP adresi koyarak bir vekilmiş gibi davranır. Eğer bu bilgiyi göz önünde bulundurarak istekleri reddetmeye başlarsak, saldırgan IP adresini değiştirip devam edecektir. Sonuç olarak saldırgan uygulamanın açıklıklarını bulmaya çalışırken geçerli kullanıcıları reddetmiş oluruz.

Bu nedenle bu metod sadece vekillerden uygulamaya ulaşılmasına engel olursanız veya sadece çok iyi tanınan veya daha önemlisi güvenilen vekillerden uygulamaya ulaşılmasını sağlarsanız işe yarar.

Eğer hala IP tabanlı olarak istekleri reddetmek istiyorsanız (bütün uyarılarımıza rağmen), filtre eşleşmesinde çalışacak bir betik yazmanız gerekir. Betik çevre değişkenlerinden saldırganın IP adresini alıp, iptables veya ipchains’i verilen IP adresini reddetmeleri için çağırmalıdır. mod_security ileri bir sürümünde böyle bir betik içerecektir.

Extra Özellikler

Karşıdan dosya yükleme desteği

ModSecurity, POST istekleri ve multipart/form-data kodlaması veya (1.9 ile beraber) PUT istekleriyle karşıdan yüklenen dosyaların yakalanabilmesini sağlar.

Karşıdan yüklenen dosyaların nereye yükleneceğini seçme

ModSecurity her zaman dosyaları geçici bir dizine yükleyecektir. Bu dizini SecUploadDir direktifi ile belirtebilirsiniz:

SecUploadDir /tmp

Sadece web sunucu kullanıcısının ulaşabileceği bir dosya alanın kullanılması daha iyidir. Öteki türlü, diğer sunucu kullanıcıları web sunucu tarafından yüklenen dosyalara erişebilirler.

Dosyaların doğruluklarını sağlama

Web sunucusundan uygulamaya geçmeden dosyaların doğruluklarını sağlayacak harici bir betik çalıştırmayı seçebilirsiniz. SecUploadApproveScript direktifi bu fonksiyonu kullanmaya açar. Aşağıdaki örnekte ki gibi:

SecUploadApproveScript /full/path/to/the/script.sh

Betiğe komut satırından sadece bir parametre sağlanır – karşıdan yüklenen dosyanın tam yolu. Betik dosya ile istediği her şeyi yapabilir. Dosyayı işledikten sonra, cevabını standard çıktıya (stdout) yazmalıdır. Eğer cevabının ilk karakteri “1” olursa dosya kabul edilir. Bunun dışında herşey dosyanın reddedilmesine sebep olur. Betiğiniz satırın geri kalanını daha yararlı bir hata mesajı için kullanabilir. Bu mesaj hata ayıklama kaydına (debug log) yazılacaktır.

Karşıdan yüklenen dosyaları depolama

Web sunucu aracılığı ile karşıdan yüklediğiniz dosyaları tutmak isteyebilirsiniz. Aşağıdaki satırı yapılandırmanıza ekleyin:

SecUploadKeepFiles On

SecUploadDir direktifi tarafından belirtilen yere dosyalarınız depolanacaktır. Eğer sadece seçtiğiniz bazı dosyalarınızı tutmak istiyorsanız:

SecUploadKeepFiles RelevantOnly

Böylece sadece ilgili olarak tanımlanmış isteklerinize ait dosyalar depolanacaktır.

Geri plandaki diğer programlarınız ile etkileşim

Geri plandaki diğer programlarınızla etkileşime izin vermek için (mesela daha sonra açıklanacağı gibi ClamAV), 1.9dev1 ile birlikte dosyalar, grup okumasına izin verecek şekilde gevşetilmiş izinlerle oluşturulmaktadırlar. Bunu yapmak için, Apache’nin httpd ve geri plandaki programın clamav olarak koştuğunu farzedersek:

# mkdir /tmp/webfiles
# chown httpd:clamav /tmp/webfiles
# chmod 2750 /tmp/webfiles

Bu yapılandırma sonrası, clamav kullanıcısı dizine ulaşabilecektir. Aynı şey, clamav grup sahibi olduğundan, diğer dosyalar için de geçerlidir. Dosyaları /tmp/webfiles dizinine yüklemek için SecUploadDir direktifini kullanmayı unutmayın.

Not

Eğer dosyaları tutuyorsanız, onları bulundukları yerde web sunucu kullanıcısı hakları ile saklamanız güvenli olmayabilir. Mesela, web sunucunuzda modül olarak PHP ve güvenmediğiniz kullanıcılar koşuyorsanız, dosyalara ulaşabilirler. Dosyaları sadece root tarafından okunabilir hale getirmek için bir cron betiği yazmayı ve dosyaları tamamen başka bir yere taşımayı düşünün.

ClamAV ile entegrasyon

ModSecurity, dosya kabul mekanizmasını ClamAV virüs tarayıcısı ile bütünleştirmek için bir betik içerir. Bu özellikle, karşıdan dosya yükleme yolu ile web sunucusuna bulaşan virüsleri ve etkileyen açıklıkları engellemek için kullanışlıdır.

#!/usr/bin/perl
#
# modsec-clamscan.pl
# mod_security, http://www.modsecurity.org
# Copyright (c) 2002-2004 Ivan Ristic <[email protected]>
#
# $Id: modsecurity-manual.xml,v 1.7 2005/11/01 13:59:55 ivanr Exp $
#
# This script is an interface between mod_security and its
# ability to intercept files being uploaded through the
# web server, and ClamAV
 
# by default use the command-line version of ClamAV,
# which is slower but more likely to work out of the
# box
$CLAMSCAN = "/usr/bin/clamscan";
 
# using ClamAV in daemon mode is faster since the
# anti-virus engine is already running, but you also
# need to configure file permissions to allow ClamAV,
# usually running as a user other than the one Apache
# is running as, to access the files
# $CLAMSCAN = "/usr/bin/clamdscan";
 
if (@ARGV != 1) {
    print "Usage: modsec-clamscan.pl <filename>\n";
    exit;
}
 
my ($FILE) = @ARGV;
 
$cmd = "$CLAMSCAN --stdout --disable-summary $FILE";
$input = `$cmd`;
$input =~ m/^(.+)/;
$error_message = $1;
 
$output = "0 Unable to parse clamscan output [$1]";
 
if ($error_message =~ m/: Empty file\.$/) {
    $output = "1 empty file";
}
elsif ($error_message =~ m/: (.+) ERROR$/) {
    $output = "0 clamscan: $1";
}
elsif ($error_message =~ m/: (.+) FOUND$/) {
    $output = "0 clamscan: $1";
}
elsif ($error_message =~ m/: OK$/) {
    $output = "1 clamscan: OK";
}
 
print "$output\n";

Karşıdan yükleme hafıza limiti

Apache 1.x istek yakalamak için yeterli bir alt yapı sağlamaz. Ancak tamamen işlem hafızasında tutabilinen istekler yakalanabilir. Apache 1.x ile iki seçenek mevcuttur: multipart/form-data isteklerini aynı hafızada analiz etmek veya hiç analiz etmemek.

Ama Apache 2.x ile beraber ayrıştırmak (parse) isteğiniz multipart/form-data isteklerine hafızada ayrılacak büyüklüğü tanımlayabilirsiniz. Eğer istek belirttiğinizden daha fazla hafıza kaplıyorsa, geçici bir dosya kullanılacaktır. Varsayılı değer 60 KB’dir ama SecUploadInMemoryLimit direktifi kullanılarak limit değiştirilebilir:

SecUploadInMemoryLimit 125000

Sunucu kimlik maskelemesi

Saldırganların kafasını karıştıran veya yavaşlatan bir teknik web sunucusunun kimliğinin değiştirilmesidir. Web sunucuları tipik olarak kimliklerini bütün HTTP cevaplarında Server başlığı altında yollarlar. Apache özellikle bu nokta faydalıdır, sadece kendi kimliğini ve tam sürüm numarasını vermekle kalmaz, sunduğu modüllerin de sürüm numaralarını da ekler.

Apache web sunucusunun kimliğini değiştirmek için, kaynak koduna gitmeniz, “Apache”nin yazıldığı yeri bulmanız, değiştirmeniz ve sunucuyu yeniden derlemeniz gerekir. Aynı etki, SecServerSignature direktifi ile de başarılır.

SecServerSignature "Microsoft-IIS/5.0"

Bu iyi çalıştığı halde yetenekli saldırganlar (ve araçlar) web sunucunuzun kimliğini başka yollarla da bulabileceklerini bilmeniz gerekir. Mesela,  varsayılı dosyalar, hata mesajları, cevap başlıklarının sıralaması, sunucunun belli isteklere verdiği cevaplar – bütün bunlar web sunucunuzun kimliğini ortaya koyar. mod_security’nin ilerki versiyonlarında web sunucusu kimliğiniz daha iyi gizlenmesi hakkında geliştirmeler yapacağım.

If you change Apache signature but you are annoyed by the strange message in the error log (some modules are still visible - this only affects the error log, from the outside it still works as expected):

Eğer Apache imzasını değiştirip, hata kayıtlarında garip mesajlar görürseniz (bazı modüller hala görünür – bu sadece hata kaydını etkiler, dışarıdan hala umulduğu gibi çalışmaktadır.):

[Fri Jun 11 04:02:28 2004] [notice] Microsoft-IIS/5.0 mod_ssl/2.8.12 OpenSSL/0.9.6b \
configured -- resuming normal operations

modüllerinizin yüklenme sırasını değiştirip mod_security’nin en son çalışmasına izin vermelisiniz, chrooting için anlatıldığı gibi (aşağıda).

Not

Bu direktifin çalışması için ServerTokens için Full değerini vermeniz gerekir.

SecServerSignature direktifi sunucu kimliğini değiştirmek için kullanıldığında, web sunucuyu tanımlamanız ve hangi modüllerin kullanıldığını anlamanız için, ModSecurity gerçek imzayı hata mesajlarına yazmaya başlayacaktır

[Fri Jun 11 04:02:28 2004] [notice] mod_security/1.9dev1 configured - Apache/2.0.52 \
(Unix) PHP/4.3.10 proxy_html/2.4

Chroot desteği

Standard yaklaşım

ModSecurity, Apache dosya sistemi izolasyonuna, diğer bir deyişle chrooting işlemine destek verir. Chrooting, bir uygulamayı dosya sisteminin bazen “hapishane” de denilen belli bir bölümüne hapsetmektir. Chroot (change root’ın kısaltılmışı) operasyonu uygulandığında uygulama, hapishanenin dışındakilere artık ulaşamaz. Sadece root kullanıcısı hapishaneden kaçabilir. Chrooting işleminin hayati bölümlerinden bir tanesi, root ile alakalı herhangi bir şeyin (root işlerinin -processes- veya root suid ikililerinin -binary-) hapishane içine erişememesidir. Ana fikir, herhangi bir saldırgan web sunucusunu kırmayı başarsa da çok fazla bi şey yapamayacaktır, çünkü o da hapishanede olacağı için kaçacak bir yeri olmayacaktır.

Uygulamalar chrooting’e destek vermek zorunda değildirler. Chroot ikilisi (binary) kullanılarak herhangi bir uygulama chroot içinde kullanılabilir. Aşağıdaki satır:

chroot /chroot/apache /usr/local/web/bin/apachectl start

dosya sistemini /chroot/apache dizinin altında ne varsa değiştirerek Apache’yi başlatacaktır.

Ne yazık ki, işler bu kadar kolay değildir. Uygulamaların düzgün çalışmak için paylaşılan kütüphanelere (shared libraries) ve diğer bir çok dosyalara ve ikililere ihtiyaç duymaları problem yaratır. Bu nedenle, ihtiyaç duydukları dosyaların kopyalarını alıp hapishane içine koymanız gerekir. Bu kolay bir iş değildir (Apache web sunucusunu chroot yapmak üzerine bilgiler için buraya bakınız: http://www.modsecurity.org/documentation/modsecurity-apache-manual-1.9.html???).

mod_security yaklaşımı

Apache’ye chrooting işlemi yaparken sıkılmış ve işlemi daha basitleştirmek için yollar aramaya başlamıştım. Sonuç olarak, chrooting özelliğini mod_security modülünün kendisine ekleyerek bütün işlemi daha az karmaşık hale getirdim. Yapılandırma dosyasına sadece bir satır eklemeniz gerekir:

SecChrootDir /chroot/apache

ve böylece web sunucunuza başarılı bir şekilde chroot işlemini uygulamış olacaksınız.

Basitliği bir tarafa, ModSecurity chrooting işlemi diğer bir avantajı da beraberinde getirir. Harici chrooting’den (daha önce bahsedildiği gibi) farklı olarak, ModSecurity chrooting hapishanede bulunmak için extra dosyalara ihtiyaç duymaz. Chroot çağrısı web sunucu ilklendirmesinden sonra ama sürecin başlatılmasından (forking) önce yapılır. Bütün bunlardan dolayı, bütün paylaşılan kütüphaneler çoktan yüklenmiş, bütün web sunucu modülleri ilklendirilmiş ve kayıt dosyaları açılmıştır. Sadece bilgilerinizin hapishanede bulunması gerekecektir.

Ancak CGI betikleri ve sistem ikililerini çalıştırmak istediğinizde hapishaneye koymanız gereken ek dosyalar olacaktır. Bu dosyaların kendi dosya gereksinimleri olabilir. Eğer bu kategoride iseniz normalde yapacağınız gibi harici chroot prosedürünü uygulamanız gerekir.

Not

Apache 2.x ile, AcceptMutex direktifinin varsayılı değeri pthread dir. Bazen bu yapılandırma ayarı chroot özelliği kullanıldığında Apache’yi çalışmaktan alıkoyar. Bu problemi aşmak için AcceptMutex değerini herhangi bir değere eşitleyin (mesela posixsem)..

Eğer chroot’u kayıt dosyalarını hapishane dışında tutacak şekilde yapılandırırsanız, Apache’nin hapishane dışındaki dosyalara işaret eden dosya tanımlayıcıları (file descriptors) olacaktır. Chroot mekanizması ilk önceleri güvenlik için dizayn edilmemiştir ve bazı insanlar bu durum hakkında pek rahat değillerdir. Kendi kararınızı verin. Bu özelliği deneme amaçlı kullanın.

Not

Eğer Apache kurulumunuz mod_ssl kullanıyorsa, dosya tabanlı SSL mutex’i kullanıldığında kayıt dizinini hapishane dışında bırakmanın mümkün olmadığını anlarsınız. Çünkü mod_ssl açılış ile beraber hemen bir kilit (lock) dosyası oluşturur, ama daha sonra bulamadığından başarısızlığa uğrar. Bu problem diğer bir mutex çeşidi (mesela SSLMutex sem) kullanıldığında veya mod_ssl‘ye bu dosya tabanlı mutex’i hapishane içerisindeki bir dizine koymasını söylediğinizde ortadan kalkar (SSLMutex file://path/to/file kullanarak).

Not

Eğer chroot özelliğini birçok kanallı Apache kurulumu ile kullanmaya çalışırsanız, şu mesajı alabilirsiniz "libgcc_s.so.1 must be installed for pthread_cancel to work". Bu problemi çözmek için Apache yapılandırmanıza LoadFile /lib/libgcc_s.so.1 ekleyin.

Kimlik doğrulama için Apache tarafından kullanılan dosyalar her istek sırasında açıldıklarından hapishane içerisinde olmalıdırlar.

chroot desteği için gerekli modül sıralaması (Apache 1.x)

Not

Kayıt dosyalarını hapishane içerisinde bırakırsanız bu adıma gerek kalmaz.

Yukarıda da anlatıldığı gibi, chroot çağrısı Apache ilklendirmesinin (initialization) belli bir anında yapılmalıdır (diğer bütün modüller ilklendirildikten sonra). Bu ModSecurity’nin listelenen modüllerden ilki olmasını gösterir. Bunu sağlamak için, aşağıdaki yapılandırma direktiflerini kullanarak modül sıralamasında bir kaç değişiklik yapmanız gerekecektir.

ClearModuleList
AddModule mod_security.c
AddModule ...
AddModule ...
AddModule ...

İlk direktif listeyi temizler. ModSecurity’i hemen sonrasına koymanız gerekir, daha sonra kullanmak istediğiniz diğer bütün modüller (her zaman otomatik olarak eklenen ve kafanıza takmanız gerekmeyen http_core.c hariç) sıralanır. Kurulu modüllerin listesini httpd ikilisini –l sekmesi ile koşarak görebilirsiniz:

./httpd -l

Not

Eğer Apache ikilisini ve destekleyen dosyaları hapishanenin dışında bırakmayı seçerseniz, apachectl graceful ve apachectl restart komutlarını daha fazla kullanamazsınız. Bu Apache’nin hapishanenin dışında çıkmasını gerektirir ki bu durm imkansızdır. Apache 2 ile beraber apachectl stop komutu bile çalışmayabilir. İlerki dağıtımlarda çözüm için bir değiştirici (replacement) betik oluşturabilirim.

chroot desteği için gerekli modül sıralaması (Apache 2.x)

Not

Kayıt dosyalarını hapishane içerisinde bırakırsanız bu adıma gerek kalmaz.

Apache 2.x ile beraber modül sıralamasını elle yapılandırmanıza gerek yoktur. Çünkü Apache 2.x’in dahili olarak zaten modül sıralaması için desteği vardır. ModSecurity bu özelliği kullanarak tam olarak ne zaman çağırılacağını Apache 2.x’ye anlatır ve böylece chroot çalışır (Eğer bir problem yaşıyorsanız bana bildirin).

Apache 2’de sürecin nasıl çalıştırılacağı hakkında bir değişiklik vardır. httpd ikilisinin kendisi süreç numarısı ile pid dosyasını oluşturur. Bu nedenle Apache’yi hapishanenin dışında olduğu gibi hapishanenin içinde de aynı dizine koymanız gerekir. Hapishane dışındaki Apache’nin /usr/local/web/apache olduğunu ve hapishanenin /chroot olacağını farzedersek /chroot/usr/local/web/apache/logs dizinini oluşturmanız gerekir.

Çalıştırıldığıda, Apache pid dosyasını orda oluşturacaktır (httpd.conf dosyasındaki pid dosyasının yerini değiştirmediğinizi farzederek).

Adım adım chroot kılavuzu

Eğer bu adım adım kılavuzu izlerseniz, modül sıralaması ile uğraşmak zorunda bile kalmazsınız. Önce normalde yapacağınız gibi Apache’yi kurun. Burada Apache’nin /usr/local/apache dizinine kurulduğunu farzedelim. Ayrıca hapishanenin /chroot/apache dizinine yerleştirileceğini de farzedelim. Kurulumun başarılı olup olmadığını kontrol etmek için sunucuyu başlatmak her zaman iyi bir fikirdir.

# mkdir -p /chroot/apache/usr/local
# cd /usr/local
# mv apache /chroot/apache/usr/local
# ln -s /chroot/apache/usr/local/apache

Şimdi ModSecurity’e başladığında chroot işlemi yapmasını gösterin:

SecChrootDir /chroot/apache

Ve Apache’yi başlatın:

/usr/local/apache/bin/apachectl startssl

Not

Bu prosedür, Apache dosyalarının chroot işlemi gerçekleştikten sonra hapishanenin içerisinde bırakılacağı bir yaklaşımı gösterir. Bu yaklaşım, önerilen bir yaklaşımdır çünkü her zaman çalışır ve çünkü chroot yapılmayan bir Apache’den chroot yapılan birine geçiş çok kolaydır (yapılandırma dosyasında SecChrootDir direktifini basitçe yorum haline getirmekle). Ancak dosyaların çoğunun dışarıda bırakılacağı bir hapishane oluşturmak tamamen mümkündür. Ama bu seçeneğin doğru çalışması çok zordur. Bu seçeneğin doğru çalışması için chroot mekanizmasının çok iyi anlaşılması gerekir.

Not

Sürüm 1.8’den beri, eğer ModSecurity herhangi bir nedenden dolayı başarısız olursa sunucunun başlamasına izin vermez. Yapılandırma fazında chroot başarısızlığını belirlemez ve sonra yürütme zamanında anlarsa, bunun hakkında hata kaydına bir mesaj düşer ve alt süreci bitirir. Bu güzel olmayabilir ama çalıştığını düşündüğünüz ama gerçekte çalışmayan bir chroot olmasından daha iyidir.

Performans Ölçümü

1.9dev1’de ModSecurity’nin Apache 2 sürümünde performans ölçümü için deneysel bir destek getirmiştim. İstemciler yavaş bir bağlantı üzerinde iseler betik performansının ölçülmesi bazen zordur. Cevap hem üretilip hem de istemciye yollandığından ikisini birbirinden ayırmak mümkün değildir. Performansı ölçmenin tek yolu cevabı parçalar halinde göndermeyip, sadece tam olarak üretimi bittiğinde yollamaktır. ModSecurity’nin de tam olarak yaptığı budur (güvenlik sebeplerinden) ve böylece bu durumu performans ölçümünde kullanmak mantıklı hale gelir. Üç zaman ölçümü yapılır ve sonuçlar Apache notlarında kayıt edilir. Bütün zamanlar mikrosaniye biriminde süreç başlangıcına göre ölçülür.

·         mod_security-time1 – ModSecurity ilklendirmesi biter. Eğer istek bir gövde (body) içeriyorsa, şimdiye kadar çoktan okunacaktır (POST taraması açıksa).

·         mod_security-time2 – ModSecurity işlem çalışmasını bitirir. En son çalışmak istediğimizden, istek bir işleyici tarafından işlenmeden hemen önce, bu zaman işlemin başlamasından kabaca hemen öncedir.

·         mod_security-time3 – cevap üretilmiş ve istemciye yollanmak üzeredir.

Bu değerleri özel yapım bir kayıt dosyasında kullanmak için şunu yapın (tekrar, bu sadece Apache 2’de çalışır):

CustomLog logs/timer_log "%h %l %u %t \"%r\" %>s %b - \
%<{mod_security-time1}n %<{mod_security-time2}n \
%<{mod_security-time2}n %D"

Kayıttaki her eleman aşağıdaki gibi gözükecektir:

82.70.94.182 - - [19/Nov/2004:11:33:52 +0000] "GET /cgi-bin/modsec-test.pl HTTP/1.1" \
200 1418 - 532 1490 13115 14120

Yukarıdaki örnekte işlemin ModSecurity’e ulaşması 532 mikrosaniye sürmüştür. ModSecurity tanımlanmış kuralları çalıştırmak için 958 mikrosaniye (1490 - 532) harcamıştır ve CGI betiğinin çıktıyı üretmesi 11652 mikrosaniye (13155 - 1490) sürmüştür ve Apache’nin isteği istemciye yollaması 965 mikrosaniye sürmüştür. 

Kayıt Tutma

Hata ayıklama kaydı

Hata ayıklama çıktısının yazılacağı dosyayı seçmek için SecFilterDebugLog direktifini kullanın. Eğer parametre kesme işareti ile başlamıyorsa, Apache home yolu değerin başına eklenecektir.

SecFilterDebugLog logs/modsec_debug_log

Hata ayıklama kaydının ne kadar detaylı olmasını SecFilterDebugLevel direktifi ile ayarlayabilirsiniz:

SecFilterDebugLevel 4

Alabileceği değerler:

·         0 – hiç (bu değer üretim sistemlerinde her zaman kullanılmalıdır)

·         1 – önemli olaylar (bunlar aynı zamanda error_log dosyasında da raporlanacaktır)

·         2 – bilgilendirici mesajları

·         3 – daha detaylı bilgilendirici mesajlar

Not

ModSecurity dahili olarak 9’a kadar kayıt seviyeri kullanır ama bunlar sadece hata ayıklama amaçları için faydalıdır.

Denetleme (Audit) kaydı

Standard Apache kayıt tutması belli bir kullanıcının veya saldırganın adımlarını geriye doğru izlemenizde çok yardımcı olmaz. Problem, her isteğin sadece bir parçasının kayıt dosyasına yazılmasıdır. Bu problem ModSecurity’nin denetleme kayıt tutma özelliği ile iyileştirilebilir. Aşağıdaki iki direktif

SecAuditEngine On
SecAuditLog logs/audit_log

mod_security’e audit_log dosyasında kapsamlı bir denetleme kaydının olmasını istediğinizi  söyleyecektir. İşte bir isteğin nasıl kayıt edildiğine dair bir örnek:

========================================
Request: 192.168.0.2 - - [[18/May/2003:11:20:43 +0100]] "GET /cgi-bin/printenv?p1=666 \
HTTP/1.0" 406 822
Handler: cgi-script
----------------------------------------
GET /cgi-bin/printenv?p1=666 HTTP/1.0
Host: wkx.dyndns.org:8080
User-Agent: mod_security regression test utility
Connection: Close
mod_security-message: Access denied with code 406. Pattern match "666" at \
ARGS_SELECTIVE
mod_security-action: 406
 
HTTP/1.0 406 Not Acceptable
========================================

Bunu normalde Apache’den alacağınız gibi ilk satırda görebilirsiniz. İkinci satır, isteği halledecek işleyicinin (handler) ismini içerir. Tam istek (ek mod_security başlıkları ile beraber) ayraçtan sonra verilir ve cevap başlıkları (bu durumda sadece bir satır vardır) bir boş satırdan sonra verilir.

POST filtrelemesi açık olduğunda, POST verileri her zaman denetleme kaydında olur. Gerçek cevap asla olmaz (en azından bu sürümde).

Not

Denetleme kayıt verilerini işlerken dikkat edin. Dosyalar ağ üzerinden alınmış ama filtrelenmemiş ikili (binary) veriyi bulundurabilir. Bu veriler doğru şekilde halledilmezse tehlikerli olabilir (mesela terminal değişim karakterlerini içerebilirler).

Şu anda, modülün kayıt tutma parçası Apache 1.x hata mesajlarını Handler: satırının altındaki satırda kaydedecektir. Satır her zaman Error: ile başlayacaktır. Bu fonksiyonellik mümkün olursa, modülün Apache 2.x sürümüne eklenecektir.

Not

Kayıt tutma alt sistemi zamanı dolan istekleri kaydetmez.

Not

Kayıt başlıkları Date ve Server çıktı başlıklarını içermez. Bu, Apache’nin bu başlıkları cevap üretme işleminin en sonunda ekleyip bir modülün onları elde etmesini imkansız hale getimesindendir.

Cevap durum koduna bakarak neyin kaydedileceğini seçmek

1.9 ile beraber ModSecurity, istekleri uyarı veya hata üretmeseler bile seçmeli olarak denetleme kaydına düşürmek için kullanılan SecAuditLogRelevantStatus direktifini destekler. Web sunucusu üzerindeki uygulamalar ile basit bir iletişim kanalı kurmak gerçekten faydalı olabilir. Mesela, eğer uygulamanın her hangi bir dahili hata durumunda veya saldırı olduğunda her zaman HTTP 500 durum kodu ile cevapladığını bilirseniz, ModSecurity’i bu tür istekleri tam olarak kayıt edecek şekilde yapılandırabilirsiniz:

SecAuditLogRelevantStatus ^5

Bu direktif bir parametre kabul eder; cevap durum kodu ile eşleşen bir düzenli ifade (regular expression). Eğer bir eşleşme olursa, işlem ilgili kabul ve kaydedilir.

Biricik (Unique) istek tanımlayıcıları

If you add mod_unique_id to the Apache configuration mod_security will detect it and use the environment variable it generates (UNIQUE_ID). Its value will be written to the audit log. You could write the unique ID in an error page to the user and use it later to track and fix a false positive.

Eğer Apache yapılandırmasına mod_unique_id eklerseniz,  mod_security anlar ve ürettiği çevre değişkenini kullanır (UNIQUE_ID). Değeri denetleme kaydına yazılır. Kullanıcıya hata sayfası içerisinde

Ne kaydedileceğini seçmek

SecAuditEngine parametresi 4 değerden birini alır:

·         On - bütün istekleri kaydet

·         Off - hiçbir isteği kaydetme

·         RelevantOnly – sadece ilgili istekleri kaydet. İlgili istekler bir filtre eşleşmesine sebebiyet veren isteklerdir.

·         DynamicOrRelevant – dinamik olarak üretilen veya ilgili istekleri kaydet. İstek ancak bir işleyicisi varsa dinamik olarak kabul edilir.

ModSecurity’i dinamik isteklerin de kaydını almasına çalışmak yapılandırmanıza bağlı olarak bazen biraz iş gerektirir. Apache teorisinde, bir isteğe cevap işleyici (handler) ismi verilen bir yapı tarafından üretilir. Eğer bir isteğe bağlanan bir işleyici varsa, dinamik bir yapı olarak düşünülmelidir. Pratikte ise, Apache dinamik sayfalar servisini işleyicileri kullanmadan da verebilir (MIME çeşidine göre modülü seçer). Bu, eğer PHP’yi ana dağıtımda gelen şekilde yapılandırırsanız olur:

AddType application/x-httpd-php .php

Bu çalışır ama tam olarak doğru değildir. Ancak, eğer yukarıdaki satırı aşağıdaki ile değiştirirseniz:

AddHandler application/x-httpd-php .php

PHP’nin normal çalışacağı gibi Apache’nin de isteğe atanmış bir işleyicisi olacak ve denetleme kaydedicisi seçmeli olarak kayıt tutabilecektir.

1.9 ile beraber denetleme kaydedicisi bir şeyin ilgili olup olmadığına karar vermek için cevap kodunu dikkate alır. Şu an itibarıyle 4xx ve 5xx ilgili sayılmaktadırlar. Bu herhangi bir web uygulamasında gelen istekler üzerinde denetleme kaydının yapılmasını kolaylaştırır. Bir hata oluştuğunda normalde vereceğiniz gibi cevap verin ama sadece cevap kodunu mesela 500’e çevirin.

Yeni Denetleme Kayıt Çeşidi

Yeni denetleme kayıt çeşidi ModSecurity 1.9 ile beraber getirildi. Eski denetleme kayıt çeşidi gelişi güzel kayıt kullanımı için hala kullanışlıdır. Yeni denetleme kayıt çeşidi performansı arttırmak (paralel istekler arasında yazma işlemini senkronize etme işlemini ortadan kaldırmak için her yeni işlem için bir dosya oluşturulması), kaydı tutulan bilgi miktarını arttırmak ve gerçek zamanlı denetleme kaydı bir araya getirilmesi (aggregation) amacıyla oluşturuldu. Yeni denetleme kayıt çeşidi cevap gövdelerini (body) de kaydedebilir.

Not

Yeni denetleme kayıt çeşidinin çalışması için mod_unique_id modülünün aktif olması gerekir.

Örnek yapılandırma:

# Yes, we want to use the new format
SecAuditLogType Concurrent
 
# Directory where the files will be stored
# MUST NOT BE THE SAME AS THE APACHE LOGS FOLDER
SecAuditLogStorageDir /var/www/audit_log/
 
# The index of all files created
SecAuditLog /var/www/audit_log/index
 
# Choose what to log – everything (default is ABCFHZ)
SecAuditLogParts ABCDEFGHZ

Her denetleme kayıt dosyası için index dosyasında bir satır giriş oluşturulacaktır. Gerçek zamanlı denetleme kaydı bir araya getirilmesi (aggregation) gerçeklemek isteyenler kanallama kayıt mekanizmasını kullanarak denetleme kayıt girişleri hakkında bilgi almak için bir betik yapılandırmaları gerekir.

Tipik bir kayıt girişi aşağıdaki şekilde gözükür:

192.168.2.101 192.168.2.11 - - [15/Jul/2005:11:56:52 +0100] \
"POST /form.php HTTP/1.1" 403 3 "http://192.168.2.101:8080/form.php" \
"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.8) Gecko/20050511 \
Firefox/1.0.4" G3yTd38AAAEAAAM7BLwAAAAA "-" \
/20050715/20050715-1156/20050715-115652-G3yTd38AAAEAAAM7BLwAAAAA 0 1031 \
md5:dc910f6d647d47b32ae6e47326f0ca42

Satır bir “vcombined” kayıt formatı ile başlar ama sonra aşağıdaki alanları ekler:

·         unique_id

·         session_id (şu anda kullanılmamaktadır)

·         filename

·         offset

·         size

·         denetleme kayıt girişinin kriptografik özeti (hash) (şu anda MD5 kullanılmaktadır)

Tipik bir kayıt girişi aşağıdaki şekilde gözükebilir:

--67458b6b-A--
[15/Jul/2005:11:56:52 +0100] G3yTd38AAAEAAAM7BLwAAAAA \
192.168.2.11 4236 192.168.2.101 8080
--67458b6b-B--
POST /form.php HTTP/1.1
Host: 192.168.2.101:8080
User-Agent: Mozilla/5.0
Accept: */*
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-9,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://192.168.2.101:8080/form.php
Content-Type: application/x-www-form-urlencoded
Content-Length: 5
 
--67458b6b-C--
f=111
--67458b6b-E--
403 (Response body)
--67458b6b-F--
HTTP/1.1 403 Forbidden
Last-Modified: Fri, 08 Jul 2005 14:25:30 GMT
ETag: "decb4-3-34b96a80"
Accept-Ranges: bytes
Content-Length: 19
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: text/html
 
--67458b6b-H--
Message: Pattern match "111" at POST_PAYLOAD \
[id "1"] [rev "2"] [msg "3"] [severity "4"]
Apache-Handler: application/x-httpd-php
Stopwatch: 1126536042708000 11024 (7276* 7375 9842)
 
--67458b6b-Z--

Not

Denetleme kayıt verilerini incelerken dikkat ediniz. Dosyalar ağdan alınan ve filtrelenmemiş veriler içerebilirler. Eğer doğru bir şekilde işlenmezlerse bu tür veriler tehlikeli olabilir (yani bazı terminal kaçırma dizgileri (escape sequences) içerebilirler).

Kullanılabilir denetleme kayıt bölümleri:

·         A – denetleme kayıt başlığı (zorunlu)

·         B – istek başlıkları

·         C – istek gövdesi (body) (sadece eğer istek gövdesi varsa ve ModSecurity bunları yakalamak için yapılandırılmışsa)

·         D – ara (intermediary) cevap başlıkları (Sadece cevap gövdesinde ModSecurity’nin istemciye ulaşmasını engelleyecek bir problem oluştuğunda bu bölüm bulunur).

·         E – ara (intermediary) cevap gövdeleri (Sadece ModSecurity cevap gövdesini yakalayacak şekilde yapılandırıldığında, ve denetleme kayıt moturu bu durumu kayıt edecek şekilde yapılandırıldığında). Ara cevap gövdeleri gerçek cevap gövdesi ile ancak ModSecurity ara cevap gövdesini yakalamaz ise aynı olur. Ki bu durumda gerçek cevap gövdesi hata mesajını içerir (Apache varsayılı hata mesajını veya ErrorDocument sayfasını).

·         F – son cevap başlıkları (Apache tarafından her zaman son anda eklenen Date ve Server başlıklarını dışarıda tutarak).

·         G – RESERVE EDİLMİŞ (gerçek cevap gövdesi, şu anda gerçekleştirilmedi)

·         H – denetleme kayıt izleri

·         Z – son sınır (boundary), girişin (entry) sonunu belirtmesi amacıyla (zorunlu)

Guardian kaydı

1.9’dan beri ModSecurity yeni bir direktifi destekler,  SecGuardianLog. Bu direktif bütün erişim verisini kanallama kayıt (piped logging) özelliğini kullanarak diğer bir programa göndermek için dizayn edildi. Apache tipik olarak, veri paylaşımını zorlaştıran çoklu süreç şeklinde koşulduğu için, ana fikir bütün istekleri durumları muhafaza edilecek şekilde (stateful) gözleyecek ve böylece ek koruma sağlayacak bir tek harici süreç çalıştırılmasıdır.

Harici bir koruma aracı geliştirmesi bundan sonraki ModSecurity dağıtımlarının ana konusu olacaktır. Ama, bütün özellikleri ile çalışan bir araç, Apache httpd araçları projesinin bir parçası olarak zaten kullanılabilir (http://www.apachesecurity.net/tools/). Aracın ismi httpd-guardian ve Hizmet Dışı Bırakma saldırılarına karşı kullanılabilir. iptables tabanlı güvenlik duvarları ile iletişim kurmak için blacklist aracını kullanır ve dinamik olarak saldıran IP adreslerini bloke eder. httpd-guardian’ın hali hazırda kurulduğunu farzederek (daha detaylı talimatlar için kaynak koduna bakın) kurmak için Apache yapılandırmanıza sadece bir satır eklemeniz gerekir:

SecGuardianLog |/path/to/httpd-guardian

Varsayılı olarak (by default) httpd-guardian dakikada 120 veya beş dakika içerisinde 360 istekten fazla yollayan istemcilere karşı koruyacaktır.

Özel yapım (custom) kayıt tutma

1.8’den beri Apache’nin özel yapım kayıt tutmasını sadece mod_security’nin işin içine karıştığı isteklerde kullanmak mümkündür. Çünkü ModSecurity şimdi herhangi bir işlem yaptığında mod_security-relevant çevre değişkenini tanımlar. Özel yapım kayıt dosyasını kullanmak için, yapılandırmanıza aşağıdakini (veya benzerini) ekleyin:

CustomLog logs/modsec_custom_log \
"%h %l %u %t \"%r\" %>s %b %{mod_security-message}i" \
env=mod_security-relevant

Çeşitli Konular

Empedans (Impedance) uyumsuzluğu

Web uygulama güvenlik duvarları korudukları uygulama ve onların kullandıkları iş mantığını bilmeden, gelip geçen verilerden anlam çıkarmakta zorlanır. Getirdikleri koruma dışarıdan sağladıkları bağımsız bir güvenlik katmanı ile gelir. Veri denetlemesi iki kere yapıldığından uygulamaya dokunulmadan güvenlik sağlanmış olur. Ama bazı durumlarda her şeyin iki kere yapılması beraberinde problemler getirir. Problemler, iletişim protokollerinin tam olarak anlatılamadığı veya, aracın veya uygulamanın spesifikasyonlara uyumsuzluk içerdiği durumlarda oluşabilir.

En kafa karıştıranı cookie spesifikasyonudur. (Aslında dördü de: http://wp.netscape.com/newsref/std/cookie_spec.html, http://www.ietf.org/rfc/rfc2109.txt, http://www.modsecurity.org/documentation/<?xml version=%221.0%22?> <ns:clipboard xmlns:ns=%22http://www.xmlmind.com/xmleditor/namespace/clipboard%22 ><ulink url=%22???%22 >http://www.ietf.org/rfc/rfc2964.txt</ulink ></ns:clipboard >, http://www.ietf.org/rfc/rfc2965.txt.) Gerçek hayattaki bir çok durumda spesifikasyon ile uygun olmayan ve programcıyı neyi uygun görürlerse onu gerçekleyecekleri durumla karşılaşırsınız. Büyük bölüm için bu bir problem değildir çünkü bir çok cookie doğru oluşturulmuştur. Aynı zamanda birçok uygulama kendi oluşturduğu cookieyi ayrıştırdığı için uyumsuzluk problemi çok yaygın olarak göze çarpmaz. Bir web uygulaması güvenlik duvarı veya atlatmaya çalışan bir saldırgan gözüyle baktığınızda bir problemin olduğunu görürsünüz. 1.8.x dalında ve 1.8.6’ya kadar, ModSecurity (1.8.7’e değişiklikler yapılmıştır) bir v1 ayrıştırıcısı kullanmıştır. Ama v0 ve v1 arasındaki farklar, v1’in sadece bir v0 ayrıştırıcısının ise birden fazla cookie göreceği şekilde saldırlarda kullanılabilir. Aşağıdakini düşünün:

Cookie: innocent="; nasty=payload; third="

Bir v0 ayrıştırıcısı çift tırnaktan anlamaz. Tipik olarak noktalı virgülleri arar ve başlığı (header) buna göre böler. Böyle bir ayrıştırıcı cookieleri innocent, nasty, ve third şeklinde görür. Ama diğer taraftan bir v1 ayrıştırıcısı cookieleri sadece olarak innocent görür.

Empedans uyumsuzluğu web uygulama güvenlik duvarı kullanıcılarını ve geliştiricileri nasıl etkiler? İşimizi daha zor hale sokar ama önemli değil – ne de olsa oyunun bir parçası. Geliştiriciler daha akıllı ve iyi ayrıştırıcı (parser) fonksiyonları bulmaya çalışmalıdırlar. Mesela, ModSecurity 1.8.7’de iki cookie ayrıştırıcısı vardır ve kullanıcı hangisini kullanacağını seçebilirler. (Varsayılı olarak şimdi bir v0 ayrıştırıcısı kullanılmaktadır) Ama bu gelişmeler, otomatikleştirilemedikleri için, güvenlik duvarını kullanmayı daha zor hale getirir – kullanıcılar için düşünülmesi ve yapılandırılması gereken bir şey daha.

Diğer taraftan, cookie ayrıştırıcıları hakkında düşünmek istemezlerse kullanıcılar daha iyi tanımlanmış HTTP parçalarını kullanabilirler. Mesela başlıklar. Bireysel bir cookieyi hedef alan COOKIE_innocent kullanmak dışında HTTP_Cookie kullanarak bütün cookie başlığını hedef alabilirler. ARGS gibi diğer değişkenler, saldırganlar ne kadar saklamaya çalışırlarsa çalışşınlar, bütün değişkenleri inceleyeceklerdir.

Test etme

ModSecurity ile beraber küçük bir HTTP test etme aracı da geliştirilmiştir. Sunucuya özel yapım HTTP isteklerini göndermek ve sonra saldırının anlaşılıp anlaşılmadığını kontrol etmek içim kolay ve basit bir yol sağlar.

Aracın hiç bir parametre ile çağırılmaması kullanılma biçimini çıktı olarak basacaktır:

$ ./run-test.pl
Usage: ./run-test.pl host[:port] testfile1, testfile2, ...

İlk parametre, port numarası opsiyonel olacak şekilde, sunucunun ismidir. Diğer bütün parametreler özel yapım HTTP isteklerinin bulunduğu dosyalardır.

İşinizi biraz daha kolaylaştırmak için, araç bazı istek başlıklarını otomatik olarak üretecektir:

·         Host: hostname

·         User-Agent: mod_security regression testing utility

·         Connection: Close

Eğer gerekiyorsa bu başlıkları istekte de bulundurabilirsiniz. Ordalarda, araç bu değerleri eklemeyecektir.

İşte bir HTTP isteğinin nasıl gözüktüğü:

# 01 Simple keyword filter
#
# mod_security is configured not to allow
# the "/cgi-bin/keyword" pattern
#
GET /cgi-bin/keyword HTTP/1.0

Diğer ek başlıklar olmadan, bu istek sadece bir satırdan oluşur. İstediğiniz kadar karmaşık istekler üretebilirsiniz. İşte POST metodunun kullanılışına dair bir örnek:

# 10 Keyword in POST
#
POST /cgi-bin/printenv HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 5
 
p=333

Dosyanın başında bulunan ve # ile başlayan satırlar yorum olarak işlenirler. İlk satır özeldir ve testin ismini içermelidir.

Araç sonuç olarak 200 durum kodunu bekler ve bu şekildeki cevapları başarılı olarak algılar. Eğer başka cevaplara ihtiyacınız varsa, bunu ilk satırda (herhangi bir yerinde) göstermeniz gerekir. Şunun gibi:

# 14 Redirect action (requires 302)
GET /cgi-bin/test.cgi?p=xxx HTTP/1.0

Parantezler ve “requires” anahtar kelimesi gerekli değildirler ama daha iyi okunabilmeleri için önerilirler.

Yaygın Güvenlik Problemlerini Çözmek

Size ModSecurity’nin yeteneklerinin bir örneği olarak bazı yaygın güvenlik problemlerini nasıl yakaladığını ve engellediğini göstereceğiz. Burada problemler hakkında detaylara girmeyeceğiz ama çok iyi bir açıklama Open Web Application Security Project kılavuzunda bulunabilir, http://www.owasp.org/documentation/guide/guide_downloads.html.

Dizin gezinimi (Directory Traversal)

Eğer betiğiniz dosya sistemi ile uğraşıyorsa o zaman bazı yardımcı karakterlere ve yapılara dikkat etmeniz gerekir. Mesela, bir dizindeki ../ karakter kombinasyonu dizin seviyesinde bir seviye yukarı çıkmak isteği anlamına gelir.

Normalde bu karakter kombinasyonunun isteklerde bulunmasına gerek yoktur ve aşağıdaki filtreyi kullanarak yasaklayabilirsiniz:

SecFilter "\.\./"

Siteler arası betik çalıştırma (Cross site scripting) saldırıları

Siteler arası betik çalıştırma (XSS) saldırıları, saldırgan Web sayfalarına HTML ve/veya JavaScript kodu enjekte eder ve sonra bu kod daha sonra diğer kullanıcılar tarafından çalıştırılır. Bu genellikle beklemediğiniz yerlere HTML eklemekle olur. Başarılı bir XSS saldırısı saldırganın oturumunuzun cookiesini elde etmesi ile ve uygulamaya tam yetki ike erişmesiyle sonuçlanabilir.

Bu saldırı için düzgün savunma parametre filtrelemesidir (yani zararlı HTML/Javascript’ların silinmesi) ama genellikle hali hazırda bulunan uygulamaları değiştirmeden korumanız gerekir. Bu aşağıdaki filtrelerden herhangi birisi ile yapılabilir:

SecFilter "<script"
SecFilter "<.+>"

İlk filtre, <script> etiketi (tag) ile yapılan JavaScript enjeksiyonuna karşı koruma sağlar. İkinci ise daha geneldir ve parametreler içerisindeki bütün HTML kodunu reddeder.

Bu tür bir filtreyi uygularken çok dikkat etmeniz gerekir çünkü bir çok uygulama parametrelerde HTML ister (mesela, CMS uygulamaları, forumlar, v.b.). Bunu seçmeli filtreleme ile başarabilirsiniz. Örneğin, ikinci filtreyi genel bir site-boyu kuralı olarak alabilir ama daha sonra belli uygulamalar için aşağıdaki kodla durumu gevşetebilirsiniz:

<Location /cms/article-update.php>
    SecFilterInheritance Off
    # other filters here ...
    SecFilterSelective "ARGS|!ARG_body" "<.+>"
</Location>

Bu kod parçası sadece isimli parametre gövdesindeki HTML’I kabul edecektir. Gerçekte bu listeye bir kaç daha fazla isimli parametre eklemek isteyebilirsiniz.

SQL/veritabanı saldırıları

Şimdilerde bir çok web uygulaması veri manipulasyonu için çoğu zaman veritabanlarını kullanılırlar. Veritabanı erişimi büyük bir özenle güvenli hale getirilmezse, bir saldırgan gelişigüzel SQL komutlarını veritabanına enjekte edebilir. Bu da saldırganın hassas verileri okuması, değiştirmesi veya silmesi ile sonuçlanabilir.

Aşağıdaki gibi filtreler:

SecFilter "delete[[:space:]]+from"
SecFilter "insert[[:space:]]+into"
SecFilter "select.+from"

sizi bir çok SQL ile ilgili saldırıdan koruyabilir. Bunlar sadece örnektirler ve gerçekte kullandığınız veritabanı motoruna göre dikkatlice filtreler hazırlamanız gereklidir.

İşletim sistemi komut yürütme (command injection)

Web uygulamaları bazen işlemler gerçekleştirmek için işletim sistemi komutları çalıştıracak şekilde yazılırlar. Kararlı bir saldırgan bu kapsamda bir açıklık bulursa, sistemde gelişigüzei komutlar çalıştırabilir.

Aşağıdaki gibi bir filtre:

SecFilterSelective ARGS "bin/"

Unix gibi işletim sistemlerinde değişik dizinlerde bulunan ikililerin (binaries) çalıştırılmasını engeller.

Arabellek taşması saldırıları

Arabellek taşırması bir programın yürütme yığıtını taşırmak ve çalıştırma amacıyla assembly komutlarını ekleme tekniğidir. Bazı durumlarda aşağıdakine benzer bir satır ile bu tür saldırıları engellemek mümkündür:

SecFilterByteRange 32 126

Çünkü böylece sadece bazı bayt aralığında olan istekler kabul edilecektir. Bu tür bir korumayı kullanıp kullanmayacağınız nasıl bir uygulamanız olduğuna ve hangi karakter kodlamalarının kabul edildiğine göre değişir.

Birden fazla aralığı desteklemek isterseniz, düzenli ifadeleri (regular expression) kullanabilirsiniz. Bunun gibi bir şey kullanabilirsiniz:

SecFilterSelective THE_REQUEST "!^[\x0a\x0d\x20-\x7f]+$"

PHP

PHP’ye has özellikler

PHP uygulamalarını korumak amaçlı kod yazarken PHP’ye has özelliklerin akılda bulundurulması gerekir. Çoğu zaman kendi kendinize saldırırken çalışan bir kuralın başka bir saldırı çeşidini kaçırması kolaydır. Aşağıda bildiğim bazı durumların listesi vardır:

·         register_globals On olarak kullanıldığında, istek parametreleri global değişkenler olurlar. (PHP 4.x’te GLOBALS dizgisini bile değiştirmek mümkündür)

·         Cookieler istek parametreleri şeklinde işleme tabi tutulurlar.

·         Parametrelerin başındaki boşluklar görmezden gelinir.

·         (Parametre isimlerindeki) geri kalan boşluklar alt çizgi haline dönüştürülür.

·         Çevre değişkenlerinden ve isteklerden alınan parametrelerin sırası EGPCS’dir ((environment, get, post, cookies, kurulu -builtin- değişkenler). Bu, bir POST parametresinin istek satırındaki parametreleri değiştireceği anlamına gelir.

·         magic_quotes_gpc On olarak kullanıldığında, PHP ters bölme işaretini kullanarak şu karakterleri kaçırır (escape): tek tırnak, çift tırnak, ters bölme ve NULL

·         Eğer magic_quotes_sybase On olarak kullanılıyorsa, sadece tek tırnak diğer bir tek tırnak ile kaçırılır (escape). Bu durumda magic_quotes_gpc değeri bir anlam ifade etmez.

register_global problemlerini engelleme

Bu günlerde, PHP’nin register_globals özelliğinin kullanılmasının güvenlik açıkları oluşturduğu kabul edilir, ama her zaman böyle değildir (bu özelliğin ne olduğunu bilmiyorsanız, büyük ihtimalle kullanmıyorsunuzdur, ama okumaya devam ederseniz bilginiz artmış olur). Aslında, register_globals özelliği 4.2.0 sürümüne kadar varsayılı olarak açıktı. Sonuç olarak, varolan bir çok uygulama bu özelliğe bağımlıdır (daha fazla detay için http://www.php.net/register_globals).

Eğer bir seçme şansınız varsa, bu özelliği kullanmayacak şekilde kodu değiştirmek en iyisidir. Ama o veya bu şekilde bunu yapamazsanız, bir uygulamayı bilinen bir açıklıktan ModSecurity kullanarak koruyabilirsiniz. Problemli kod parçası genellikle şu şekilde gözükür:

<?php
// this is the beginning of the page
if ($authorised) {
    // do something protected
}
// the rest of the page here
?>

Ve saldırgan bu durumu URL’ye ek bir parametre ekleyerek avantaj elde eder. Mesela, http://www.modsecurity.org/examples/test.php?authorised=1

Problemdeki parametreyi doğrudan belirten istekleri reddetmek uygulamayı bütün saldırganlardan korumaya yeterli olacaktır:

Yukarıdaki filtre, “authorised” değişkeninin boş olmadığı bütün istekleri reddeder. Aynı zaman filtrelemeyi web sunucusunun sadece ilgili parçalarına uygulamak için <Location> başlıklarını kullandığımızı görebilirsiniz.

ModSecurity tarafından sağlanan korumanın bir bedeli vardır, ama genellikle çok düşüktür. Web sunucunuz çok az yavaş ve biraz daha fazla hafıza tüketir hale gelir.

Tecrübelerime göre, hız farkı önemsenmez haldedir. Bir çok düzenli ifadeler (regular expressions) sadece bir kaç micro saniyede biter. Ve ModSecurity’i sadece dinamik isteklerde etkin hale getirirseniz fark daha da az olacaktır. Gerçek hayat web sitelerinde bir dinamik sayfaya erişim diğer bir çok statik sayfaya erişimi de beraberinde getirir (CSS, JavaScript, images). Performans etkisi yapılandırmanın karmaşıklığına bağlıdır. Apache 2 sürümündeki modülün performans ölçümünü kullanıp ModSecurity’nin her istekte tam olarak ne kadar zaman harcadığını görebilirsiniz. Testlerimde genellikle bir kaç yüz kural için 2-4 milisaniye idi (2 GHz işlemci üzerinde).

Not

Eğer hata ayıklama kayıt özelliğini açmışsanız ModSecurity’den alacağınız performans değerleri gerçekçi olmayacaktır. Hata ayıklama kayıt işlemi genellikle çok yoğun (özellikle yüksek seviyelerde) ve aynı zamanda yavaştır. ModSecurity’nin hızını en iyi değerlendirme metodu özel yapım bir Apache kayıdı oluşturmak ve önceden anlatıldığı gibi performansı kaydetmektir.

Hafıza kullanımı

Bir isteği analiz etmek için, ModSecurity istek verisini hafızada tutar. Bir çok durumda istekler küçük olduğundan bu durum bir sorun yaratmaz. Ama, web sitesinin, dosyaların karşıdan yüklendiği bölümlerinde bir problem oluşturabilir. Bu problemi önlemek için web sitesinin o bölümlerinde istek gövde (body) tamponlamasını kapatmanız gerekir (Bu sadece Apache 1.x sürümünde bir problem yaratır. Apache 2.x bir istek saklamak için çok büyük olduğunda disk üzerinde geçici bir dosya kullanacaktır). Her durumda Apache yapılandırmasında bazı kısıtlandırmaları değerlendirmeli ve yapılandırmalısınız (İlgili direktifler LimitRequestBody, LimitRequestsFields, LimitRequestFieldsize and LimitRequestLine için http://httpd.apache.org/docs/mod/core.html#limitrequestbody).

İzlenecek diğer işlemler

Hata ayıklama özelliği gerçekten yardımcı olabilir ama her istek için büyük ölçülerde veriyi dosyaya yazar. Bu nedenle meşgul sunucular için bir dar boğaz yaratır. Üretim sunucularında hata ayıklama özelliğini açık tutmak için hiçbir neden yoktur.

Denetleme kayıt özelliği de aynı şekildedir ve dahası açık tutulduğunda iki dar boğaz yaratır. Öncelikle, büyük ölçülerdeki veri diske yazılır ve ikincisi dosyaya erişim senkronizasyonlu olmalıdır. Eğer yine de denetleme kaydını kullanmak istiyorsanız, senkronizasyon performans kaybını minimize etmek için bir çok denetleme kayıt dosyası (sunucuda çalışan her uygulama için) oluşturmaya çalışın (bu öneri Apache 2.x’deki performans kaybını ortadan kaldırmaz çünkü senkronizasyon merkezi bir mutex tarafından sağlanmaktadır).

Önemli notlar

Lütfen aşağıdaki notları okuyun:

·         Yapılandırma dosyasına eklediğiniz her filtrenin etkisini dikkatlice düşünmelisiniz. Özellikle erişimi, çok geniş kurallar kullanarak, kapatmak istemezsiniz. Geniş kurallar çoğunlukla yanlış artılar (false positives) yaratırlar.

·         ModSecurity .htaccess dosyalarında (bunu yapabilmek için AllowOverride Options gereklidir) kullanılabilse de, güvenmediğiniz kişiler tarafından kullanılabilecek şekilde açılmamalıdır. Eğer bu konuda paranoyaksanız, bu özelliği ModSecurity’i -DDISABLE_HTACCESS_CONFIG parametresi ile derleyebilirsiniz (apxs aracına bir parametre olarak).

mod_security’nin koştuğu Apache kancasını (hook) değiştirme

Varsayılı olarak mod_security Apache istek ön-işlemesinin mümkün olan en son noktasında, ama isteği çalışamaya başlayacağı ilk noktada çalışmaya (mesela mod_php tarafından çalıştırılmadan) çalışacaktır. Böyle bir yaklaşımı uygun gördüm çünkü mod_security’nin en önemli fonksiyonu uygulamayı korumaktır. Diğer taraftan böyle yaparak, hakkında yapacağımız şeyler olduğu halde, Apache’nin bazı bölümlerini korumasız bırakırız. Denemek isteyenler için, 1.9dev3 ile beraber mod_security, mümkün olabilecek en erken noktada çalışacak şekilde derlenebilir. -DENABLE_EARLY_HOOK ile derlemeniz yeterli. Bunun deneysel bir özellik olduğu aklınızda bulunsun. Keşfedeceğiniz bazı farklılıklar:

·         Apache işlemeden geçersiz istekleri yakalamak artık mümkün olmalıdır

·         Diğer türlü, Apache tarafından işlenecek istekleri değerlendirmek mümkün olacaktır (mesela TRACE)

·         Sadece sunucu boyu kurallar koşacaktır. Çünkü bu noktada Apache isteği yola eşleştirmemiştir.

ModSecurity’nin ilerki sürümleri büyük ihtimalle kural işlemeyi iki faza ayıracaktır. Birisi mümkün olabilecek en erken zamanda ve diğeri mümkün olan en geç zamanda.

Örnekler

Parametre kontrolü

Düzenli ifadeler (regular expressions) çok güçlü olabilirler. Aşağıdaki ile bir tam sayının 0 ile 99999 aralığında olup olmadığını kontrol edebilirsiniz:

SecFilterSelective ARG_parameter "!^[0-9]{1,5}$"

Karşıdan dosya yükleme

Uygulamanın bütününde karşıdan dosya yüklemeyi yasakla ancak bir alt dizin için izin ver:

# Reject requests with header "Content-Type" set
# to "multipart/form-data"
SecFilterSelective HTTP_CONTENT_TYPE multipart/form-data
 
# Only for the script that performs upload
<Location /upload.php>
    # Do not inherit filters from the parent folder
    SecFilterInheritance Off
</Location>

FormMail’i güvenli hale getirme

FormMail’in önceki sürümleri herhangi bir alıcıya e-posta göndermek için kullanılabilirdi (Düzgün olarak güvenli hale getirilebilen yeni bir sürümü olduğunu duydum).

# Only for the FormMail script
<Location /cgi-bin/FormMail>
    # Reject request where the value of parameter "recipient"
    # does not end with "@webkreator.com"
    SecFilterSelective ARG_recipient "![a-zA-Z0-9][email protected]\.com$">
</Location>

Ek A: Önerilen Yapılandırma

Aşağıda önerilen en kısa mod_security yapılandırması verilmiştir. Sadece, size ani bir baş ağrısı vermemesi için dizayn edilmiş bir başlangıç noktasıdır. Yapabildiğiniz her noktada yapılandırmayı sıkılaştırmalısınız.

# ModSecurity’i aç
SecFilterEngine On
 
# 403 durumlu istekleri reddet
SecFilterDefaultAction "deny,log,status:403"
 
# bazı akıllıca işlemler
SecFilterScanPOST On
SecFilterCheckURLEncoding On
SecFilterCheckUnicodeEncoding Off
 
# hemen hemen her bayt aralığını kabul et
SecFilterForceByteRange 1 255
 
# sunucu maskelemesi isteğe bağlı
# SecServerSignature "Microsoft-IIS/5.0"
 
SecUploadDir /tmp
SecUploadKeepFiles Off
 
# sadece ilginç şeyleri kaydet
SecAuditEngine RelevantOnly
SecAuditLog logs/audit_log
 
# normalde hata ayıklama kaydına ihtiyaç duymazsınız
SecFilterDebugLevel 0
SecFilterDebugLog logs/modsec_debug_log
 
# sadece nasıl işleneceğini bildiğimiz istek kodlamaları kabul et
# sadece GET isteklerini dışarıda tutuyoruz çünkü
# bazı (otomatik) istemciler Content-Type olarak "text/html" gönderir
SecFilterSelective REQUEST_METHOD "!^(GET|HEAD)$" chain
SecFilterSelective HTTP_Content-Type \
"!(^application/x-www-form-urlencoded$|^multipart/form-data;)"
 
# gövdeleri (body) olan GET veya HEAD isteklerini kabul etme
SecFilterSelective REQUEST_METHOD "^(GET|HEAD)$" chain
SecFilterSelective HTTP_Content-Length "!^$"
 
# Content-Length alanının bütün POST isteklerinde
# bulunmasını denetle
SecFilterSelective REQUEST_METHOD "^POST$" chain
SecFilterSelective HTTP_Content-Length "^$"
 
# nasıl işleneceğini bilmediğimiz transfer kodlamalarını kabul etme
SecFilterSelective HTTP_Transfer-Encoding "!^$"