Katika somo hili nitakwenda kukufundisha kuhusu php sql injection. Somo hili tutaangalia kwa ufupi kuhusu sql injection na jinsi ya kuweza kuizuia. Somo hili ni muenelezo wa masomo yetu kadhaa yaliyozungumzia usalama. Masomo mengine ni kama matumiazi ya htaccess, matumizi ya hashing, na encription pamoja na decription. Somo hili nitakuonyesha hatari ya sql injection.
Sql injection ni nini?
Hizi ni code shambulizi la kimtandao ambalo hufanyika kwa kuingiza sql statement kwenye ukurasa ambao mtumiaji huweka taarifa fulani. Kwa mfano ukurasa wa ku log in mtumiaji anatakiwa kuweka jina na password yake. Sasa hacker yeye ataweza code flani na kulog in bila ya kujisajili. Kwa mfano badala ya kuingiza jina na password mtumiaji anaweza kuingina '--'OR 1-1 hapo akafanikiwa ku log ina moja kwa moja.
Baadhi ya sql code zinazofanya injection
-
OR 1=1
-
–’ AND ..
-
‘) OR 1=1-]
-
“OR “”=”
-
“OR=”
-
1=1
-
UNION SELECT
-
DROP TABLE
Endapo mshambuliaji wa kimtandano (hacker) atafanikiwa kufanya injection anaweza kufanya mambo mengi hatari kama:-
-
Kufuta table ama database yote
-
Kufuta data
-
Kulogin
-
Kupata taarifa za watumiaji
-
Kuedit data
Takwimu zinaeleza kuwa sql injection ni moja kati ya njia kuu 10 ambazo hutumiwa katika ku hack. Ni miaka 20 sasa imepita toka sql injection ijulikane lakini mpaka leo bado ma hacker wanagunduwa mbinu mpya za ku hack kw akutumia njia hii. Takwimu zinaonyesha kuwa asilimia 47 ya mashambulizi ya kimtandao ya ku hack husababishwa hutokana na sql injection.
AINA ZA SQL INJECTION
-
In- band sql injection
Hii ni aina ya injection aambapo attack hufanyika kupitia error message ambayo hutokea kwenye web endapo kuna kitu hakipo sawa, ama kwa kutumia UNION oparator hivyo kuzuia aina hii ni vyema kila error za kwenye database yako usifanye za kawaida. Mfano iwe inaleta maneno ya kawaida kama “kuna hitilafu tafadhali jaribu tena” lakini kama error zinakuja zile za sql yenyewe mfano hiyo hapo chini
-
Out-band sql injection
Hii ni injection ambayo hufanyika kupitia HTTP, DNS au SMB. Kuzuia attack hii vyema kuwa makini wakati wa kusafirisha data kwenye hizi protocal. Kwa mfano kuwa makini wakati wa kusafirisha data kwenye parameter. Vyema kama hakuna ulazima kutumia POST method.
WAPI INJECTION HUTOKEA
Ujumla wa maneno ni kuwa statement yote ya sql ipo hatarini ila kuna maeneo ambayo yapo hatarini sana kuwa ndio chanzo cha attack nyingi zinazotokea. Kwa kiasi kikubwa attack hutokea kwenye WHERE na kwenye SELECT hata hivyo zinaweza pia kutokea kwenye
-
UPDATE
-
INSERT
-
ORDER BY
NJIA ZA KUZUIA SQL INJECTIONS
Sio kitu rahisi kwa programmer kuwa mkamilifu kwa maana code zake zisiwe na makosa. Hvyo basi ni vyema kujuwa hizi njia zitakusaidia kuweka tahadhari. Njia hizo ni kama
-
Parameterized queries
-
Sanitizing
-
validating
Katika somo hili tutakwenda kuangalia njia hizi moja baada ya njingine kw avitendo. Kwa kuwa tumeshajifunza jinsi ya ku sanitize na ku validate haitakuwa vigumu kuzifanyia kazi kwenye somo hili. Hata hivyo hapa nitafundisha hasa kuhusu hii parameterized Querry kwa kuwa tulisha jifunz akuhusu sanitizing na validating kwenye masomo yaliopita.
MAREJEO
Kusoma zaidi kuhusu somo hili tembelea website hizi:-
https://www.acunetix.com/websitesecurity/sql-injection/
https://www.javatpoint.com/sql-injection
https://www.invicti.com/blog/web-security/sql-injection-cheat-sheet/
https://www.guru99.com/learn-sql-injection-with-practical-example.html
Exploiting SQL Injection: a Hands-on Example | Acunetix
Prevent SQL injection vulnerabilities in PHP applications and fix them (acunetix.com)
https://geekflare.com/open-source-web-security-scanner/
MAFUNZO KWA VITENDO:
Sasa ndio tunakwnda kufanyia kazi ambacho tumekisoma hapo juu. Wacha tuone hatari ya injection. Katika somo hili tutakwenda kutengeneza simple login system ambayo ni rahisi kufanya injection. Tutaona kwa ufupi jinsi injection zinavyofanya kazi kisha tutaangalia jinsiya kuiboresha system yetu ki usalama.
-
Tengeneza database yenye jina sql. Kisha tengeneza table yenye jina users. Unaweza kutumia xode hizi
CREATE TABLE `users` (
`id` int(11) NOT NULL,
`username` varchar(50) NOT NULL,
`email` varchar(50) NOT NULL,
`password` varchar(255) NOT NULL,
`status` int(1) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Kumbuka kuweka id kuwa Auto Increment. Kisha ingiza data hizi
INSERT INTO `users` (`id`, `username`, `email`, `password`, `status`) VALUES
(5, 'chogozo', 'chogozo@gmail.com', 'chogozo@123', 1),
(6, 'kilimozo', 'kili@gmail.com', 'kili@321.com', 1),
(7, 'kilimozo', 'kili@gmail.com', 'e6e061838856bf47e1de730719fb2609', 1),
(8, 'mkwayu', 'admin@wikibongo.com', '0192023a7bbd73250516f069df18b500', 1);
Kwanza kabisa tengeneza folda liite web ndai ya folda hilo utatengeneza mafaili kadhaa kama nitakavyokutajia hapo chini.
-
Tengeneza faili liite registration.php kisha weka htlm form kwa ajili ya kujisajili. Tumia code hizi
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Registration form</title>
</head>
<body>
<form method="post" action="reg_script.php">
<label for="name">User Name</label><br>
<input type="text" id="name" placeholder="write your name" name="name"><br><br>
<label for="email">Email</label><br>
<input type="email" id="email" placeholder="write your email" name="email"><br><br>
<label for="password">Password</label><br>
<input type="password" id="password" placeholder="write your password" name="password"><br><br>
<input type="submit" value="Register">
</form>
</body>
</html>
-
Tengeneza faili lingine liite reg_script.php hili litafanyia kazi hiyo registration form. Weka code hizi:-
<?php
include 'config.php';
//prepare variable
$name = ($_POST['name']);
$email = ($_POST['email']);
$password = ($_POST['password']);
$hashed_password = md5($password);
//insert data in database
$sql = "INSERT INTO users (username, email, password, status)
VALUES ('$name', '$email', '$hashed_password', 1)";
/** @var TYPE_NAME $conn */
if (mysqli_query($conn, $sql)) {
header("location: login.php");
} else {
echo "Error: " . $sql . "
<br>" . mysqli_error($conn);
}
mysqli_close($conn);
?>
-
Sasa tengeneza faili liite config.php hili ndilo la kuunganisha database. Weka code hizi
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "sql";
// Kufanya connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Kuangalia connection
if (mysqli_connect_error()) {
die("you are not connected: " . mysqli_connect_error());
}
?>
-
Tengeneza faili lingine la login.php kisha weka code hizi
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Login form</title>
</head>
<body>
<form method="post" action="login-script.php">
<label for="name">User Name</label><br>
<input type="text" id="name" placeholder="write your name" name="name"><br><br>
<label for="password">Password</label><br>
<input type="text" id="password" placeholder="write your password" name="password"><br><br>
<input type="submit" value="Login">
</form>
</body>
</html>
-
Sasa tengeneza faili lingine liite login-script.php hili ni kwa ajili ya kuchakata code za ku log in.
<?php
session_start();
include 'config.php';
//prepare variable
$name = ($_POST['name']);
$password = ($_POST['password']);
$hashed_password = md5($password);
/** @var TYPE_NAME $conn */
$sql = mysqli_query($conn, "SELECT * FROM `users` where username ='$name'");
while($fetch = mysqli_fetch_array($sql)){
?>
<?php
//session start
$_SESSION['username'] = $name;
// go to dashboard
header("location: dashboard.php");
?>
<?php }
-
Tengeneza faili liite session.php kisha weka code hizi
<?php
//Start the session
session_start();
Tengeneza faili liite logout.php kisha weka code hizi
<?php
//Start the session
session_start();
session_destroy();
header("location: login.php");
-
Tengeneza faili liite dashboard.php kisha wweka code hizi
<?php
include 'config.php';
include 'session.php';
?>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Dashboard</title>
</head>
<body>
<?php
//kwa ajili ya kuangalia kama session imeanzishwa
if(!isset($_SESSION['username'])):
?>
<b><a class="btn btn-primary btn-lg" href="login.php">Login</a></b>
<?php else: ?>
<?php
$p = $_SESSION['username'];
echo $p;
?>
<?php include 'menu.php';?>
<style>
table {
width: auto;
border-collapse: collapse;
margin: 10px auto;
}
th,
td {
height: 50px;
vertical-align: center;
border: 1px solid black;
}
</style>
<table>
<th>ID</th>
<th>name</th>
<th>Email</th>
<th>View</th>
<?php
/** @var TYPE_NAME $conn */
$file = mysqli_query($conn, "SELECT * FROM `users`");
while($fetch = mysqli_fetch_array($file)){
?>
<tr>
<td><?php echo $fetch['id']; ?></td>
<td><?php echo $fetch['username']; ?></td>
<td><?php echo $fetch['email']; ?></td>
<td><a href="view.php?id=<?php echo $fetch['id']; ?> ">view</a> </td>
</tr>
<?php }?>
</table>
<?php endif; ?>
</body>
</html>
-
Tengeneza faili lingine liite profile.php kisha weka code hizi
<?php
include 'config.php';
include 'session.php';
?>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Dashboard</title>
</head>
<body>
<?php
if(!isset($_SESSION['username'])):
?>
<b><a class="btn btn-primary btn-lg" href="login.php">Login</a></b>
<?php else: ?>
<?php
$username = $_SESSION['username'];
?>
<?php include 'menu.php';?>
<style>
table {
width: auto;
border-collapse: collapse;
margin: 10px auto;
}
th,
td {
height: 50px;
vertical-align: center;
border: 1px solid black;
}
</style>
<table>
<?php
/** @var TYPE_NAME $conn */
$file = mysqli_query($conn, "SELECT * FROM `users` where username='$username'");
while($fetch = mysqli_fetch_array($file)){
?>
<tr><th>Id<td><?php echo $fetch['id']; ?></td></th></tr>
<tr><th>Name<td><?php echo $fetch['username']; ?></td></th></tr>
<tr><th>Email<td><?php echo $fetch['email']; ?></td></th></tr>
<?php }?>
</table>
<?php endif; ?>
</body>
</html>
-
Tengeneza faili lingine liite view.php hili ni kwa ajili ya kusoma taarifa za waliojisajili.
<?php
include 'config.php';
include 'session.php';
?>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Dashboard</title>
</head>
<body>
<?php
if(!isset($_SESSION['username'])):
?>
<b><a class="btn btn-primary btn-lg" href="login.php">Login</a></b>
<?php else: ?>
<?php
$p = $_SESSION['username'];
$id = $_GET['id'];
?>
<?php include 'menu.php';?>
<style>
table {
width: auto;
border-collapse: collapse;
margin: 10px auto;
}
th,
td {
height: 50px;
vertical-align: center;
border: 1px solid black;
}
</style>
<table>
<?php
/** @var TYPE_NAME $conn */
$file = mysqli_query($conn, "SELECT * FROM `users` where id=$id");
while($fetch = mysqli_fetch_array($file)){
?>
<tr><th>Id<td><?php echo $fetch['id']; ?></td></th></tr>
<tr><th>Name<td><?php echo $fetch['username']; ?></td></th></tr>
<tr><th>Email<td><?php echo $fetch['email']; ?></td></th></tr>
<?php }?>
</table>
<?php endif; ?>
</body>
</html>
Unaweza kujisajili kisha u login. Ama tumia data ambazo nimeingiza.
Username ni mkwayu
Password ni admin123
Kama utajiingiza taarifa sahihi kwenye log in utapelekwa kwenye dashboard. Ambapo utaona list ya waliojisajili. Kwenye dashboard kuna menu ambapo utaweweza kuona taarifa biafsi kwenye profile au utaweza kusoma taarifa za mtumiaji moja mmoja kwa kubofya view. Pia ukibofya logout session itastop na utarudishwa tena kwenye ukurasa wa ku login.
Sasa muda wa kufanya sql injection.
Ingia kwenye ukursasa wa ku login kisha kwenye username weka '--'OR 1-1 na kwenye password weka chochote unachotaka unaweza kueka neno bongoclass
Hapo moja kwa moja utafanikiwa ku log in. tayari umefanikiwa ku hack website na upo kwenye dashboard. Utaona jina uliloweka linaonekana kama ndio jina lako.
Kwa kuwa umefanikiwa ku log in unaweza kusoma taarifa ambazo zipo bila ya ruhusa. Kuna list ya watu waliojisajili hapo unaweza kuiingia.
Kwa username ulioweka endapo utabofya profile utaweza kuona taarifa za waliojisajili wote. Kwa kuwa username yako ulioweka ni sql injection hivyo imesha athiri ufanyaji kazi wa kawaida wa web yetu.
Rudi kwenye users kwenye menu utapelekwa kwenye list ya watliojisajili. Sasa bofya mmojawapo. Utapelekwa kwenye ukurasa wa view ambao ndo unasoma taarifa za watumiaji ila kw ammoja mmoja. Kwa mfano ukibofya view kwenye jina chogozi mwenye ID namba 5 utaletewa taarifa hizi
Sasa angalia vyema kwenye url utaona link inasomeka hivi http://localhost/web/view.php?id=5
Hiyo link hapo ipo hatariri maana inaruhusu injection. Kwa mfano ongeza maneno haya mbele ya hiyo link OR 1=1 hivyo link itasomeka hivi http://localhost/web/view.php?id=5 OR 1=1 bofya enter hapo utakuwa umehach hiyo list baada ya kuletewa jina moja utaletewa majina yote ya waliojisajili na taarifa zao.
Ni nini hasa kimetokea kwenye hiyo OR 1=1 au ‘--’OR 1=1
Ufupo wa maneno ni kuwa kwenye log in code zilikuwa zipo hivi SELECT * FROM users WHERE username = $name hii $name ni variable ambapo data zake tunazipata kutoka kwenye log in form.kwa hiyo hapo endapo username itakuwa sawa atapelekwa kwenye dashboard. Sasa kitendo cha kuweka '--'OR 1-1 ina maana sehemu ya code ilobakia ni comment hivyo mtu ataruhusiwa. Kwa kuwa sasa sql code zimebadilishwa.
Kwenye dashboard tumetum OR 1=1 kwa kuwa ki mahesabu 1=1 nii ni true hivyo ukiiweka pale kwenye parameta italeta true, hatimaye kutuletea taarifa zote. Sasa wacha tuone jinsi ya kulinda system yetu hii.
KUZUIA INJECTION KATIKA SQL QUERY
Kuna step unatakiwa uzipitie ili kuweza kuthibiti usalama wa sql querry unayoweka. Step hizo ni kama:-
-
Validate input
Hii ina maana kwanza unatakiwa kuthibitisha input zote ambazo mtumiaji anaingiza kwenye web yako. Kwa mfano kama kisanduku kina hitaji aweke namba basi iwe ni namba tu na sio vingine. Mfano input inahitaji email itakubidi ufanye validation ya hiyo email kama ni kweli ama laa. Rejea mafunzo ya php level 3 somo la 6 bofya hapa
-
Prepare Query
Nitakupa mfano mmoja kwa hizo code ambazo tumetumia hapo juu
$sql = mysqli_query($conn, "SELECT * FROM `users` where username ='$name'");
while($fetch = mysqli_fetch_array($sql)){
?>
<?php
//session start
$_SESSION['username'] = $name;
// go to dashboard
header("location: dashboard.php");
?>
<?php }
Ku prepare quey tutatumia function ya php kwa ajili ya ku prepare query prepare() kisha ndipo sql query yako inafata. Kinachobadilika ni kuwa kwenye where username = “$name” hapa itatubidi tuweke alama ya (?) yaani alama ya kuuliza swali. Ili kwamba thamani yeke tutaweka baadaye wamba hapo tulipoweka alama hiyo tunahitaji nini. Njia hii itasaidia kama mtu atataka ku inject sql query ili afanye hacking atazuiliwa. Hivyo statement yetu itasomeka hivi
$sql = $conn->prepare("SELECT * FROM users where username = ?"); baada ya hapo utaendelea na hatuwa inayofuata.
4. Bind parameter
Sasa utahtajika kuunganisha parameter yako kutoka kwenye hiyo query na thamani ambazo zitaingia kwenye hiyo parameter. Kufanya hivi tutatumia function hii bind_param() ambapo ndani yake tutaweka data zetu pia utahitajika kutaja aina ya hiyo data. Utataja kwa kutumia alama. Mfano
-
i - integer
-
d - double
-
s - string
-
b - BLOB
Kama umeprepare parameter 2 basi na hapa nampo hizo viwakilishi ya aina za data vitakuwa viwili kwa kila parameter. Utaangalia kwenye code nitakazo kutumia. Hivyo code zetu zitakuwa hivi $sql->bind_param("s", $name3);
5. Execute
Hatuwa hii sasa ni pale ambapo tunakwenda ku run code zetu. Tunakwenda kuifanya function yetu ifanye kazi ya ku select data kutoka kwenye database. Kufanya hivi tutatumia excute function ambayo ni execute() kwa mujibu wa code zetu hapo function yetu itakuwa hivi $sql->execute();
6. Fetch data
Sasa kila kitu kipo sawa hatuwa iliobaki ni ku fetch data. Hapa tutatumia funvtion ya get_result() vitu vingine vitakuwa kama ulivyozooea. Code hizo kwa ujumla zitaonekana hivi
$sql = $conn->prepare("SELECT * FROM users where username = ?");
//s ni string, i ni int
$sql->bind_param("s", $name3);
$sql->execute();
$result = $sql->get_result();
while ($row = $result->fetch_assoc()) {
$userId = $row['id'];
$username = $row['username'];
$email = $row['email'];
$saved_password = $row['password'];
$hashed_password = md5($password);
if ($name3 == $username & $saved_password == $hashed_password) {
$_SESSION['id'] = $userId;
$_SESSION['username'] = $name;
//echo "You welcome". $_SESSION['username'];
header("location: dashboard.php");
} else echo "password or user name is incorrect";
}
//kufunga connection
$sql->close();
$conn->close();
}
Mpaka kufikia hapo kwa kiasi tumeweza kuzuia sql injections. Sasa wacha nikueleze kwa urefu marakebisho ambayo nimefanya kwenye hizo code ili kuzifanya ziwe salama.
NENO LA USHAURI:
Somo hili limejikita kwenye sql injection, ila hichi ni kipengele kidogo tu kwenye usalama wa web App. hata hivyo zipo njia nyingi za kitaalamu ku hack web licha ya kuwa na sanitizing ama parametizing. So usiishie hapa unatakiwa usome zaidi, kuanzia huu mwangaza ulioipatahapa.