SQL Injection

Na tejto prednáške si porozprávame niečo o bezpečnosti MySQL alebo skôr o tom, aké nástrahy hrozia pri bežnej práci s databázou. Nemáme na mysli prácu priamo v systéme phpMyAdmin, ale vykonávanie SQL query z kódu PHP, najmä pri práci s parametrami – či už z URL alebo z formulárov. Aby sme sa dostali do obrazu, otvorte si zdrojový kód našej domovskej stránky (index.php), čiže súbory controller.php a model.php.

 

Zamerajme sa v tejto chvíli na spôsob filtrovania na našej stránke, ale tento problém sa v podstate bude týkať aj ostatných funkcionalít, ktoré je možné vykonávať pomocou domovskej stránky. Ako vidíme, v controlleri máme v časti kódu, ktorá rieši filtrovanie, iba pár riadkov. Na začiatku sa pýtame v podmienke if, či bola vykonaná metóda GET a či prišiel parameter z formulára na vyhľadávanie, čiže či bol tento formulár odoslaný. V tomto prípade, ak formulár nebol odoslaný, ale zavedieme ho do URL, tak táto podmienka bude splnená. Následne si berieme hodnotu z parametra search_keyword, v ktorom je uložený textový reťazec, ktorý vyhľadávame v databáze.

 

Ak sa teda snažíme jednoducho vyhľadať napríklad slovo miro, naša url vyzerá takto : ...index.php?search_keyword=miro&sort_by=&sort_type=&search_form=Filtruj. Po zachytení sa hodnota tohto parametra uloží do property search_keyword objektu UserList. V modeli sa pri vyťahovaní všetkých dát skladá SQL Query, ktorá do seba zahrnie jednak parametre týkajúce sa zoraďovania a aj filtrovania. A toto je kameň úrazu. Všimnite si, že následne v modeli vo funkcii toLoadAllUsers nerobíme nič, iba rovno skladáme sql query s tým, že do nej zakomponujeme bez akejkoľvek kontroly hodnotu parametra zadaného vo formulári alebo v URL (prilepíme do stringu tvoriaceho query).

 

V prípade normálnych štandardných hodnôt to nie je problém. Jednoducho skladáme query, zakomponujeme string na vyhľadanie a zavoláme query. Všimnite si ale, že v podstate cez túto hodnotu sa akokeby rovno dostávame do databázy, resp. to, čo zadáme ako parameter, sa dostáva rovno (priamo) do databázy cez query. Čo keď sa k takémuto systému dostane niekto, kto sa troška vyzná do programovania a bude sa chceť trošku zabaviť? Aby sme vedeli, o čom je reč. Skúste si dať po zložení stringu vypísať obsah query cez print_r:

 


model.php:

...
}
    print_r($sql_query);
    return mysqli_query($GLOBALS['db']->connection, $sql_query);
...

 


Po zadaní slova miro pre filtrovanie by mala query vyzerať asi takto:

 

SELECT users.id,users.user_name,users.user_surname,users.age,users.role,user_phone_numbers.phone_number,upn.phone_number AS phone_number_2,COUNT(*) FROM users LEFT JOIN user_phone_numbers ON users.main_phone_number_id=user_phone_numbers.id LEFT JOIN user_phone_numbers AS upn ON users.id=upn.id_user WHERE users.user_name LIKE '%miro%' OR users.user_surname LIKE '%miro%' GROUP BY users.id

 


Ako vidíte, hodnota zadaná v inpute vo formulári je priamo v príkaze do db. Predstavte si, že tam napíšeme úplne niečo iné...hocijakú blbosť...napríklad : ako sa mas. Query vyzerá takto:

 


...users.user_name LIKE '%ako sa mas%' OR users.user_surname LIKE '%ako sa mas%' GROUP BY users.id...

 


Toto je ešte stále fajn. Ale čo keď tam niekto zadá niečo iné a ten niekto ovláda jazyk SQL a predpokladá, že to nemáme nijak ošetrené? Čo sa môže stať? Čo keby zadal taký reťazec, že by uzavrel náš príkaz (SELECT) a následne by tam zadal iný príkaz? Napríklad na vymazanie všetkých dát z databázy? A my by sme o tom nevedeli, iba by sme toto query spustili (stránka by to spustila automaticky sama na serveri) a vymazalo by nám to všetky dáta? Odpoveď je bohužiaľ krutá...kľudne sa to môže stať a nemáme tomu momentálne ako zabrániť, resp. nemáme to nijak ošetrené. O čom sa ale bavíme? Skúste si len na ukážku vytvoriť nejakú tabuľku s názvom test:

 


sql:

CREATE TABLE test (id int);

 


Po vykonaní príkazu vidíte tabuľku v zoznam tabuliek našej databázy. Predstavte si, že by používateľ do formuláru na filtrovanie zadal niečo takéto :

 


'; DROP TABLE test; SELECT * FROM users where id='%

 


Po zadaní tejto hodnoty na filtrovanie by mala celá sql query vyzerať asi takto:

 


SELECT users.id,users.user_name,users.user_surname,users.age,users.role,user_phone_numbers.phone_number,upn.phone_number AS phone_number_2,COUNT(*) FROM users LEFT JOIN user_phone_numbers ON users.main_phone_number_id=user_phone_numbers.id LEFT JOIN user_phone_numbers AS upn ON users.id=upn.id_user WHERE users.user_name LIKE '%';
DROP TABLE sss; SELECT * FROM users where id='%%' OR users.user_surname LIKE '%'; DROP TABLE test;
SELECT * FROM users where id='%%' GROUP BY users.id

 


Skúste si vyfiltrovať daný text a pozrite sa, čo sa stane, tabuľka v našej databáze je zmazaná! A to sme nechceli, návštevník stránky iba niečo špeciálne vyfiltroval a keby zmazal users, tak nenávratne prídeme takýmto krokom o všetky dáta v databáze. Už vidíte, aké to je nebezpečné? Keď sa pozriete na query čo sa stalo, tak je to pochopiteľné. Úvodzovkou a bodkočiarkou sme uzavreli select, keďže je to na filtrovanie, dá sa ľahko predpokladať, že daná hodnota bude obsahom WHERE podmienky. Následne sme zadali príkaz na vymazanie tabuľky. A potom sme dali nový select, aby sme k nemu pripojili zvyšok query, pretože sme ho predčasne uzavreli. Tam sme dali ľubovoľný select, len aby query nehodilo chybu.

 

Takto sme z jedného príkazu spravili tri, ovšem ten stredný slúži na útok na databázu. Možno ste si povedali, no dobre, ale ako bude vedieť útočník, aký máme presne SELECT a aký máme názov tabuľky. Máte pravdu, nemá to skade vedieť, môže ale skúšať a možno sa trafí.

 

Možností pre takýto útok je viacero, niekedy je zmazanie ešte tá lepšia vec. Čo keď sú ale v databáze uložené citlivé dáta a nejakým takýmto útokom by k ním útočník prišiel? Napríklad nevykonával by príkaz na zmazanie tabuľky ale možno by použil nejaký select, aby získal prihlasovacie údaje v databáze alebo iné citlivé (súkromné) údaje? Možností je veľa. A ciest takisto. Všade, kde sa zadávajú parametre v URL alebo cez formuláre a ide to databázy, je tam takáto hrozba. Tento druh útoku sa volá SQL Injection, pretože útočník (inject – vstreknúť) akokeby vstrekol/vsunul vlastný SQL kód cez parameter.

 

Ako sa voči tomu brániť? Jednoduché riešenie, pokiaľ to je možné a neobmedzí to fungovanie systému, je kontrolvať hodnoty pred vložením do query stringu. Napríklad použiť regulárne výrazy alebo len jendoducho odifovať, či sa v stringu nenachádza nejaký zakázaný string ako bodkočiarka, úvodzovky, select, drop, delete a podobne.

 

V niektorých prípadoch je to ale obmedzenie, lebo niekedy sa takéto slová môžu nachádzať v databáze, napríklad úvodzovka môže byť súčasťou nejakého stringu, ktorý sa vkladá do databázy. V tomto prípade je nutné použiť náročnejšiu ochranu a to iné volanie query v db. V tomto prípade sa takéto hodnoty zadané zvonka pridávajú do query ako parametre, ktoré sú kontrolované samotným db serverom (parametrizované query). Čiže do query sa vloží len info, že niečo tam bude pridané (parameter), ale tento parameter sa pridáva až následne osobitnými funkciami. V takomto prípade je query akokeby kontrolovaná a vykonávaná osobitne, takže to zabraňuje tomuto typu útoku. Nám by ale stačil v tomto prípade zatiaľ prvý prípad, s ktorým by sme nemali mať problém ho zakomponovať a možno neskôr sa dostaneme aj k parametrizovaným query...

Máte nejakú otázku alebo Vám niečo nie je jasné? Napíšte nám na info@zacni-programovat.sk a poradíme!

Obsah súborov projektu po tejto prednáške

1 - controller.php

<?php 
//vnorene subory
include "helper.php";
include "model.php";

$actual_page = "index";
$helper = new Helper();

$user_name = '';
$user_surname = '';
$age = '';
$role = '';
$message = '';

//TRIEDA USERLIST (zoznam pouzivatelov)
class UserList{

public $users = array();
public $search_keyword = '';
public $sort_by = 'id';
public $sort_type = 'ASC';
public $helper = null;

function __construct($helper){
$this->helper = $helper;
}

function loadData(){
$result = toLoadAllUsers($this->search_keyword, $this->sort_by, $this->sort_type);

if (mysqli_num_rows($result) > 0) {
$data = mysqli_fetch_all($result, MYSQLI_ASSOC);

//TRANSFORMACIA DAT NA POLE OBJEKTOV
foreach($data as $key => $value){
if($value['role'] == 'owner'){
$this->users[$key] = new UserOwner($value['id'], $value['user_name'], $value['user_surname'], $value['age'], $value['role'], $value['phone_number'], $value['phone_number_2'], $value['COUNT(*)']);
}else{
$this->users[$key] = new User($value['id'], $value['user_name'], $value['user_surname'], $value['age'], $value['role'], $value['phone_number'], $value['phone_number_2'], $value['COUNT(*)']);
}
}

//$this->helper->printArray($this->users);
}
}

function deleteUserById($id_user){
$actual_user = null;
$actual_user_key = null;

foreach($this->users as $key => $value){
if($value->id == $id_user){
$actual_user = $value;
$actual_user_key = $key;
}
}

if($actual_user && $actual_user->deleteUser()){
array_splice($this->users, $actual_user_key, 1);

return true;
}else{
return false;
}
}
}

//TRIEDA USER (pouzivatel v tabulke users)
class User{

public $id = 0;
public $user_name = '';
public $user_surname = '';
public $age = 0;
public $role = '';
public $main_phone_number = '';
public $all_phone_numbers = array();

function __construct($id, $user_name, $user_surname, $age, $role, $main_phone_number, $phone_number, $count_phone_number){
$this->id = $id;
$this->user_name = $user_name;
$this->user_surname = $user_surname;
$this->age = $age;
$this->role = $role;
$this->main_phone_number = $main_phone_number;

//test ci treba nacitat viac cisiel
if($phone_number && $count_phone_number > 1){
//musime nacitat cisla
$this->loadPhoneNumbers();
}else{
//ma iba ajedno alebo ziadne cislo
if($phone_number){
$this->all_phone_numbers[] = $phone_number;
}
}
}

function loadPhoneNumbers(){

$result = toLoadAllNumbersByIdUser($this->id);

$data = mysqli_fetch_all($result, MYSQLI_ASSOC);

foreach($data as $key => $value){
$this->all_phone_numbers[] = $value['phone_number'];
}
}

function deleteUser(){
return toDeleteUserByIdUser($this->id);
}

function insertToDb(){
return toInsertNewUser($this->user_name, $this->user_surname, $this->age, $this->role);
}
}

class UserOwner extends User{

function remindOwnerByMail(){
//kod pre vykonanie funkcie
print_r('Zavolala sa metoda remindOwnerByMail()');
}
}

//ZACHYTENIE PARAMETROV PRE VLOZENIE NOVEHO USERA
if($_SERVER['REQUEST_METHOD'] == 'POST' && $_POST['user_form']){
$user_name = $_POST['user_name'];
$user_surname = $_POST['user_surname'];
$age = $_POST['age'];
$role = $_POST['role'];

if(preg_match('#^.{0,50}$#', $user_name) &&
preg_match('#^.{1,50}$#', $user_surname) &&
preg_match('#^.{0,20}$#', $role) &&
preg_match('#^[0-9]{0,3}$#', $age)){

//KOREKTNE DATA
$new_user = new User(null, $user_name, $user_surname, $age, $role);

if($new_user->insertToDb()){
$message = '<p class="success">Položka bola úspešne uložená.</p>';
}else{
$message = '<p class="error">Pri ukladaní dát do databzy sa vyskytla chyba.</p>';
}

//vycistenie poloziek
$user_name = '';
$user_surname = '';
$age = '';
$role = '';

}else{
//CHYBNE DATA
$message = '<p class="error">Nová položka nebola uložená - nesprávne vyplnené dáta vo formulári. </p>';
}

}

$user_list = new UserList($helper);

//SPRACOVANIE FILTROVANIA
if($_SERVER['REQUEST_METHOD'] == 'GET' && $_GET['search_form']){
$user_list->search_keyword = $_GET['search_keyword'];
}

//ZACHYTENIE PARAMETRA PRE TRIEDENIE DAT V TABULKE
$user_list->sort_by = $_GET['sort_by'];
$user_list->sort_type = $_GET['sort_type'];

$user_list->loadData();

//MAZANIE POLOZKY
$id_user = $_GET['id_user'];
if($id_user){

$result = $user_list->deleteUserById($id_user);

if($result){
$message = '<p class="success">Položka bola úspešne zmazaná.</p>';
}else{
$message = '<p class="error">Pri mazaní položky sa vyskytla chyba.</p>';
}
}

?>

2 - footer.php

<div class="footer">
</div>

3 - fotogaleria.php

<!DOCTYPE html>

<html lang="sk">
<head>
<title>Vitajte na našej prvej skutočnej webstránke!</title>

<meta charset=“UTF-8“>
<meta name="description" content="Ponúkame vám lekcie jazykov HTML, CSS, PHP a mnoho ďalších užitočných rád pri programovaní">
<meta name="keywords" content="programovanie, html, css, php, webstranka, web, tvorba webu, web developer, ucenie programovania, ako programovat">

<link rel="stylesheet" type="text/css" href="global.css">
</head>

<body>
<?php $actual_page = "fotogaleria";?>
<div class="main">

<?php include "header.php";?>

<div class="content">

<?php include "menu.php";?>

<div id="gallery-content" class="main-content right">
<h1>Fotogaléria</h1>
<div class="line"></div>

<?php

$pictures = array();

for($i = 0; $i < 30; $i++){
$pictures[] = 'images/placeholder.jpg';
}

//zadefinovanie maximalneho poctu pre jednu stranku a nacitanie parametra (urcenie aktualnej stranky)
$countPerPage = 12;
if($_GET['page']){
$page = $_GET['page'];
}else{
$page = 1;
}

//vypocet od ktorej po ktoru fotku zobrazujeme galeriu
$start = ($page-1)*$countPerPage;
$end = $page*$countPerPage;

echo '<ul id="gallery">';
for($i = $start; $i < $end; $i++){

if($pictures[$i]){
echo '<li class="left';

if(($i+1)%3){
echo ' photo-margin';
}

echo '">';

echo '<img src="'.$pictures[$i].'">';

echo '<a target="_blank" href="'.$pictures[$i].'" class="over_div">';
echo '<span>Kliknite pre zväčšenie!</span>';
echo '</a>';

echo '</li>';
}
}
echo '</ul>';

//cyklus, ktory nam vypise dostatocny pocet odkazov pre jednotlive stranky
$pageLink = 1;
$photosCount = count($pictures);

echo '<ul class="pagination">';
while($photosCount > 0){

echo '<li><a ';

if($pageLink == $page){
echo ' class="active" ';
}

echo 'href="fotogaleria.php?page='.$pageLink.'">'.$pageLink.'</a>';
echo '</li>';
$photosCount = $photosCount - $countPerPage;
$pageLink++;
}
echo '</ul>';

?>

<h2 style="text-shadow: 4px 4px 5px #5b6b78;">Na tento text sme si aplikovali shadooooooow!</h2>
<div style="width: 50px; height: 50px; background-color: yellow; transform: rotate(-80deg);">Tocim sa...</div>

<div style="width: 80px; height: 20px; background-color: red; color: white; margin-left: 50px; margin-bottom: 50px; transform: rotate(45deg);">AKCIA</div>

<div style="width: 50px; height: 20px; background-color: red; color: white;">Domov</div>

<div style="width: 50px; height: 20px; background-color: red; color: white; margin-top: 5px; transform: rotateX(180deg);">Domov</div>

<br>

<div style="width: 50px; height: 20px; background-color: red; color: white; display:inline-block; transform: rotateY(180deg)">Home</div>

<div style="width: 50px; height: 20px; background-color: red; color: white; display:inline-block;">Home</div>

<div class="div_effect"></div>

<br><br>
</div>

<div class="clear"></div>
</div>

<?php include "footer.php";?>
</div>
</body>
</html>

4 - global.css

BODY{
margin: 0;
background-color: #dee8e7;
font-family: Arial;
}

H1{
color: #5b6b78;
margin-bottom: 10px;
}

.line{
height: 3px;
border-top: 1px dotted #5b6b78;
border-bottom: 1px dotted #5b6b78;
margin-bottom: 25px;
}

.main{
background-color: #f6f7f1;
width: 900px;
margin: auto;
margin-top: 20px;
margin-bottom: 20px;
border-radius: 10px;
box-shadow: 5px 5px 5px #CCCCCC, -5px -5px 5px #CCCCCC;
}

.header{
border-bottom: 1px solid #7d8079;
height: 150px;
}

.header-inner1{
}

.header-inner2{
}

.content{
}

.footer{
border-top: 1px solid #7d8079;
height: 200px;
}

.half-width{
width: 50%;
}

.full-height{
height: 100%;
}

.left{
float: left;
}

.right{
float: right;
}

.clear{
clear: both;
}

/**********MENU***********/
.sidebar{
width: 200px;
height: 400px;
}

.sidebar UL{
list-style-type: none;
padding: 0;
margin: 0;
}

.sidebar UL LI{
position: relative;
}

.sidebar UL LI A, .sidebar UL LI:HOVER .submenu A{
display: block;
padding: 15px 0px 15px 35px;
border-bottom: 1px solid #7d8079;
color: #7d8079;
text-decoration: none;
text-transform: uppercase;
}

.sidebar UL LI A.active{
color: #f5f7f4;
background-color: #f96b81;
}

.sidebar UL LI:HOVER A, .sidebar UL LI .submenu LI:HOVER A{
background-color: #5b6b78;
color: #d6e3e9;
}

.main-content{
width: calc(100% - 241px);
min-height: 700px;
border-left: 1px solid #7d8079;
padding-left: 20px;
padding-right: 20px;
}

.submenu{
display: none;
border: 2px solid #7d8079;
position: absolute;
top: -1px;
left: 201px;
width: 200px;
background-color: #FFFFFF;
}

.sidebar UL LI:HOVER .submenu{
display: block;
}

.sidebar UL LI:HOVER .submenu A{
background-color: #FFFFFF;
}

.main-content{
width: calc(100% - 241px);
min-height: 700px;
border-left: 1px solid #7d8079;
padding-left: 20px;
padding-right: 20px;
}

/**********GALERIA***********/
/**********GALERIA***********/
#gallery{
display: inline-block;
width: 100%;
list-style-type: none;
margin: 0;
padding: 0;
}

#gallery LI{
position: relative;
height: 133px;
margin-bottom: 10px;
}

#gallery LI IMG{
width: 213px;
height: 133px;
}

.photo-margin{
margin-right: 10px;
}

#gallery A{
display: none;
}

#gallery LI:HOVER A{
display: block;
}

#gallery LI:HOVER{
outline: 2px solid #7d8079;
}

#gallery A{
text-decoration: none;
position: absolute;
background-color: grey;
opacity: 0.4;
height: 100%;
width: 100%;
top: 0px;
}

#gallery A SPAN{
position: relative;
top: 100px;
color: #FFFFFF;
font-weight: bold;
}

/**********PERSONS***********/
.persons{
width: 100%;
font-family: Arial;
}

.persons, .persons TH, .persons TD{
border: 1px solid #D9E4E6;
}

.persons TH, .persons TD{
padding: 10px;
}

.persons TH{
background-color: #167F92;
color: #FFFFFF;
font-weight: normal;
text-transform: uppercase;
}

.persons TR:nth-child(odd){
background-color: #D9E4E6;
}

.persons TR{
color: #024457;
background-color: #FFFFFF;
}

.persons TD{
font-size: 14px;
}

.persons TR:HOVER{
color: #f5f7f4;
background-color: #f96b81;
cursor: pointer;
}

.persons TH A.sortable{
color: #FFFFFF;
}

.persons TH A.sortable:HOVER{
color: #D9E4E6;
}

.persons TH A.sortable.asc:before{
content: '⇡ ';
}

.persons TH A.sortable.desc:before{
content: '⇣ ';
}

/**********PERSONS***********/
.contact_form{
padding: 20px;
border: 1px solid #ebebeb;
background-color: white;
font-family: Arial;
font-size: 14px;
color: #455560;
text-transform: uppercase;
text-align: center;
}

.filter_box{
border-radius: 40px 10px;
}

.contact_form INPUT, .contact_form TEXTAREA, .contact_form LABEL{
display: block;
width: 100%;
}

.contact_form LABEL{
margin-bottom: 5px;
text-align: left;
}

.contact_form INPUT, .contact_form TEXTAREA{
height: 30px;
border: 1px solid #bababa;
margin-bottom: 30px;
}

.contact_form TEXTAREA{
min-height: 100px;
min-width: 100%;
max-width: 100%;
}

.contact_form INPUT[type="submit"]{
display: inline;
width: 200px;
height: 40px;
background-color: #7bc143;
border: 1px solid #6fae3c;
font-size: 16px;
color: #FFFFFF;
text-transform: uppercase;
}

.contact_form INPUT[type="submit"]:HOVER{
cursor: pointer;
background-color: #42aa44;
}

.success, .error{
border: 1px solid;
margin: 10px 0px;
padding:15px 10px 15px 10px;
}

.success {
color: #4F8A10;
background-color: #DFF2BF;
}

.error {
color: #D8000C;
background-color: #FFBABA;
}
/**********PAGINATION***********/
#gallery-content{
text-align: center;
}

ul.pagination {
display: inline-block;
padding: 0;
margin: 10px 0px 20px 0px;
}

ul.pagination li {
display: inline;
}

ul.pagination li a {
color: black;
padding: 8px 16px;
text-decoration: none;
border: 1px solid #ddd;
}

ul.pagination li a.active {
background-color: #4CAF50;
color: white;
}

ul.pagination li a:hover{
background-color: #ddd;
}

.map{
margin: 30px 0px;
text-align: center;
padding: 25px 0px;
background-color: #FFFFFF;
}

/**********TRANSITION***********/
.div_effect{
width: 100px;
height: 50px;
background-color: yellow;
transition: width 2s, height 2s, background-color 2s;
}

.div_effect:HOVER{
width: 200px;
height: 100px;
background-color: pink;
}

5 - header.php

<div class="header">
<div class="header-inner1 full-height half-width left"></div>
<div class="header-inner2 full-height half-width left"></div>
</div>

6 - helper.php

<?php

class Helper{

function printArray($array){
echo '<br><br>Obsah pola vypisany metodou PrintArray :<br><pre>';
print_r($array);
echo '</pre><br><br>';
}
}

?>

7 - index.php

<?php

include "controller.php";
include "view.php";

?>

8 - kontakt.php

<!DOCTYPE html>

<html lang="sk">
<head>
<title>Vitajte na našej prvej skutočnej webstránke!</title>

<meta charset=“UTF-8“>
<meta name="description" content="Ponúkame vám lekcie jazykov HTML, CSS, PHP a mnoho ďalších užitočných rád pri programovaní">
<meta name="keywords" content="programovanie, html, css, php, webstranka, web, tvorba webu, web developer, ucenie programovania, ako programovat">

<link rel="stylesheet" type="text/css" href="global.css">
</head>

<body>
<?php $actual_page = "kontakt";?>
<div class="main">

<?php include "header.php";?>

<div class="content">

<?php include "menu.php";?>

<div class="main-content right">
<h1>Kontakt</h1>
<div class="line"></div>

<?php
if($_SERVER['REQUEST_METHOD'] == 'POST' && $_POST['contact_form']){
if(!preg_match('#^[a-zA-Z0-9]{5,10}$#', $_POST['name']) || !filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)){
echo '<p class="error">Zadajte prosim korektne udaje</p>';

//naplnenie formulara
$name = $_POST['name'];
$email = $_POST['email'];
$subject = $_POST['subject'];
$message = $_POST['message'];
}else{
//odoslanie emailu
echo '<p class="success">Vasa sprava bola uspesne odoslana.</p>';

$name = '';
$email = '';
$subject = '';
$message = '';
}

}

?>

<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method="post" class="contact_form">
<label for="email">Meno a priezvisko</label>
<input type="text" name="name" id="name" value="<?php echo $name;?>"><br><br>

<label for="email">Email</label>
<input type="text" name="email" id="email" value="<?php echo $email;?>"><br><br>

<label for="subject">Predmet</label>
<input type="text" name="subject" id="subject" value="<?php echo $subject;?>"><br><br>

<label for="message">Správa</label>
<textarea name="message" id="message" placeholder="Zadajte text spravy..."><?php echo $message;?></textarea><br><br>

<input type="submit" name="contact_form" value="Odoslat">
</form>

<div class="map">
<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d84199.38373426767!2d19.06093170408453!3d48.73928892777478!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x47153de36e8ad42f%3A0xf8223f8a0b8b9032!2sBansk%C3%A1+Bystrica!5e0!3m2!1ssk!2ssk!4v1465151393672" width="600" height="450" frameborder="0" style="border:0" allowfullscreen></iframe>
</div>
</div>

<div class="clear"></div>
</div>

<?php include "footer.php";?>
</div>
</body>
</html>

9 - menu.php

<div class="sidebar left">
<ul>
<li><a class="<?php if($actual_page == "index"){echo 'active';}?>" href="index.php">Domov</a></li>
<li><a class="<?php if($actual_page == "o-nas"){echo 'active';}?>" href="o-nas.php">O nás</a></li>
<li><a class="<?php if($actual_page == "fotogaleria"){echo 'active';}?>" href="fotogaleria.php">Fotogaléria</a></li>
<li>
<a class="<?php if($actual_page == "kontakt"){echo 'active';}?>" href="kontakt.php">Kontakt</a>

<ul class="submenu">
<li><a href="kontakt.php">Kontakt</a></li>
<li><a href="kontakt.php">Kontakt</a></li>
</ul>

</li>
</ul>
</div>

10 - model.php

<?php
//TRIEDA DATABAZA (pripojenie)
class Database{

public $server_name = '';
public $login_name = '';
public $login_password = '';
public $db_name = '';
public $connection = null;

function __construct($server_name, $login_name, $login_password, $db_name){
$this->server_name = $server_name;
$this->login_name = $login_name;
$this->login_password = $login_password;
$this->db_name = $db_name;
}

function connectToDb(){
$this->connection = mysqli_connect($this->server_name, $this->login_name, $this->login_password, $this->db_name);

if (!$this->connection) {
echo 'Spojenie s databázou sa nepodarilo nadviazať.';
}else{
// echo 'Spojenie s databázou sa podarilo úspešne nadviazať.';
}
}
}

//PRIPOJENIE DO DB
$db = new Database('localhost', 'root', 'root', 'zapr_db_1');
$db->connectToDb();





//------FUNKCIE PRE TABULKU users

//vytiahnutie vsetkych dat z tabulky spolu s primarnym cislom pre tabulkovy zoznam na domovskej stranke
function toLoadAllUsers($search_keyword, $sort_by, $sort_type){
$sql_query = "SELECT users.id,users.user_name,users.user_surname,users.age,users.role,user_phone_numbers.phone_number,upn.phone_number AS phone_number_2,COUNT(*) FROM users LEFT JOIN user_phone_numbers ON users.main_phone_number_id=user_phone_numbers.id LEFT JOIN user_phone_numbers AS upn ON users.id=upn.id_user";

if($search_keyword){
$sql_query .= " WHERE users.user_name LIKE '%".$search_keyword."%' OR users.user_surname LIKE '%".$search_keyword."%'";
}

$sql_query .= " GROUP BY users.id";

if($sort_by){
$sql_query .= " ORDER BY ".$sort_by;

if($sort_type){
$sql_query .= " ".$sort_type;
}else{
$sql_query .= " ASC";
}
}

print_r($sql_query);
return mysqli_query($GLOBALS['db']->connection, $sql_query);
}

//zmazanie pouzivatela podla jeho id
function toDeleteUserByIdUser($id_user){
$sql_query = "DELETE FROM users WHERE id=".$id_user;
return mysqli_query($GLOBALS['db']->connection, $sql_query);
}

//pridanie noveho pouzivatela z formulara na domovskej stranke
function toInsertNewUser($user_name, $user_surname, $age, $role){
$sql_query = "INSERT INTO users (user_name, user_surname, age, role) VALUES (";

//otestovanie ci prisli parametre, inak vkladame NULL
if($user_name){
$sql_query .= "'".$user_name."',";
}else{
$sql_query .= "NULL,";
}

$sql_query .= "'".$user_surname."',";

if($age){
$sql_query .= $age.",";
}else{
$sql_query .= "NULL,";
}

if($role){
$sql_query .= "'".$role."')";
}else{
$sql_query .= "NULL)";
}

return mysqli_query($GLOBALS['db']->connection, $sql_query);
}



//------FUNKCIE PRE TABULKU user_phone_numbers

//nacitanie vsetkych telefonnych cisiel jedneho usera podla jeho id z tabulky user
function toLoadAllNumbersByIdUser($id_user){
$sql_query = "SELECT * from user_phone_numbers WHERE id_user=".$id_user;
return mysqli_query($GLOBALS['db']->connection, $sql_query);
}

?>

11 - o-nas.php

<!DOCTYPE html>

<html lang="sk">
<head>
<title>Vitajte na našej prvej skutočnej webstránke!</title>

<meta charset=“UTF-8“>
<meta name="description" content="Ponúkame vám lekcie jazykov HTML, CSS, PHP a mnoho ďalších užitočných rád pri programovaní">
<meta name="keywords" content="programovanie, html, css, php, webstranka, web, tvorba webu, web developer, ucenie programovania, ako programovat">

<link rel="stylesheet" type="text/css" href="global.css">
</head>

<body>
<?php $actual_page = "o-nas";?>
<div class="main">

<?php include "header.php";?>

<div class="content">

<?php include "menu.php";?>

<div class="main-content right">
<h1>O nás</h1>
<div class="line"></div>

<?php
$person_1 = array('Raťafák', 'Plachta', 'plachtos@mail.sk','0903 123 123');
$person_2 = array('Od kuka', 'do kuka', 'kuko@mail.sk','0903 123 123');
$person_3 = array('Joey', 'Tribbiani', 'ako.sa.mas@mail.sk','0903 123 123');
$person_4 = array('Charlie', 'Harper', 'hooker@mail.sk','0903 123 123');
$person_5 = array('Chruno', 'Moysey', 'abstinent@mail.sk','0903 123 123');

$pole = array($person_1, $person_2, $person_3, $person_4, $person_5);

$pole[5] = array('Jardo', 'Jágr', 'legenda@mail.sk','0903 123 123');

echo '<table class="persons">';
echo '<tr>';
echo '<th>Meno</th>';
echo '<th>Priezvisko</th>';
echo '<th>Email</th>';
echo '<th>Telefónne číslo</th>';
echo '</tr>';

for($i=0; $i<count($pole); $i++){
echo '<tr>';

for($j=0; $j<count($pole[$i]); $j++){
echo '<td>'.$pole[$i][$j].'</td>';
}

echo '</tr>';
}

echo '</table>';

?>
</div>

<div class="clear"></div>
</div>

<?php include "footer.php";?>
</div>
</body>
</html>

12 - uprava-zaznamu.php

<!DOCTYPE html>

<html lang="sk">
<head>
<link rel="stylesheet" type="text/css" href="global.css">
</head>

<body>
<div class="main">

<?php include "header.php";?>

<div class="content">

<?php include "menu.php";?>

<div class="main-content right">
<h1>Editácia používateľa</h1>
<div class="line"></div>

<?php
$id_user = $_GET['id_user'];

//PRIPOJENIE DO DB
$server_name = "localhost";
$db_user_name = "root";
$password = "root";
$dbname = "zapr_db_1";

$connection = mysqli_connect($server_name, $db_user_name, $password, $dbname);

if (!$connection) {
echo '<p class="error">Spojenie s databázou sa nepodarilo nadviazať.</p>';
}

//SPRACOVANIE ODOSLANIA FORMULARA
if($_SERVER['REQUEST_METHOD'] == 'GET' && $_GET['edit_user_form']){
$user_name = $_GET['user_name'];
$user_surname = $_GET['user_surname'];
$age = $_GET['age'];
$role = $_GET['role'];

if(preg_match('#^.{0,50}$#', $user_name) &&
preg_match('#^.{1,50}$#', $user_surname) &&
preg_match('#^.{0,20}$#', $role) &&
preg_match('#^[0-9]{0,3}$#', $age)){

//KOREKTNE DATA

//ulozenie do DB
$sql_query = "UPDATE users SET user_name=";

//otestovanie ci prisli parametre, inak vkladame NULL
if($user_name){
$sql_query .= "'".$user_name."',";
}else{
$sql_query .= "NULL,";
}

$sql_query .= "user_surname='".$user_surname."',age=";

if($age){
$sql_query .= $age.",";
}else{
$sql_query .= "NULL,";
}

$sql_query .= "role=";

if($role){
$sql_query .= "'".$role."'";
}else{
$sql_query .= "NULL";
}

$sql_query .= " WHERE id=".$id_user.";";

$result = mysqli_query($connection, $sql_query);

if($result){
echo '<p class="success">Položka bola úspešne uložená.</p>';
?>

<script>
window.location.href = "/MyProject Coding/5-Projekt2/index.php";
</script>

<?php
}else{
echo '<p class="error">Pri ukladaní dát do databázy sa vyskytla chyba.</p>';
}


}else{
//CHYBNE DATA
echo '<p class="error">Položka nebola uložená - nesprávne vyplnené dáta vo formulári. </p>';
}
}

//NACITANIE DAT O USEROVI
if($id_user){
$sql_query = "SELECT * FROM users WHERE id=".$id_user.";";

$result = mysqli_query($connection, $sql_query);

if (mysqli_num_rows($result) > 0) {

$data = mysqli_fetch_all($result, MYSQLI_ASSOC);
$user_name = $data[0]['user_name'];
$user_surname = $data[0]['user_surname'];
$age = $data[0]['age'];
$role = $data[0]['role'];


?>

<!-- Formular pre editovanie usera -->
<form class="contact_form" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method="get">
<label for="user_name">Meno</label>
<input type="text" name="user_name" id="user_name" value="<?php echo $user_name;?>">

<label for="user_surname">Priezvisko</label>
<input type="text" name="user_surname" id="user_surname" value="<?php echo $user_surname;?>">

<label for="age">Vek</label>
<input type="text" name="age" id="age" value="<?php echo $age;?>">

<label for="role">Rola</label>
<input type="text" name="role" id="role" value="<?php echo $role;?>">

<input type="hidden" name="id_user" value="<?php echo $id_user;?>">

<input type="submit" name="edit_user_form" value="Odoslať">
</form>

<?php


}else{
echo '<p class="error">Nepodarilo sa načítať dáta pre editovanie.</p>';
}


}else{
echo '<p class="error">Parameter používateľa pre editáciu sa nepodarilo načítať.</p>';
}

?>
</div>

<div class="clear"></div>
</div>

<?php include "footer.php";?>

</div>

</body>
</html>

13 - view.php

<!DOCTYPE html>

<html lang="sk">
<head>
<title>Vitajte na našej prvej skutočnej webstránke!</title>

<meta charset=“UTF-8“>
<meta name="description" content="Ponúkame vám lekcie jazykov HTML, CSS, PHP a mnoho ďalších užitočných rád pri programovaní">
<meta name="keywords" content="programovanie, html, css, php, webstranka, web, tvorba webu, web developer, ucenie programovania, ako programovat">

<link rel="stylesheet" type="text/css" href="global.css">
</head>

<body>
<div class="main">

<?php include "header.php";?>

<div class="content">

<?php include "menu.php";?>

<div class="main-content right">
<h1>Domov</h1>
<div class="line"></div>

<?php
if($message){
echo $message;
}
?>

<h2>Pridanie nového používateľa</h2>

<!-- Formular pre vlozenie noveho usera -->
<form class="contact_form" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method="post">
<label for="user_name">Meno</label>
<input type="text" name="user_name" id="user_name" value="<?php echo $user_name;?>">

<label for="user_surname">Priezvisko</label>
<input type="text" name="user_surname" id="user_surname" value="<?php echo $user_surname;?>">

<label for="age">Vek</label>
<input type="text" name="age" id="age" value="<?php echo $age;?>">

<label for="role">Rola</label>
<input type="text" name="role" id="role" value="<?php echo $role;?>">

<input type="submit" name="user_form" value="Odoslať">
</form>

<h2>Zoznam používateľov</h2>

<!-- Formular na filtrovanie usera -->
<form class="contact_form filter_box" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method="get">
<label for="search_keyword">Meno</label>
<input type="text" name="search_keyword" id="search_keyword" value="<?php echo $user_list->search_keyword;?>">

<input type="hidden" name="sort_by" value="<?php echo $user_list->sort_by;?>">
<input type="hidden" name="sort_type" value="<?php echo $user_list->sort_type;?>">

<input type="submit" name="search_form" value="Filtruj">
</form>

<br>

<?php
//VYPIS POUZIVATELOV DO TABULKY
if($user_list->users){

echo '<table class="persons">';
echo '<tr>';
echo '<th>ID</th>';

echo '<th><a class="sortable';

if($user_list->sort_by == 'user_name'){
if($user_list->sort_type == 'ASC'){
echo ' asc';
}else{
echo ' desc';
}
}

echo '" href="index.php?sort_by=user_name';

if($user_list->sort_by == 'user_name'){
if($user_list->sort_type == 'ASC'){
echo '&sort_type=DESC';
}else{
echo '&sort_type=ASC';
}
}else{
echo '&sort_type=ASC';
}

if($user_list->search_keyword){
echo '&search_keyword='.$user_list->search_keyword.'&search_form=Filtruj';
}

echo '">Meno</a></th>';

echo '<th><a class="sortable';

if($user_list->sort_by == 'user_surname'){
if($user_list->sort_type == 'ASC'){
echo ' asc';
}else{
echo ' desc';
}
}

echo '" href="index.php?sort_by=user_surname';

if($user_list->sort_by == 'user_surname'){
if($user_list->sort_type == 'ASC'){
echo '&sort_type=DESC';
}else{
echo '&sort_type=ASC';
}
}else{
echo '&sort_type=ASC';
}

if($user_list->search_keyword){
echo '&search_keyword='.$user_list->search_keyword.'&search_form=Filtruj';
}

echo '">Priezvisko</a></th>';

echo '<th>Vek</th>';
echo '<th>Rola</th>';
echo '<th>Telefón</th>';
echo '<th>Akcie</th>';
echo '</tr>';

for($i=0; $i<count($user_list->users); $i++){
echo '<tr>';
echo '<td>'.$user_list->users[$i]->id.'</td>';
echo '<td>'.$user_list->users[$i]->user_name.'</td>';
echo '<td>'.$user_list->users[$i]->user_surname.'</td>';
echo '<td>'.$user_list->users[$i]->age.'</td>';
echo '<td>'.$user_list->users[$i]->role.'</td>';

echo '<td style="white-space: nowrap;">';
echo '<span><b>'.$user_list->users[$i]->main_phone_number.'</b></span><br><br>';

if(count($user_list->users[$i]->all_phone_numbers)){
echo '<div id="numbers_'.$user_list->users[$i]->id.'" style="display:none;">';
foreach($user_list->users[$i]->all_phone_numbers as $index => $value){
echo '<span>'.$value.'</span><br>';
}
echo '</div>';

echo '<a href="javascript:void(0)" onClick="showNumbers('.$user_list->users[$i]->id.')">Zobraziť čísla</a>';
}

echo '</td>';

echo '<td>';
echo '<a href="uprava-zaznamu.php?id_user='.$user_list->users[$i]->id.'">Upraviť záznam</a><br><br>';
echo '<a href="index.php?id_user='.$user_list->users[$i]->id.'" onclick="return showConfirm()">Vymazať záznam</a>';
echo '</td>';

echo '</tr>';
}

echo '</table>';

} else {
echo "0 results were selected.";
}

echo '<br><br>';
?>
</div>

<div class="clear"></div>
</div>

<?php include "footer.php";?>

</div>

<script>
function showNumbers(id){
// alert(id);
document.getElementById('numbers_'+id).style.display ='block';
}

function showConfirm(){
var answer = confirm("Naozaj chcete vymazať daný záznam?");

if(answer){
//vykonanie, ak pouzivatel potvrdi confirm okno - odkaz sa vykona
return true;
}else{
//vykonanie, ak pouzivatel zruzi confirm okno - odkaz sa nevykona
return false;
}
}
</script>

</body>
</html>

Ťažko sa vám učí samému?

Máte problémy s niektorými časťami alebo sa neviete učiť sám? Využite našu možnosť individuálnej asistencie:

  • samostatný prístup
  • vysvetlenie nejasností prebraného učiva
  • úlohy a cvičenia navyše
  • všetko z pohodlia domova cez mail a skype

Pre viac info kliknite tu

Kľúčové slová prednášky

sql injectionutok sqlbezpecnostdatabaza bezpecnostphp sql bezpecnostphp mysql injectionutok databazazabezpecenie databazy

IT ftip

Doktor sa díva na faktúru za inštaláciu počítačovej siete: "Človeče, veď vy si počítate na hodinu ďaleko viac, než my!" "To je normálne. Vy doktori vystačíte so znalosťou jediného systému celý život, ale my sa musíme každy rok učit nejaký nový systém."