HTML PHP (ve ZF) ile kullanıcı tarafından sağlanan verileri kaçmak için en iyi uygulama

4 Cevap php

Note: I'm using Zend Framework, but I think most of this applies to PHP coding in general.

Ben belki bir çiftleşmiş motoru yardımı ile, görünümleri komut dosyaları yazmak için bir strateji seçmek için çalışıyorum. Motivasyonları: clarity ve security. Ben sadece yazı ile mutlu değilim. Phtml komut. Bu sözdizimi en sık ihtiyaç duyulan bir şey yapmak için çok ayrıntılı - bir değişken çıkarılırken:

<?php echo $this->escape($this->myVariable); ?>

Kod uzun olmasının yanı sıra, şablon yazar IMHO hatırlamak zorunda (ve rahatsız) bir kaçış çağrıma o / o çıkış için bir değişken istediği her zaman yazılı olmamalıdır. Aramayı unutmak neredeyse kesinlikle bir XSS güvenlik açığına neden olur.

Ben bu sorunun iki olası çözümler var:

Solution 1: A template engine with automatic escaping

Ben en az Smarty değişkenleri çıktısı otomatik olarak html varlıkları kaçmak için bir seçenek olduğunu düşünüyorum. Orada points against Smarty, ama belki bunların en azından bazı yaklaşan 3,0 değinilen - Ben henüz bakmadım.

Gibi XML tabanlı motor şablonu PHPTAL varsayılan olarak herhangi bir veri kaçış olacaktır. Onlar olsa da, yeni başlayanlar için oldukça tuhaf görünebilir. Belki hala değer mi çalışıyorsun?

Solution 2: Escape the data in the Model

Tabii ki, diğer seçenek Modeli zaten gerekli veri kaçmayı olacaktır (hatta denetleyicisi?). Model zaten her alanın içerik türünü (özellikle düz metin veya HTML metin) bilmeli, bu yüzden bu tür mantıksal orada verileri kaçmak olacaktır. Görünümü güvenli HTML olarak tüm verileri düşünebiliriz. Bu örneğin sağlayacak. görünümü senaryoyu dokunmadan HTML, düz metin bir alanın veri türünü değiştirme - yalnızca Modeli değiştirerek.

Ama sonra tekrar, iyi MVC uygulama gibi gelmiyor. Buna ek olarak, hem de bu yaklaşımla sorunlar vardır:

  • bazen görünüm yalnızca ilk n karakterini yazdırmak istiyor ve biz foo & bar verileri kesiliyor bitirmek istemiyorum foo &am (ilk olarak kaçan gibi {[(2) ]})
  • belki görünümü sorgu dizesi içinde varName = $ varName ile bir URL oluşturmak istiyor - Tekrar, Model zaten kaçış kötü olurdu.

(Bu sorunlar. Verilerin iki sürümlerini sağlıyorsanız, veya şablonda atlanmaması tarafından ele bana kötü görünüyor olabilir.)

Fikirler? Ben bir şey eksik? Eğer "en iyi uygulama" Ne düşünüyorsunuz?

PS. Bu mesaj < veya > veya herhangi diğer karakterleri içerebilir herhangi bir kullanıcı tarafından sağlanan düz metin veri için genel bir çözüm bulmak. Yani, veritabanına kaydetmeden önce verileri filtreleme çözüm değildir.

Update:

Kadar tüm yorumlar için teşekkürler. Ben biraz daha araştırma yaptım ve sonraki Twig ve muhtemelen Open Power Template değerlendirecektir. Her ikisi de ilginç görünüyor: budak çok basit görünüyor, ama proje genç. XML tarafta, OPT sözdizimi PHPTAL en biraz daha güzel görünüyor. Dal ve OPT her ikisi de oldukça iyi belgelenmiştir.

4 Cevap

  1. Filter kısa sürede. Eğer metin işleme fonksiyonları tahmin çalışması için tüm metin girişi uygun UTF-8 olduğundan emin olmanız gerekir.

    Ama "tehlikeli" karakterleri veya fragmanları filtrelemeyi denemek yok! Bu işe yaramazsa. Sadece düzeltmek veya girişi hatalı veri reddediyoruz. < yanlış veya ' karakter şey yok.

  2. Escape mümkün olduğunca geç. SQL SQL sorgu işlevi kaçan Ekle (ya da daha iyisi - hazırlanmış ifadeler kullanmak). HTML şablonları HTML-kaçış. E-posta nesil işlevler, kabuk-kaçış CLI komutları çalıştırırken, vb kote-Baskı-kaçış

    Uzun kaçtı veri yaşıyor, büyük bir şans size çıkmamış verileri ile karıştırmak ya da işleme sırasında kaçan kırarım çünkü kaçtı verileri, tüm uygulama yayılmış izin vermeyin.

Bu tam bir çözüm değil, ama durum bu tür bir son derece yararlı şey macar-stili gösterimde olduğunu. Her zaman kullanılır Macar notasyonu bana, sadece can sıkıcı olduğunu, ancak bu değişken adı meta bu tür çok değerli olduğu yerde türüdür. İyi bir uygulama ondan beklemek ne diyor bir önek ... yani ile değişkenleri isim olduğunu Vb $ rawUserInput, $ escapedUserInput,

Bu tamamen sorunu çözmek değil, ama iyi bir kodlama uygulamadır. Sonra diyor ki bir kod parçası gördüğünüzde

'SELECT * from table where username = ' + $rawUserName

Eğer ham önek bunu kaçmış değil demektir biliyorum çünkü, bir enjeksiyon açığı var ki hemen ortada.

Ama sonra tekrar, iyi MVC uygulama gibi gelmiyor.

Tamamen Model tür sunum kaygılar ve kolay bunları senkronize çıkmak için yapacak bir HTML ve her değişkenin bir ham versiyonu hem de saklamak için yanlış yer, katılıyorum. Çözüm 2 unutun.

Bu alternatif çiftleşmiş motorları, veya PHP ile yapışmasını ve htmlspecialchars'dan her zaman çağrı yükü taşımaları öğrenme ile size bırakır. Ben alternatif çiftleşmiş girişlerinin fikrine açığım, ama ben şimdiye kadar denedim olanlar gerçekten mutlu olmamıştır.

(Birçok ıskarta PHP sözdizimi ve size zaten bildiğiniz ve daha karmaşık sunum mantığı imkansız kılan bir noddy-dil ile sıkışmış dil avantajı kaybetmek anlamına gelir, bu yüzden PHP kendiniz yapıyor sonuna kadar kendi sınırlı anlatım dilleri, uygulamak kesinlikle bir kazan değil, HTML, dolu dizeleri ile.)

HTML-kaçan acısını çıkarmak için kısa bir adla bir küresel işlevi tanımlayın: Yani şu an için bir Solution 0a kazık eklemek için öneririm:

<?php
    function h($s) {
        echo(htmlspecialchars($s, ENT_QUOTES));
    }
?>
...

My lovely variable is <?php h($this->myVariable); ?>.

Ben PHP dediğiniz gibi farkla en yaygın kullanım durumunda olan, bunun için bir kısayol tanımlamak değil neden hiçbir fikrim yok. Şimdi dedikleri gibi, XML-PI-stil etiketleri için kısa etiketleri, neden orada doğru olanı yapmak için başka bir ad ile bir değil, terk ettik <?phph?

Bunu yapmanın bir düzine yolu vardır. İşte bir kaç olduğunu:

  • You could write your custom View class, as described in the Zend Framework Manual, and escape any variables when they are assigned to or requested from the View.
  • In case of Datasets, you could wrap them into a custom ArrayIterator that does output escaping when fetching items from it, along with any other stuff you want to automate on output.
  • Or you could use the View Script approach.
  • Or, if you dont want to have your template authors write any PHP or template syntax whatsoever, you could ask them them to write just the structured HTML and then insert the values through the DomDocument extension.

Ayrıntılı olan bir şablonda PHP gelince de .. bu kısa gösterimde sunmuyor olabilir, ama sonra tekrar, does bir gösterim sağlamak ve hiçbir yükü ile birlikte gelir. Bile olmayan PHP şablon yazarlar için temelde PHP kutunun dışında yapabileceği bir alt kümesini yeniden keşfediyor bir (genellikle garip) bir şablon dili daha PHP birkaç yöntem çağrıları öğrenmek için kolay olmalıdır.

Eğer ile bitebileceğini böylece de, <?php kurtulmak için şablonlar Alternative PHP Syntax ve NowDoc or HereDoc kullanın ve echo çağrıları olabilir gibi bir şey

<?php
// get some partial block done first
foreach($this->books as $book):
$loopdata = << LOOPDATA
<li> {$book->title} -  {$book->author} - {$book->publisher}</li>
LOOPDATA;
endforeach;

// render entire template
echo << HTML
<h1>{$this->title}</h1>
<ul>{$loopdata}</ul>
HTML;

Şahsen, ben bu çok çekici bulmuyorum, ama gördüğünüz gibi, PHP ile şablonları yazmak için birçok yol vardır. Sadece birini seçmek.