<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>&#60;?blog &#187; walidacja</title>
	<atom:link href="http://blog.visionsoftware.pl/tag/walidacja/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.visionsoftware.pl</link>
	<description>...nie tylko o programowaniu</description>
	<lastBuildDate>Sun, 23 Mar 2014 19:23:43 +0000</lastBuildDate>
	<language>pl-PL</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	
	<item>
		<title>Rozpoznawanie typów plików w PHP</title>
		<link>http://blog.visionsoftware.pl/programowanie-php/rozpoznawanie-typow-plikow-w-php.html</link>
		<comments>http://blog.visionsoftware.pl/programowanie-php/rozpoznawanie-typow-plikow-w-php.html#comments</comments>
		<pubDate>Fri, 30 Sep 2011 21:25:28 +0000</pubDate>
		<dc:creator><![CDATA[Marcin Fliszta]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[fileinfo]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[plik]]></category>
		<category><![CDATA[rozszerzenie]]></category>
		<category><![CDATA[walidacja]]></category>

		<guid isPermaLink="false">http://blog.visionsoftware.pl/?p=368</guid>
		<description><![CDATA[Gdy umożliwiamy na naszej stronie internetowej lub w systemie wgrywanie plików, powinniśmy sprawdzać ich typ. Dzięki temu dopuścimy tylko wybrane przez nas rodzaje, np. pliki graficzne. Możemy sobie jednak nie zdawać sprawy, że podstawowe, najczęściej stosowane możliwości sprawdzania typu są bardzo zawodne i umożliwiają wgranie na serwer niepożądanych danych. Sprawdzanie rozszerzenia pliku Najprostszym możliwym testem dla pliku jest sprawdzenie jego rozszerzenia. Oczywiście w ten sposób jest on wykonywany niezwykle rzadko. Wystarczy, że rozdzielimy nazwę względem [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Gdy umożliwiamy na naszej stronie internetowej lub w systemie wgrywanie plików, powinniśmy sprawdzać ich typ. Dzięki temu dopuścimy tylko wybrane przez nas rodzaje, np. pliki graficzne. Możemy sobie jednak nie zdawać sprawy, że podstawowe, najczęściej stosowane możliwości sprawdzania typu są bardzo zawodne i umożliwiają wgranie na serwer niepożądanych danych.<span id="more-368"></span></p>
<h3>Sprawdzanie rozszerzenia pliku</h3>
<p>Najprostszym możliwym testem dla pliku jest sprawdzenie jego rozszerzenia. Oczywiście w ten sposób jest on wykonywany niezwykle rzadko. Wystarczy, że rozdzielimy nazwę względem kropki i sprawdzimy ostatnią z części. Jest to oczywiście sposób bardzo zawodny, gdyż ktoś może zmienić rozszerzenie przed wgraniem na serwer. Na przykład plik PHP może zostać ukryty pod nazwą image.jpg. Wykorzystując następnie luki w naszym systemie, istnieje możliwość wykonania takiego kodu.</p>
<h3>Sprawdzanie typu MIME w tablicy <code>$_FILES</code></h3>
<p>Znacznie częściej stosowanym sposobem na rozpoznawanie rodzaju pliku jest sprawdzenie typu MIME. Możemy to osiągnąć, analizując dane z formularza, konkretnie wartość <code>$_FILES['type']</code>.</p>
<p>Poniższy, bardzo uproszczony kod, wyświetla formularz HTML z jednym polem umożliwiającym wczytanie pliku. Po jego wysłaniu wyświetlone zostaną szczegółowe dane o pliku z tablicy <code>$_FILES</code>.</p>
<pre class="brush: php; title: ; notranslate">
&lt;html&gt;
    &lt;body&gt;
        &lt;form action=&quot;mime_test.php&quot; method=&quot;post&quot; enctype=&quot;multipart/form-data&quot;&gt;
        	&lt;label for=&quot;file&quot;&gt;Filename:&lt;/label&gt;
        	&lt;input type=&quot;file&quot; name=&quot;file&quot; id=&quot;file&quot; /&gt;
        	&lt;input type=&quot;submit&quot; name=&quot;submit&quot; value=&quot;Submit&quot; /&gt;
        &lt;/form&gt;
    &lt;/body&gt;
&lt;/html&gt; 

&lt;?php 
if($_POST){
    print_r($_FILES);    
}
?&gt;
</pre>
<p>Wczytanie przykładowego zdjęcia zwróci w polu type wartość image/jpeg. Co się jednak stanie, gdy przez formularz wczytamy plik PHP ze zmienioną nazwą na jpg? Wynik może być dla niektórych zaskakujący – powyższy kod wyświetli informację, że wgrany został plik graficzny. </p>
<p>Dlaczego tak się dzieje? Otóż dane na temat pliku przekazywane są przez przeglądarkę, a większość z nich (wszystkie?)  określa typ MIME po rozszerzeniu pliku. Tak więc wracamy do punktu wyjścia.</p>
<h3>Wykrywanie pliku graficznego</h3>
<p>Zawodność powyższych metod możemy naprawić jednym prostym rozwiązaniem. Wystarczy, że skorzystamy z funkcji  <code>getimagesize()</code> z biblioteki GD, która zwraca wymiary pliku graficznego. Przykładowe wywołanie wraz z efektem może wyglądać nastepująco:</p>
<pre class="brush: php; light: true; title: ; notranslate">
print_r(getimagesize('image.jpg'));

Array
(
    [0] =&gt; 979
    [1] =&gt; 734
    [2] =&gt; 2
    [3] =&gt; width=&quot;979&quot; height=&quot;734&quot;
    [bits] =&gt; 8
    [channels] =&gt; 3
    [mime] =&gt; image/jpeg
)
</pre>
<p>Otrzymujemy więc dane na temat wymiarów grafiki, palety kolorów, liczby kanałów oraz typu MIME. Jeśli spróbujemy naszego oszustwa ze zmianą rozszerzenia i użyjemy powyższej funkcji do sprawdzenia spreparowanego pliku PHP, funkcja zwróci wartość <code>false</code>. </p>
<pre class="brush: php; light: true; title: ; notranslate">
var_dump(getimagesize('phpcode.jpg'));
bool(false)
</pre>
<p>Dzięki temu możemy sprawdzić, czy wgrywany plik jest faktycznie obrazkiem. Co jednak zrobić, gdy chcemy testować inne typy?</p>
<h3>Sprawdzanie typu pliku po &#8222;magicznych bajtach&#8221;</h3>
<p>Każdy plik zaczyna się od charakterystycznych bajtów, które identyfikują jego typ. Dla kilku popularnych typów, wyglądają one następująco (w zapisie szesnastkowym):</p>
<pre class="brush: plain; light: true; title: ; notranslate">
GIF87a:  47 49 46 38 37 61 
GIF89a:  47 49 46 38 39 61 
JFIF, JPE, JPEG, JPG: FF D8 FF E0 xx xx 4A 46 49 46 00 
AVI: 52 49 46 46 xx xx xx xx 41 56 49 20 4C 49 53 54 
</pre>
<p>Wystarczy więc je wczytać i sprawdzić, aby określić rodzaj. Na poniższym przykładzie przedstawiono sprawdzenie, czy dany plik to gif.</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
$file = fopen('image.gif', 'r');
$bytes = bin2hex(fread($file, 6));

if($bytes == '474946383761' || $bytes == '474946383961'){
    print 'To plik gif';
}
else{
    print 'To NIE JEST gif';
}

fclose($file);
?&gt;
</pre>
<p>Działanie kodu jest niezwykle proste. Wczytujemy pierwsze 6 bajtów z pliku, po czym konwertujemy je na wartości hexadecymalne. Następnie porównujemy z odpowiednim schematem, który dla GIF może być  <code>47 49 46 38 37 61</code> lub <code>47 49 46 38 39 61</code>.</p>
<p>Długa lista „magicznych bajtów” dla najróżniejszych typów plików jest dostępna <a href="http://www.garykessler.net/library/file_sigs.html" title="" target="_blank">tutaj</a>.</p>
<p>Możemy na jej podstawie stworzyć własną funkcję sprawdzającą. Oczywiście to także nie zabezpieczy nas w stu procentach. Możliwe jest bowiem stworzenie pliku z oszukanym nagłówkiem. Ten sposób, mimo że dość karkołomny, jest jednak znacznie lepszy od poprzednich.</p>
<h3>Sprawdzanie typu przez Fileinfo</h3>
<p>Niedogodności poprzednio opisanego sposobu można zlikwidować, stosując wbudowane w PHP funkcje <code>Fileinfo</code>. Są one obecne od wersji 5.3.0 języka, dla wcześniejszych możemy skorzystać z PECL. Oczywiście podczas kompilacji PHP należy się upewnić, że dołączamy powyższą bibliotekę.</p>
<p>Poniższe wywołanie pokazuje efekt sprawdzenia typu pliku jpg oraz PHP ze zmienionym rozszerzeniem.</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php 
$file1 = 'image.jpg';
$file2 = 'phpcode.jpg';

$file_info = new finfo(FILEINFO_MIME);

print $file_info-&gt;file($file1, FILEINFO_MIME_TYPE); 
print $file_info-&gt;file($file2, FILEINFO_MIME_TYPE);
?&gt;
</pre>
<p>Wynik wywołania skryptu:</p>
<pre class="brush: plain; light: true; title: ; notranslate">
image/jpeg
text/x-php
</pre>
<p>Wywołanie metody <code>file</code> posiada kilka innych wariantów, w zależności od drugiego parametru. Możemy między innymi sprawdzić kodowanie pliku oraz klika innych rzeczy.</p>
<p><em>Artykuł został oparty o tekst z bloga http://cakephp-php.blogspot.com.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.visionsoftware.pl/programowanie-php/rozpoznawanie-typow-plikow-w-php.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Walidacja i satynizacja z filter_var()</title>
		<link>http://blog.visionsoftware.pl/programowanie-php/walidacja-i-satynizacja-z-filter_var.html</link>
		<comments>http://blog.visionsoftware.pl/programowanie-php/walidacja-i-satynizacja-z-filter_var.html#comments</comments>
		<pubDate>Sun, 12 Dec 2010 22:13:34 +0000</pubDate>
		<dc:creator><![CDATA[Marcin Fliszta]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[filter_var]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[regexp]]></category>
		<category><![CDATA[walidacja]]></category>

		<guid isPermaLink="false">http://blog.visionsoftware.pl/?p=43</guid>
		<description><![CDATA[Sprawdzanie poprawności danych to nieodzowny element każdej strony internetowej. Wszędzie tam, gdzie prosimy użytkownika o wprowadzenie danych, musimy być bardzo ostrożni. Należy określić, czy nie popełnił błędu podczas wpisywania, oraz dodatkowo zabezpieczyć się przed użyciem niepożądanych wyrażeń mogących prowadzić na przykład do SQL lub Java Script Injection.Takie dane jak email lub adres WWW najlepiej sprawdzać przy pomocy wyrażeń regularnych, czyli np. funkcji preg_match(), a dane &#8222;oczyszczać&#8221; przy pomocy strip_tags, int_val lub podobnych. Od PHP 5.2 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Sprawdzanie poprawności danych to nieodzowny element każdej strony internetowej. Wszędzie tam, gdzie prosimy użytkownika o wprowadzenie danych, musimy być bardzo ostrożni. Należy określić, czy nie popełnił błędu podczas wpisywania, oraz dodatkowo zabezpieczyć się przed użyciem niepożądanych wyrażeń mogących prowadzić na przykład do SQL lub Java Script Injection.<span id="more-43"></span>Takie dane jak email lub adres WWW najlepiej sprawdzać przy pomocy wyrażeń regularnych, czyli np. funkcji preg_match(), a dane &#8222;oczyszczać&#8221; przy pomocy strip_tags, int_val lub podobnych. Od PHP 5.2 mamy jednak do dyspozycji jeszcze jedno dobre narzędzie &#8211; funkcję filter_var().</p>
<p>Dzięki niej możemy sprawdzić poprawność różnych danych, oraz przefiltrować je w celu pominięcia określonych znaków. Wszystko w postaci jednego, krótkiego polecenia.</p>
<p>Przykładowo, aby sprawdzić poprawność adresu email. Wystarczy, że użyjemy następującego polecenia:</p>
<pre class="brush: php; title: ; notranslate">filter_var('mail@server.com', FILTER_VALIDATE_EMAIL);</pre>
<p>Funkcja filter_var zwróci testowaną zmienną jeśli jest ona poprawna, lub false w przypadku, gdy jest błędna.</p>
<p>Istnieje możliwość przeprowadzania wielu innych testów:<br />
FILTER_VALIDATE_BOOLEAN – zwraca true dla &#8222;1&#8243;, &#8222;true&#8221;, &#8222;on&#8221; lub &#8222;yes&#8221;, false dla pozostałych wartości. Po zastosowaniu flagi FILTER_NULL_ON_FAILURE zwraca false tylko dla for &#8222;0&#8243;, &#8222;false&#8221;, &#8222;off&#8221;, &#8222;no&#8221; i “”. Jeśli testowana zmienna nie jest boolean, zwraca NULL.<br />
FILTER_VALIDATE_FLOAT – sprawdza, czy parametr jest liczbą zmiennoprzecinkową<br />
FILTER_VALIDATE_INT – sprawdza, czy parametr jest liczbą całkowitą<br />
FILTER_VALIDATE_IP – sprawdza poprawność adresu IP. Można zastosować flagi zawężające test do protokołu IPv4, IPv6, adresów prywatnych lub zarezerwowanych<br />
FILTER_VALIDATE_REGEXP – do używania wyrażeń regularnych (Pearl)<br />
FILTER_VALIDATE_URL – sprawdzanie poprawności adresu URL</p>
<p>Przy użyciu funkcji filter_var() można także „oczyścić” dane z niepożądanych znaków. Poniższy kod usunie zezmiennej $var wszystko poza cyframi oraz znakiem +/-</p>
<pre class="brush: php; title: ; notranslate">$var_clean = filter_var($var, FILTER_SANITIZE_NUMBER_INT);</pre>
<p>Lista innych możliwości jest całkiem długa, przy pomocy innych parametrów możemy dodawać slashe do ciągów, usuwać niepożądane znaki z adresów e-mail, ciągów znaków, adresów URL itd. Istnieje możliwość używania flag, które dodatkowo rozszerzają możliwość filtrów.</p>
<p>Oprócz filter_var() istnieją także inne funkcje związane z filtrowaniem danych. Umożliwiają one bezpośrednie filtrowanie zmiennych $_GET, $_POST, $_COOKIE, $_SERVER, $_ENV oraz własnych tablic. Szczegóły można znaleźć w <a href="http://pl.php.net/manual/en/function.filter-input.php" target="_blank">dokumentacji</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.visionsoftware.pl/programowanie-php/walidacja-i-satynizacja-z-filter_var.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
