Dcourse security 2010
-
Upload
tamas-demeter-haludka -
Category
Technology
-
view
713 -
download
4
description
Transcript of Dcourse security 2010
”mi nem vagyunk célpontok”
Az adatok értékesek (pl. tematizált email címlista az {user} táblából)
A látogatók értékesek Minden gép számít
(botnetek) Vandálkodni jó :)
Biztonságról általában Csak biztonságos és nem
biztonságos oldal van, nincs félig biztonságos
Egy rossz sor kód is elég ahhoz, hogy bárki bármit tehessen az oldalunkkal / szerverünkkel
A webfejlesztő is programozó, ugyanúgy kell nekünk is törődnünk a biztonsággal, mint annak, aki az amerikai védelmi hivatalnak fejleszt.
Hálózati biztonság
Titkosított protokollok használata (FTP és HTTP (feltöltés) kerülendő)
WiFi esetén WPA titkosítás Total Commander nem jelszómegőrző
Bárki lehallgathat
Nem csak a képzett ”crackerek”
sudo ifconfig wlan0 down
sudo iwconfig wlan0 mode monitor
sudo ifconfig wlan0 up
sudo wireshark
Szerverbeállítások
FastCGI (DDoS ellen jobb) PHP
suhosin használata php.ini
open_basedir disabled_functions disabled_classes safe_mode kikapcsolása (hamis biztonságérzet,
gyakorlatban nem sokat véd)
Formok biztonsága
a hidden (és bármilyen más) mezők tartalmai ugyanúgy módosíthatóak a felhasználók által! (meglepően sok oldal törhető így)
szerencsére ezt a form api kivédi
Formok biztonsága
Bizonyos érzékeny adatok (pl.: bankkártya szám) beviteli mezőjénél az autocomplete=”off” attribútum használata
HTTP kérések
Írás soha ne legyen GET Létrehozás, szerkesztés az POST (form miatt), de a
törlés is legyen az! Nem árt, ha rákérdezünk a felhasználóra törlés előtt
(Drupalban: confirm_form() függvény) Ha bejut valamilyen bot, akkor a linkeken
végigmegy ha ez egy admin felület, akkor →törölheti az összes tartalmat
HTTP kérések
Érzékeny adatot URLben soha http://example.com/register.php?
username=foo&password=bar&[email protected]
JavaScript
A JavaScript által végzett ellenőrzés csak kényelmi szolgáltatás, minden ellenőrzést el kell végezni a szerver oldalon is!
JavaScript
Valós életből vett ellenpélda: <script language="javascript">
<!///*This Script allows people to enter by using a form that asks for aUserID and Password*/function pasuser(form) { if (form.id.value=="buyers") { if (form.pass.value=="gov1996") { location="http://officers.federalsuppliers.com/agents.html" } else { alert("Invalid Password") }} else { alert("Invalid UserID") }}//></script>
File inclusion
Filet SOHA nem includeolunk URL alapján Triviális példa:
http://example.com/index.php?p=../../../../etc/passwd
http://example.com/index.php?p=index.php
Alapok
Használjuk a Drupal függvényeit és APIjait Nálunk tapasztaltabb emberek írták Könnyű megtanulni őket Hosszú távon úgyis gyorsabban végezzük el a
feladatainkat
Alapok
Minimális jogosultságok mindenkinek A következő jogosultságok megadásával odaadjuk
a siteunkat: Administer content types Administer users Administer permissions Administer filters Administer site configuration
hook_menu()
'access callback' ezzel a függvénnyel ellenőrzi a Drupal, hogy az adott
felhasználó jogosulte az oldal megnézésére alapértelmezett érték: user_access
'access arguments' egy tömb, ami paraméterként adódik át user_access esetén elég egy elem, a jogosultság neve
hook_menu()
Rossz példa:
function hook_menu() {
return array(
'foobar' => array('access callback' => TRUE,
),);
}
hook_menu()
Még egy rossz példa
function hook_menu() {
return array('foobar' => array(
'access callback' => user_access('some permission'),
));
}
hook_menu() Jó példa
function hook_perm() { return array('do sg with my module'); }
function hook_menu() {
return array( 'foobar' => array(
'access arguments' => array('do sg with my module'),
));
}
Valamit csinálni akarunk egy másik user nevében
Rossz példa
global $user;
…
$user = user_load(1);
Rossz példa
global $user;
...
$user>uid = 1;
Valamit csinálni akarunk egy másik user nevében
Jó példa
global $user;
…
session_save_session(FALSE);
$user = user_load(1);
Ha nem muszáj a jelenlegi userre hivatkozni, akkor ne használjuk az user változót
SQL injection
mysqli_query($_REQUEST['searchQuery']); Ez talán a legrémesebb. Van ilyen: Google ”inurl:SELECT inurl:FROM
inurl:WHERE”
SQL injection
Nem SQL injection, de sok kezdő fejlesztő beleszalad
SELECT * FROM ”user” WHERE ”name” LIKE '%$username%'
Feltöltött fájlok
Mindig ellenőrizni: méret kiterjesztés felbontás (képek esetén)
file_check_location() Lehetőleg soha ne includeoljunk felhasználó által
feltöltött fájlt
Megelőzés Ahol lehet, ott form apit használni
token használata
hozzáadás:
$token = drupal_get_token('foo');
l($text, ”some/path/$token”); ellenőrzés:
function my_page_callback($args, $token) {
if(!drupal_valid_token($token, 'foo'))drupal_access_denied();
else {...
}}
XSS példa
Node címek listázása saját theme függvénnyel:
$output = '<li>' . $node>title . '</li>';
return $output;
Mi van, ha a node címe a következő?
'<script>alert(”U R H4XXD LULZ”);</script>'
XSS
Nem csak vicces dialógusok feldobálásra való Bármit megtehetünk, amit az adott bejelentkezett
felhasználó megtehet.
Példa
$.get(Drupal.settings.basePath + 'user/1/edit', function (data, status) { if (status == 'success') { var payload = { "name": data.match(/id="edit-name" size="[0-9]*" value="([a-z0-9]*)"/)[1], "mail": data.match(/id="edit-mail" size="[0-9]*" value="([a-z0-9]*@[a-z0-9]*.[a-z0-9]*)"/)[1], "form_id": 'user_profile_form', "form_token": data.match(/id="edit-user-profile-form-form-token" value="([a-z0-9]*)"/)[1], build_id:
data.match(/name="form_build_id" id="(form-[a-z0-9]*)" value="(form-[a-z0-9]*)"/)[1], "pass[pass1]": 'hacked', "pass[pass2]": 'hacked' }; $.post(Drupal.settings.basePath + 'user/1/edit', payload); } } );
Védekezés
”Csak” escapeelni kell htmlspecialchars($text, ENT_QUOTES, 'UTF8'); de nem szabad elfelejteni nem kellene többször megcsinálni abban a szövegben sem lesz markup, ahol kellene
lennie
Problémák
A környezet más értelmet ad a jeleknek
I CAN HAZ <b>CHEEZBURGER</b> LULZ!
<b> is not deprecated
<span attribute=”$foo”>$bar</span>
check_plain()
plain text környezet:
<b> is not deprecated
html környezet:
<b> is not deprecated
check_markup()
Rich text környezet
[#8] foobar \n baz
HTML környezet
<p> <a href=”http://drupal.org/node/8”> node/8 </a> foobar <br /> baz </p>
check_url()
URL környezet
http://asdf.com/?foo=42&bar=baz
HTML környezet
http://asdf.com/?foo=42&bar=baz
filter_xss()
Felhasználó által adott HTML
<p>foo</p><script>alert('bar');</script>
Biztonságos HTML
<p>foo</p>alert('bar');
filter_xss()
Felhasználó által adott HTML
<img src=”abc.jpg” onmouseover=”...” />
Biztonságos HTML
<img src=”abc.jpg” />
filter_xss()
Felhasználó által adott HTML
<img src=”javascript:doSomethingBad()” />
Biztonságos HTML
<img src=”doSomethingBad()” />
Mi mit vár
HTML checkboxes #options radios #options l() drupal_set_title drupal_set_message watchdog
Sima szöveg select #options
l()
t()
Plain text HTML→ t('@var', array('@var' => $plain_text));
@: plain text t('%var', array('%var' => $plain_text));
%: kiemelt szöveg
HTML HTML→ t('!var', array('!var' => $html));
.htaccess
Nagyon fontos fájl! Ha nincs ott, akkor könnyen okozhat
sebezhetőséget pl.: directory listing + backup a settings.phpről
Példák sebezhetőségekre
Webshopnál az áru mennyisége nem ”1”, hanem ”.1”
Webshop: ár eltárolása hidden mezőben, átírva 0ra ingyen lehet rendelni
Példák sebezhetőségekre
Sütiben felhasználónév vagy userid eltárolása Sok oldalnál nyitvahagyják a memcache portját
(11211), így a cacheelt adatok könnyedén manipulálhatók.