2012-05-26 6 views
3

Я использовал MySQL раньше, и мне сказали, что это небезопасно, так что теперь я перекодировал панель входа администратора в PDO, которую пользователи здесь и другие форумы не могут быть введены. Но хакер все еще попадает ... Я редактировал страницу после входа в систему и сказал взломанному, чтобы рассказать мне, что я надел, и хакер сказал мне ...Является ли мой код безопасным для инъекций?

Мне нужно знать, мой код безопасно. Он говорит мне, что он входит в SQL.

Итак, сначала я сохранил свой IP во время сеанса, так что если изменения их IP он будет регистрировать их (или имя пользователя)

if (isset($_SESSION['last_ip']) == false) 
{ 
    $_SESSION['last_ip'] = $_SERVER['REMOTE_ADDR']; 
} 
if ($_SESSION['last_ip'] !== $_SERVER['REMOTE_ADDR']) 
{ 
    session_unset(); 
    session_destroy(); 
} 

Тогда вот мой Логин:

session_start(); 
include 'functions/functions.php'; 
$db = mysqlconnect(); 
$password = md5($_POST['mypassword']); 
$mod = 1; 
$statement = $db->prepare("SELECT * FROM users WHERE username = ? AND password = ?"); 
$statement->execute(array($_POST['myusername'],$password)); 
$result = $statement->fetchObject()->mod; 
$count = $statement->rowCount(); 
if ($result == 1) { 
    $db = mysqlconnect(); 
    // Register $myusername, $mypassword and redirect to file "login_success.php" 
    $_SESSION['user'] = $_POST['myusername'] ; 
    //Test if it is a shared client 
    if (!empty($_SERVER['HTTP_CLIENT_IP'])) { 
     $ip=$_SERVER['HTTP_CLIENT_IP']; 
     //Is it a proxy address 
    } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { 
     $ip=$_SERVER['HTTP_X_FORWARDED_FOR']; 
    } else { 
     $ip=$_SERVER['REMOTE_ADDR']; 
    } 
    $sqll = "UPDATE users SET lastip=? WHERE username=?"; 
    $q = $db->prepare($sqll); 
    $q->execute(array($ip,$_SESSION['username'])); 
    $_SESSION['user'] = $_POST['myusername'] ; 
    $sqlll = "INSERT INTO user_log (username,ip) VALUES (?, ?)"; 
    $qq = $db->prepare($sqlll); 
    $qq->execute(array($_SESSION['username'],$ip)); 
    header("Location: home.php"); 
} else { 
    echo "Wrong Username or Password"; 
} 

Может код вводиться?

И это моя страница home.php, которая не позволяет пользователям просматривать его.

/// My conenct is here      
$sql = "SELECT * FROM users WHERE username='$_SESSION[user]'"; 
$result = mysql_query($sql) or die(mysql_error()); 
$values = mysql_fetch_array($result); 


if(isset($_SESSION['user'])) { 

} else { 
    echo "Bye Bye"; 
    die; 
} 

if ($values['mod'] == 1) {  
    echo "welcome"; 
} else { 
    echo"Your account has been reported for hacking"; 
    die; 
} 
+1

Вы должны проверить правильность форматирования '$ _POST ['myusername']' перед его использованием в SQL. Простой 'preg_match()' должен быть достаточным или вы могли бы сбежать от него к другой переменной, а затем выполнить поиск переменной. Кроме того, откуда происходит '$ _SERVER ['HTTP_CLIENT_IP']? – ghoti

+0

Я думал, что в pdo вам не нужно форматировать переменные? – user1405062

+0

Что делает хакер? Почему вы говорите «он попадает», и почему вы думаете, что это SQL-инъекция? – Robbie

ответ

-1

Хороший SQL Injection предупреждение было бы избежать любого и весь текст, который может быть использован для завершения команды SQL в середине оценки, чтобы начать новую команду.

Чтобы сделать это, вы должны экранировать все кавычки в входе, и использовать лучшие SQL — использования кавычку вокруг полей и имен таблиц, используйте кавычки, чтобы обернуть любой текст без кода и т.д.

SELECT * FROM `users` WHERE `id` = '1' 

Тогда избежать все котировки с mysql_real_escape_string или с помощью ручных замен # 039; и т. д., также, чтобы убежать от любого HTML, чтобы убедиться, что он не испортит другие вещи, используйте htmlentities и т. д.

+3

Точка PDO заключается в том, что вам не нужно это делать. Напишите свой запрос с помощью _placeholders_, подготовьте его, затем выполните его с переданными данными, которые автоматически экранируются драйвером PDO. – Bojangles

+0

вам не нужно использовать pdo, если вы просто используете mysql_real_escape_string, 'и 'и некоторую проверку типов на ожидаемых вами данных. также используя скобки() вокруг частей вашего запроса. проверьте, является ли возвращаемый результат тем, что вы хотите, если нет, die() – Tschallacka

+0

В моей собственной структуре SQL я просто избегаю данных, прежде чем я когда-либо помещал их в базу данных примерно с 3-4 различными способами. Я всегда проверяю свои сайты на SQL Injection, и они никогда не работают. – casraf

1

Предполагая, что запросы, которые вы показываете, являются единственными запросами, которые вы используете, смешно, как хакер использует сам код вы думали, что он его заблокирует. Очень часто в мире ИТ входная дверь тройная, но бэкдор открыт. В этом случае это не бэкдор, а маленькое окно в дверь, которое вы используете, чтобы увидеть, не открываете ли вы мошеннику.

Использовать подготовленные операторы и привязки переменных по всем запросам.

Это общее правило. Вы просто забыли «все» в «всех запросах».

Ваше утверждение:

$sql = "SELECT * FROM users WHERE username='$_SESSION[user]'"; 

Ваше открытое окно. Совершенно очевидно, что ваш хакер подделал имя пользователя в данных сеанса. Простое решение заключается в следующем:

  1. проверки имени пользователя или каких-либо данных, которые вы получите от внешних ($ _SESSION, $ _POST, $ _SERVER некоторые и другие), прежде чем делать что-нибудь с ним. Разумеется, прежде чем выполнять какое-либо взаимодействие с базой данных.
  2. используйте переменное связывание, как и в других запросах.

Удаление меток или использование mysql_real_escape_string в этом случае имеет меньшее значение, потому что взлом вполне возможен без каких-либо неустойчивых символов.

Кстати, вам не нужно использовать PDO для использования привязки переменных. Это вполне возможно и в mysql.

$verbLok = mysqli_connect(Iam, not, gonna, tellyou); 
$result = array(); 
if (($stmtLok = $verbLok->prepare("SELECT * FROM users WHERE username = ? limit 1"))) 
{   
    $stmtLok->bind_param("s", $_SESSION[user]); 
    $stmtLok->execute(); 
    $result = $stmtLok->get_result(); 
    $stmtLok->close(); 
} 
mysqli_close($verbLok); 

должен сделать трюк для вас. $ result будет содержать массив строк результатов. Я больше не знаком с обычными запросами, но насколько я помню, он похож на ваш код.

Интересное чтение о том, как возможно инъекция SQL-кода в вашем запросе, можно найти on this page.

Смежные вопросы