Skocz do zawartości

Witaj na forum webmasterów Webax.pl.

Wyświetl nową zawartość

Thelleo

Thelleo

Rejestracja: 17 lip 2012
Poza forum Ostatnio: 07 paź 2013 13:40
-----

Moje tematy

Malutki projekcik webdesignerski [Nieaktualne]

13 luty 2013 - 15:36

Mój znajomy poszukuje osoby, która dobrze zna się na HTMLu i CSSie do ostylowania jego małej strony. Tutaj szczegóły:

Cześć.

Mam domenę gimb.us, na której stworzyłem skracarkę linków. Problem w tym, że ze mnie webdesigner jest dóść kiepski.
Tutaj nasuwa się moja propozycja - potrzebuję kogoś, kto zrobi ładny design strony (nic wielkiego raczej, od taki tam przycisk, header, stopka i tyle :G, nie będzie jakiegoś większego contentu raczej), a w nagrodę wyląduje w stopce strony (która ma potencjał na bycie *popularną*, ze względu na swój adres :)).

Nie liczę na coś przepięknego i megazawalistego, w końcu bardzo mało oferuję wzamian. W stopce dowolny tekst jaki autor CSSa sobie zażyczy.

Dzięki bardzo za przeczytanie i miłego dnia.


Osoby chętne mogą pisać na adres me@marahin.pl.

Podstawy bezpieczeństwa w skryptach PHP. SQL Injection i XSS.

03 styczeń 2013 - 16:12

PHP jest prawdopodobnie najpopularniejszym językiem do tworzeniach dynamicznych stron i skryptów wśród początkujących. W internecie jest bardzo dużo kursów i poradników a sam język jest instalowany na praktycznie każdym hostingu (najczęściej w wersji 5.3 lub 5.2, chociaż ja preferuję najnowsze 5.4, które ma trochę feature-ów).

Z tego powodu PHP w oczach "większych developerów" jest widziany jako dość kiepski język, bo internet oblega masa dziurawych skryptów i systemów pisanych przez osoby początkujące. Osobiście nie potępiam tego, bo pamiętam jak sam uczyłem się PHP. W kursach albo autorzy nie wspominali o bezpieczeństwie, albo były to krótkie nic nie mówiące notki (no bo początkujący nie koniecznie wie czym jest SQL Injection lub XSS). Chciałbym w tym temacie zaprezentować sposoby ochrony swoich skryptów a przy okazji uświadomić "nowych" jak łatwo można złamać niektóre rzeczy i do jakich nieprzyjemności może to doprowadzić (no bo przecież dziura wykorzystana przez crackera w skrypcie za który ktoś zapłacił powiedzmy 1000 zł może być ogromnym ciosem dla reputacji developera).

A więc zaczynamy, na początku zacznę od czegoś co można najczęściej spotkać u początkujących, czyli całkowite zaufanie dla danych od użytkownika i przekazywanie ich bezpośrednio do zapytania.

SQL Injection

Atak SQL Injection polega na wrzuceniu do zapytania SQL wywoływanego przez skrypt PHP własnych danych i tym samym manipulowaniu jego wynikiem. Załóżmy, że mamy stronę gdzie użytkownicy mogą pisać na własnych blogach. Mamy 2 tabele - jedną na użytkowników, drugą na wpisy a wyświetlanie pojedynczego wpisu opiera się o coś w stylu show.php?id=666.

Przeciętny (i podatny) kod który takie coś robi:


$id = @$_GET['id'];
$query = mysql_query("SELECT title, content FROM articles WHERE id = {$id}");
$data = mysql_fetch_array($query);
echo '<h1>'.$data['title'].'</h1>';
echo '<p>'.$data['content'].'</p>';

Jak widzimy najpierw pobieramy z tablicy $_GET identyfikator newsa i wrzucamy go na koniec zapytania. Taka metoda zadziała i wyświetli artykuł poniżej, ale... no właśnie! Ale!
Każdy odwiedzający będzie mógł pod $id podstawić cokolwiek. Zaraz pokażę Ci co dzięki temu można z tej strony wydobyć, ale najpierw jedna żelazna zasada: nigdy nie ufaj danym od użytkownika. NIGDY!

A więc tak, aby wyświetlić news o ID 666 wchodzimy na adres: show.php?id=666. Wpis się pokaże, ale wiesz co się stanie jeżeli wpiszemy coś takiego?

show.php?id=666 UNION SELECT username, password FROM users WHERE username = 'admin' --

Wtedy finalne zapytanie będzie wyglądało tak:

SELECT title, content FROM articles WHERE id = 666 UNION SELECT username, password FROM users WHERE username = 'admin' -- 

UNION SELECT jest konstrukcją która pozwala nadpisać dane pobrane przez pierwszą cześć zapytania danymi z drugiej. Tak, dobrze przeczytałeś - nadpisać. Po takim zapytaniu zamiast tytułu i treści wpisu wyświetliły by się takie dane jak nazwa użytkownika oraz hasła (nawet wyciek hasha może mieć katastrofalne skutki). Brzmi strasznie? Teraz wyobraź sobie, że masz w takim serwisie bloga. Hasła są niehashowane (trzymane czystym tekstem w bazie danych) i ktoś za pomocą tej luki wykrada dane twoje oraz innych użytkowników. Byłbyś szczęśliwy jakby twoje hasło znalazło się w rękach crackera przez błąd programisty?

Pamiętaj, że prowadząc serwis, gdzie użytkownicy się mogą zarejestrować jesteś za ich dane odpowiedzialny. Nie możesz dopuścić do sytuacji żeby wyciekły one w jakikolwiek sposób bo możesz wtedy stracić zaufanie ludzi, którzy do tej pory odwiedzali twój serwis z uśmiechem.

No dobra, ale jak to naprawić?

W bardzo prosty sposób. Jeżeli masz czas i chcesz skorzystać z nowocześniejszego rozwiązania to polecam przenieś swoją obsługę bazy danych na PDO i prepared statements, ale jeżeli chcesz szybko coś naprawić i nie możesz sobie pozwolić na przepisywanie połowy kodu to oto prosta metoda jak całkowicie zabezpieczyć dane od użytkownika dodawane do zapytania.

$id = @$_GET['id'];
$id = mysql_real_escape_string($id); // ← zmienna $id zostaje przepuszczona przez funkcję mysql_escape_string, która całkowicie ją oczyszcza ze wszystkiego co mogłoby zagrozić naszej bazie danych.
$query = mysql_query("SELECT title, content FROM articles WHERE id = {$id}");
$data = mysql_fetch_array($query);
echo '<h1>'.$data['title'].'</h1>';
echo '<p>'.$data['content'].'</p>';


Poradnik nie został skończony, mam zamiar omówić w nim jeszcze XSSy i być może inne podatności, ale na razie nie mam specjalnie czasu ani chęci na ich opisywanie, jednak gdy tylko skończę to zostaną tutaj opublikowane aktualizacje.

Ze względu na przeznaczenie tego tutoriala pozwalam, a nawet zachęcam wklejać go na inne fora i strony, ale bardzo proszę - jeżeli to robisz to umieść informację o tym, że ja go napisałem i o ile regulamin (tamtego serwisu oczywiście) na to pozwala to umieść link do oryginalnego tematu.

[MyBB] Katalog Firm by Webax.pl

02 grudzień 2012 - 18:05

Jak zapewne niektórzy pamiętają Webax.pl poprzednio używał MyBB jako skryptu forum. Został wtedy napisany skrypt katalogu firm dzięki któremu dowolna osoba która otrzymała rangę "Hosting" mogła dodać wizytówkę swojej firmy.

Ponieważ aktualnie ten panel nie jest używany już przez Webaxa to postanowiliśmy udostępnić go całkowicie za darmo naszym użytkownikom. Jest on pisany tylko i wyłącznie pod MyBB, a także nie jest sam w sobie pluginem, ale bardziej niezależnym skryptem korzystającym z udostępnianych przez MyBB bilbiotek.

Jego kod nie jest specjalnie dobry, ponieważ podczas gdy Webax.pl poswstawał to ten skrypt był pisany w pośpiechu na zasadzie "żeby było", jednak mam nadzieję, że nie odstraszy to potencjalnych użytkowników.

Ze względu na to, że skrypt był dedykowany dla Webaxa jego instalacja jest znacznie trudniejsza od instalacji pluginu, ale mam nadzieję, że sobie poradzisz.
Chcę również zauważyć, że skrypt nie będzie dalej rozwijany więc używasz go na własną odpowiedzialność.


Instalacja
  • Pobierz skrypt (http://www.speedysha...Wxd/hosting.php) i wrzuć go do głównego katalogu MyBB.
  • Zaloguj się do swojej bazy danych i wykonaj następujące polecenia:

    CREATE TABLE IF NOT EXISTS `mybb_hosting` (
    `hid` int(11) NOT NULL AUTO_INCREMENT,
    `author_id` int(11) NOT NULL,
    `title` varchar(80) COLLATE utf8_bin NOT NULL,
    `description` text COLLATE utf8_bin NOT NULL,
    `image` varchar(200) COLLATE utf8_bin NOT NULL,
    `address` varchar(80) COLLATE utf8_bin NOT NULL,
    `email` varchar(80) COLLATE utf8_bin NOT NULL,
    `phone` varchar(80) COLLATE utf8_bin NOT NULL,
    `rate` int(11) NOT NULL,
    `rate_number` int(11) NOT NULL,
    `country` varchar(60) COLLATE utf8_bin NOT NULL,
    `zipcode` varchar(20) COLLATE utf8_bin NOT NULL,
    `www` varchar(120) COLLATE utf8_bin NOT NULL,
    `city` varchar(80) COLLATE utf8_bin NOT NULL,
    `about` text COLLATE utf8_bin NOT NULL,
    `type` set('web','game') COLLATE utf8_bin NOT NULL,
    PRIMARY KEY (`hid`)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=1;
    CREATE TABLE IF NOT EXISTS `mybb_hostingrates` (
    `oid` int(11) NOT NULL AUTO_INCREMENT,
    `hosting_id` int(11) NOT NULL,
    `rate1` int(11) NOT NULL,
    `content` text COLLATE utf8_bin NOT NULL,
    `website` varchar(80) COLLATE utf8_bin NOT NULL,
    `author_id` int(11) NOT NULL,
    `time` int(11) NOT NULL,
    `type` set('good','bad') COLLATE utf8_bin NOT NULL,
    `username` varchar(80) COLLATE utf8_bin NOT NULL,
    `rate2` int(11) NOT NULL,
    `rate3` int(11) NOT NULL,
    `rate_all` double NOT NULL,
    PRIMARY KEY (`oid`)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=1;
  • Wejdź do panelu administratora i zakładkę Style i Szablony a następnie w Szablonach utwórz nowy szablon o nazwie "hosting" i wrzuć do niego następującą treść:


    <html>
    <head>
    <title>Hosting - {$mybb->settings['bbname']}</title>
    {$headerinclude}
    {$metag}
    </head>
    <body>
    {$header}
    <br class="clear" />
    <div style="width: 100%;">
    {$content}
    </div>
    <br style="clear: both" />
    {$footer}
    </body>
    </html>
  • Utwórz grupę "Hosting" w panelu administratora i odpowiednio zmodyfikuj 2 linijki w pliku hosting.php:


    $hosting_gid = array(4, 9, 8);
    $admin_gid = array(4, 8);
Znane błędy
  • Skrypt wymaga, aby jego tabele miały prefix "mybb_"
  • W załączonym skrypcie nie jest dostępny widget umieszczony w siedebarze ze względu na to, że on dopisanych bezpośrednio do plików MyBB.
  • Kod HTML jest umieszczony bezpośrednio w pliku hosting.php (to nie jest stricte błąd, ale edycja czegoś takiego nie jest specjalnie przyjemna)

Integracja PayU - niedziałający sandbox

01 listopad 2012 - 11:59

Aktualnie zajmuję się integracją pewnego sklepu opartego o autorski skrypt z PayU. Żeby to zrobić zarejestrowałem się w sandboxie PayU i utworzyłem tam testowy sklep i POS.
Ustawiłem sobie w kodzie odpowiednie wartości i wyświetliłem taki formularz:

<form action="http://sandbox.payu.pl/paygw/UTF/NewPayment" method="POST" name="payform">
<input type="hidden" name="first_name" value="<?=$payment->user->name?>">
<input type="hidden" name="last_name" value="<?=$payment->user->surname?>">
<input type="hidden" name="email" value="<?=$payment->user->email?>">
<input type="hidden" name="pos_id" value="<?=$payu->posId?>">
<input type="hidden" name="pos_auth_key" value="<?=$payu->posAuthKey?>">
<input type="hidden" name="session_id" value="<?=time()?>">
<input type="hidden" name="amount" value="<?=($payment->price * 100)?>">
<input type="hidden" name="desc" value="Humanitee.pl - Opłata via PayU">
<input type="hidden" name="desc2" value="<?=$payment->id?>;<?=$payment->price?>">
<input type="hidden" name="client_ip" value="<?=Request::$client_ip?>">
<input type="hidden" name="js" value="0">
<input type="submit" value="Zapłać poprzez PayU.pl">
</form>
<script language="Javascript" type="text/javascript">
<!--
//document.forms['payform'].js.value=1;
-->
</script>

Wszelkie wartości w stylu <?=$pau->postId?> są oczywiście wypełnione prawidłowo. System generuje formularz w takim stylu:

<form action="http://sandbox.payu.pl/paygw/UTF/NewPayment" method="POST" name="payform">
<input type="hidden" name="first_name" value="Piotr">
<input type="hidden" name="last_name" value="Macha">
<input type="hidden" name="email" value="thelleo@youcode.pl">
<input type="hidden" name="pos_id" value="39173">
<input type="hidden" name="pos_auth_key" value="fYJec8o">
<input type="hidden" name="session_id" value="1351767222">
<input type="hidden" name="amount" value="13000">
<input type="hidden" name="desc" value="Humanitee.pl - Opłata via PayU">
<input type="hidden" name="desc2" value="27;130">
<input type="hidden" name="client_ip" value="83.144.69.190">
<input type="hidden" name="js" value="1">
<input type="submit" value="Zapłać poprzez PayU.pl">
</form>

No i do tej pory wszystko działa ładnie. Problem zaczyna sie dopiero wy wysłaniu tego formularza przez użytkownika. Zostaje on przekierowany na stronę http://sandbox.payu.../UTF/NewPayment z podanymi parametrami jednak wyświetla się wyłącznie biała strona (żadnego tekstu czy kodu).
Co ciekawe gdy otworzy się ten URL bezpośrednio (tj. bez danych z formularza) to otrzymujemy ładny błąd o "nieprawidłowym pos_id" (co nie jest niczym dziwnym, bo pos_id należy przesłać przez formularz).

Ktoś zajmował się kiedyś integracją PayU w PHP i wie może czy to jakiś błąd z mojej strony czy może to wina PayU?
Dodam jeszcze, że wysłanie formularza do produkcyjnego serwera PayU z danymi istniejącej i zarejestrowanej tam firmy działa prawidłowo, no, ale bez sandboxa nie będę w stanie testować działania PayU.

Problem rozwiązany!

Rozwiązałem problem używając produkcyjnego serwera PayU i testowego kanału płatności.

System pluginów w PHP

21 październik 2012 - 01:40

Na potrzeby swojego projektu, którym jest CMS chciałem stworzyć do niego mechanizm pluginów za pomocą których będę mógł się wczepiać do różnych funkcji skryptu.
Osobiście uważam, że bardzo przyjemnym w użyciu systemem jest ten umieszczony w MyBB dlatego moja metoda opiera się o podobną ideę.

Ogólnie rzecz biorąc to co teraz chciałbym przedstawić to mój pomysł na niewielki, ale potężny system pluginów opartych o haki za pomocą których możemy wczepić się w każde miejsce w którym programista przewidział możliwość wczepiania.

Klasa ma 2 metody. Pierwsza to register_hook($name, callable $function) za pomocą którego rejestrujemy akcję dla haka. W 1 parametrze wpisujemy nazwę haka, natomiast w drugim nazwę funkcji bądź inną rzecz będącą "callable".
Natomiast drugą metodą jest run_hook($name, $params = NULL) za pomocą której odpalamy funkcje przypisane do danego haka. W pierwszym parametrze znajduje się jego nazwa, natomiast w drugim ewentualne parametry, które chcemy przekazać do funkcji.

No dobrze, po tym krótkim wstępie przyszedł czas na kod opatrzony lekkim komentarze i przykładem zaprezentowanym pod klasą.

/**
* Simple class for basic plugin system based on hooks.
* You can register many function to one hook and run they all with one method.
*
* @author Thelleo
* @see http://youcode.pl
* @version 1.0.0
* @copyright Thelleo © 2012
* @license BSD
*
* @package Curro
* @subpackage Plugin
*/
class Curro_Plugin
{
/**
* List of registered hooks
* @var array
*/
static protected $hooks = array();

/**
* Registering new hook
* @param string $name -- Name of hook
* @param callable $function -- Callable function, you can use name of function in string or anonymous function
*/
static public function register_hook($name, callable $function)
{
self::$hooks[$name][] = $function;
}

/**
* Running functions registered to selected hook.
* @param string $name -- Name of hook to run
* @param mixed $params -- Params passed to functions
*/
static public function run_hook($name, $params = NULL)
{
if(array_key_exists($name, self::$hooks))
{
foreach(self::$hooks[$name] as $hook)
{
$hook($params); // Cool, huh?
}
}
}

}

/**
* TEST
*/

function change_name()
{
// Global needs to be about 20% cooler, but you can live with him.
global $text;
$text = 'Zmieniona nazwa!';
}

Curro_Plugin::register_hook('example_hook', 'change_name');

$text = 'Jestem sobie tekstem, który zostanie zmieniony przez plugin.
';
echo 'Tekst przed aktywacją haka: '.$text.'
';

Curro_Plugin::run_hook('example_hook');

echo 'Tekst po aktywacji haka: '.$text;


?>