ããããã³ã°ã»ã©ãã®ã¤ãããã å®å
¨ç ä»®æ³ç°å¢ã«ãããããã«ã¼ä½é¨å¦ç¿ãã¨ãä½ç³»çã«å¦ã¶ å®å
¨ãªWebã¢ããªã±ã¼ã·ã§ã³ã®ä½ãæ¹ ç¬¬2ç èå¼±æ§ãçã¾ããåçã¨å¯¾çã®å®è·µãï¼éç§°ï¼å¾³ä¸¸æ¬ï¼ãåèã«ãã»ãã¥ãªãã£ã®åå¼·ãé²ãã¦ãã¾ãã
ååã¯ã以å ã«è¡ã£ã OWASP ZAP ã®èªåèå¼±æ§ã¹ãã£ã³ã®çµæã®ãã¯ãã¹ãµã¤ãã¹ã¯ãªããã£ã³ã°ï¼XSSï¼ãã«ã¤ãã¦ãåæã¨å¯¾çã¾ã§ããã¾ããã
ä»åã¯ãSQLã¤ã³ã¸ã§ã¯ã·ã§ã³ãè¦ã¦ããã¾ãã
ããã§ã¯ããã£ã¦ããã¾ãã
åèæç®
ã¯ããã«
ãã»ãã¥ãªãã£ãã®è¨äºä¸è¦§ã§ããè¯ãã£ããåèã«ãã¦ãã ããã
ã»ãã¥ãªãã£ã®è¨äºä¸è¦§
徳丸æ¬ã®ç°å¢æ§ç¯ã«ã¤ãã¦ã¯ã以ä¸ã®ç¬¬9åã§ããã¾ããã
daisuke20240310.hatenablog.com
ã¾ãã徳丸æ¬ãç¨æãã¦ããã¦ãããèå¼±ãªã¢ããªã±ã¼ã·ã§ã³ Bad Todo ã®æºåã«ã¤ãã¦ã¯ã以ä¸ã®ç¬¬12åã§ããã¾ãããä»åã¯ããã®ç°å¢ã使ã£ã¦ãã£ã¦ããã¾ãã
daisuke20240310.hatenablog.com
SQLã¤ã³ã¸ã§ã¯ã·ã§ã³ã®æ¤åºçµæã®ç¢ºèª
ã¾ãã¯ãèå¼±æ§ã¹ãã£ã³ã®ææå
容ãç´°ããè¦ã¦ããã¾ãã
SQLã¤ã³ã¸ã§ã¯ã·ã§ã³ã®èå¼±æ§ã®åæï¼èªè¨¼åé¿ï¼
SQLã¤ã³ã¸ã§ã¯ã·ã§ã³ã®å
é ããè¦ã¦ããã¾ãã1ã¤ç®ã¯ãAuthentication Bypass ã¨ããã¾ãããã°ã¤ã³ã«ã¯èªè¨¼ãå¿
è¦ã§ããããããåé¿ã§ãã SQLã¤ã³ã¸ã§ã¯ã·ã§ã³ãæå¹ã ã£ããã¨ãããã¨ã ã¨æãã¾ãã
SQLã¤ã³ã¸ã§ã¯ã·ã§ã³ã®èªè¨¼åé¿ã®ææ
ãã°ã¤ã³ç»é¢ã® id ã®ã¨ããã«ãã¦ã¼ã¶ID ãå
¥åï¼daisukeï¼ã®ä»£ããã«ãdaisuke' AND '1'='1' -- ãå
¥åããã¨ããã¹ã¯ã¼ããå
¥åããªãã¦ãããã°ã¤ã³ã§ããã¨ãããã¨ã§ããããã
ææã®2ã¤ç®ã¯ã1ã¤ç®ã¨åãå
容ã§ããã
ææã®3ã¤ç®ã¯ãåãåæã§ãããæ»ææ¹æ³ãéãããã§ããã対çå
容ã¯åãã«ãªãããã§ãã
SQLã¤ã³ã¸ã§ã¯ã·ã§ã³ã®ä»ã®ææ
SQLã¤ã³ã¸ã§ã¯ã·ã§ã³ã®èå¼±æ§ã®åç¾ï¼èªè¨¼åé¿ï¼
ã¾ãã¯ã試ãã¦ã¿ã¾ããã¦ã¼ã¶ID ã«ã¯æ»æã®æååãå
¥åãã¦ããã¹ã¯ã¼ããé©å½ãªæååãå
¥ãã¦ããã°ã¤ã³ãã¦ã¿ã¾ãã
æ»ææååãå
¥åãã¦ãã°ã¤ã³
ãã¾ããã£ã¦ãªãæ°ããã¾ãã
æ»æå¤±æ
logindo.php ã®ã½ã¼ã¹ã³ã¼ãã確èªãã¾ããSQLæã2åå®è¡ããã¦ãã¾ãããã®2åããã¾ãããã¨ãã°ã¤ã³ã§ãããã§ãã
<?php
require_once './common.php';
if (! isset($_POST['userid']) || ! isset($_POST['pwd']) || ! isset($_POST['url'])) {
exit;
}
try {
$dbh = dblogin();
$userid = filter_input(INPUT_POST, 'userid');
$pwd = substr($_POST['pwd'], 0, 6);
$url = filter_input(INPUT_POST, 'url');
$sql = "SELECT id, userid FROM users WHERE userid='$userid'";
$sth = $dbh->query($sql);
$row = $sth->fetch(PDO::FETCH_ASSOC);
$sth = null;
if (! empty($row)) {
$sqlstm = "SELECT id, userid, super FROM users WHERE userid='$userid' AND pwd='$pwd'";
$sth = $dbh->query($sqlstm);
$row = $sth->fetch(PDO::FETCH_ASSOC);
if (! empty($row)) {
$_SESSION['login'] = true;
$user = new User($row['id'], $userid, $row['super']);
setcookie('USER', serialize($user), 0, '/');
header('Location: ' . $url . '?' . SID);
} else {
e("ãã¹ã¯ã¼ããéãã¾ã");
exit;
}
} else {
e("ãã®ã¦ã¼ã¶ã¼ã¯ç»é²ããã¦ãã¾ãã");
exit;
}
} catch (PDOException $e) {
die('æ¥ç¶ã«å¤±æãã¾ãã: ' . $e->getMessage());
}
?>
以ä¸ã®2æã§ããæ»æã¯ daisuke' AND '1'='1' -- ã§ãã
<?php
$sql = "SELECT id, userid FROM users WHERE userid='$userid'";
$sqlstm = "SELECT id, userid, super FROM users WHERE userid='$userid' AND pwd='$pwd'";
ã¾ããæ»æã§ä½¿ããã¦ãã -- ã¯ãSQLã§ã¯ã³ã¡ã³ãã®éå§ãæå³ãã¾ãã以éãç¡è¦ããããã¨ããããã§ãã
ã¤ã¾ãããã¹ã¯ã¼ãã®ã¨ãããã³ã¡ã³ãã¢ã¦ããã¦ã代ããã« AND '1'='1' ãå
¥ãã¦ããã¨ãããã¨ã®ããã§ãã
ããããæ»æã¯ãã¾ããã£ã¦ãã¾ãããã ãã¶æ©ãã ã®ã§ãããåããã¾ãããæ»æããã¨ãããã©ã¦ã¶ã«ã¨ã©ã¼ã表示ããã¦ãã¾ããããã¯ææ³ã¨ã©ã¼ãåºã¦ãã¾ã£ã¦ãã¾ãããããè§£æ¶ããå¿
è¦ãããã¾ãã
ã§ã¯ãã©ãã«åé¡ãããã®ãã¨ããã¨ãSQL ã®ã³ã¡ã³ãã¯ã-- ã®å¾ã«åè§ã¹ãã¼ã¹ãå¿
è¦ãããã§ãï¼MySQL ã ããããï¼ï¼ãç¥ããããªãã¨è¨ããããªããããªå
容ã§ããããã¼ã¿ãã¼ã¹ãæ±ãã«ã¯å¸¸èãªãã§ãããããã ãã¶æéãããã£ã¦ãã¾ãã¾ããã
ã§ã¯ãæ°ãåãç´ãã¦ãdaisuke' AND '1'='1' -- ã§ãæ»æãè¡ãã¾ããè¦ãç®ãä¸ç·ãªã®ã§åããã«ããã§ããã-- ã®å¾ã«ãåè§ã¹ãã¼ã¹ãå
¥ããã¦ãã¾ãã
æ»ææååï¼æ¹ï¼ãå
¥åãã¦ãã°ã¤ã³
é©å½ãªãã¹ã¯ã¼ãã§ããã°ã¤ã³ã§ãã¾ãããã¦ã¼ã¶åãå¤ãªè¡¨ç¤ºã«ãªã£ã¦ãã¾ãããæ®éã«æä½ã§ãã¾ããèªåã®ä½ã£ã Todo ãåé¤ãã¦ã¿ãã¨ãæ®éã«åé¤ã§ãã¾ããã
æ»ææååï¼æ¹ï¼ã§ãã°ã¤ã³ã§ãã
SQLã¤ã³ã¸ã§ã¯ã·ã§ã³ã®èå¼±æ§ã®å¯¾çï¼èªè¨¼åé¿ï¼
ããã§ã¯å¯¾çãèãã¦ããã¾ãã
SQLã¤ã³ã¸ã§ã¯ã·ã§ã³ã®å¯¾çã¯ããã¬ã¼ã¹ãã«ãã使ãã°ããã¨ã®ãã¨ã§ãã
ãã¬ã¼ã¹ãã«ãã«ã¯ãéçãã¬ã¼ã¹ãã«ãã¨åçãã¬ã¼ã¹ãã«ããããã徳丸æ¬ã§ã¯ãåçãã¬ã¼ã¹ãã«ãã§ããSQLã¤ã³ã¸ã§ã¯ã·ã§ã³ã¯å¯¾çã§ããããéçãã¬ã¼ã¹ãã«ããæ¨å¥¨ãã¦ãã¾ããã
éçãã¬ã¼ã¹ãã«ãã¯å®è£
ãå¢ããã®ã§ãä»åã¯åçãã¬ã¼ã¹ãã«ãã§å¯¾çãè¡ãããã¨æãã¾ãã
2æãã SQLæã®ãã¡ãæåã® SQLæã®å¯¾çã§ããã¾ãã対çåã§ãã
<?php
$sql = "SELECT id, userid FROM users WHERE userid='$userid'";
$sth = $dbh->query($sql);
$row = $sth->fetch(PDO::FETCH_ASSOC);
$sth = null;
次ã«ã対çå¾ã§ãã? ããã¬ã¼ã¹ãã«ãã§ãSQLæã確å®ãããå¾ã«ãbindValue() ã§ãå¤ãè¨å®ããã®ã§ãå®å
¨ã¨ãããã¨ãããã§ãããã¬ã¼ã¹ãã«ãã使ã£ãå ´åããªãããquery() ã§ã¨ã©ã¼ãåºãããã«ãªã£ãã®ã§ãprepare() 㨠execute() ãä½¿ãæ¹ã«å¤æ´ãã¾ããã
<?php
$sql = $dbh->prepare("SELECT id, userid FROM users WHERE userid = ?");
$sql->bindValue(1, $userid, PDO::PARAM_STR);
$sql->execute();
$row = $sql->fetch(PDO::FETCH_ASSOC);
$sql = null;
ç¶ãã¦ããã1ã¤ã® SQLæã§ããã¾ãã対çåã§ãã
<?php
$sqlstm = "SELECT id, userid, super FROM users WHERE userid='$userid' AND pwd='$pwd'";
$sth = $dbh->query($sqlstm);
$row = $sth->fetch(PDO::FETCH_ASSOC);
次ã«ã対çå¾ã§ããbindValue() ã®ç¬¬1弿°ã¯ãä½çªç®ã®ãã¬ã¼ã¹ãã«ãããæå®ï¼1å§ã¾ãï¼ã§ã第2弿°ã夿°ã第3弿°ã夿°ã®åã§ãã
<?php
$sqlstm = $dbh->prepare("SELECT id, userid, super FROM users WHERE userid = ? AND pwd = ?");
$sqlstm->bindValue(1, $userid, PDO::PARAM_STR);
$sqlstm->bindValue(2, $pwd, PDO::PARAM_STR);
$sqlstm->execute();
$row = $sqlstm->fetch(PDO::FETCH_ASSOC);
ã¨ããããã®å¯¾çã¯åºæ¥ãã¨æãã¾ããæ®éã«åä½ãããã¨ã確èªãã¾ããã
logindo.php ã®ä¿®æ£ç¹ãè²¼ã£ã¦ããã¾ãã
--- todo.org/logindo.php 2018-08-15 15:29:23.000000000 +0900
+++ todo.change/logindo.php 2024-08-15 17:12:00.000000000 +0900
@@ -1,20 +1,27 @@
<?php
require_once './common.php';
+ if (! isset($_POST['userid']) || ! isset($_POST['pwd']) || ! isset($_POST['url'])) {
+ exit;
+ }
try {
$dbh = dblogin();
$userid = filter_input(INPUT_POST, 'userid');
$pwd = substr($_POST['pwd'], 0, 6);
$url = filter_input(INPUT_POST, 'url');
- $sql = "SELECT id, userid FROM users WHERE userid='$userid'";
- $sth = $dbh->query($sql);
- $row = $sth->fetch(PDO::FETCH_ASSOC);
- $sth = null;
+ $sql = $dbh->prepare("SELECT id, userid FROM users WHERE userid = ?");
+ $sql->bindValue(1, $userid, PDO::PARAM_STR);
+ $sql->execute();
+ $row = $sql->fetch(PDO::FETCH_ASSOC);
+ $sql = null;
if (! empty($row)) {
- $sqlstm = "SELECT id, userid, super FROM users WHERE userid='$userid' AND pwd='$pwd'";
- $sth = $dbh->query($sqlstm);
- $row = $sth->fetch(PDO::FETCH_ASSOC);
+ $sqlstm = $dbh->prepare("SELECT id, userid, super FROM users WHERE userid = ? AND pwd = ?");
+ $sqlstm->bindValue(1, $userid, PDO::PARAM_STR);
+ $sqlstm->bindValue(2, $pwd, PDO::PARAM_STR);
+ $sqlstm->execute();
+ $row = $sqlstm->fetch(PDO::FETCH_ASSOC);
if (! empty($row)) {
+ error_log("row[id]=" . $row['id'] . ", row[super]=" . $row['super']);
$_SESSION['login'] = true;
$user = new User($row['id'], $userid, $row['super']);
setcookie('USER', serialize($user), 0, '/');
èªåèå¼±æ§ã¹ãã£ã³ã®åå®è¡
ã§ã¯ã対çããã®ã§ãèªåèå¼±æ§ã¹ãã£ã³ãåå®è¡ãã¦ã¿ããã¨æãã¾ãã
SQLã¤ã³ã¸ã§ã¯ã·ã§ã³ã®èµ¤ãã©ã°ã¯ç¡ããªãã¾ããã赤ã®ãã©ã°ã¯ãªã¹ã¯é«ã§ããããã¨3ã¤ã«ãªãã¾ããããã¡ã2ã¤ã¯ããåãããªãã®ã§ããã¨ã¯ãExternal Redirect ã ãã§ãã
èªåèå¼±æ§ã¹ãã£ã³ã®åå®è¡ã®çµæ
External Redirect ã¯ã徳丸æ¬ã§ã¯ããªã¼ãã³ãªãã¤ã¬ã¯ãèå¼±æ§ã¨ãã¦èª¬æããã¦ãã¾ãããã¡ãã®å¯¾çã¯æ¬¡åã¨ãããã¨æãã¾ãã
ãããã«
ä»åã¯ãSQLã¤ã³ã¸ã§ã¯ã·ã§ã³ã®èå¼±æ§ã«ã¤ãã¦ãåç¾ã¨å¯¾çãè¡ãã¾ãããä»åã¯ãã£ããã¨ææãæ¶ãã¦ããã¦è¯ãã£ãã§ãã
次åã¯ããªã¼ãã³ãªãã¤ã¬ã¯ããè¦ã¦ããããã¨æãã¾ãã
ä»å㯠wasbook ã§ä½¿ããã¦ãã MySQL ã®ãã´ã使ããã¦ããã ãã¾ããããããã¨ããããã¾ãã
æå¾ã«ãªãã¾ããããã¨ã³ã¸ãã¢ã°ã«ã¼ãã®ã©ã³ãã³ã°ã«åå ä¸ã§ãã
æ°æ¥½ã«ãããã¨ãããããé¡ããããã¾ãð
ä»åã¯ä»¥ä¸ã§ãï¼
æå¾ã¾ã§ãèªã¿ããã ãããããã¨ããããã¾ããã