动态网站安全问题(PHP + MySQL) [英] Dynamic Website Security Questions (PHP+MySQL)

查看:202
本文介绍了动态网站安全问题(PHP + MySQL)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个由PHP和MySQL提供动力的站点(在WAMP服务器上运行)。我目前关心的是关于网站的安全性,但是它没有保存任何用户输入,然后再为任何用户(管理员除外)输出,所以我并不担心XSS。我的主要关注点是针对SQL注入攻击,并保护管理员登录门户免受彩虹表/暴力强制。



1)使用mysql_real_escape_string与sprintf()一起使用可以保护您免受SQL注入?例如,

  $ thing = mysql_real_escape_string($ _ REQUEST ['thing'])
$ query = sprintf * FROM table WHERE thing ='%s',$ thing);
$ result = mysql_query($ query);

这是否足够安全?当然,没有一个系统是完全安全的,但是我知道准备好的语句应该是防止SQL注入的最好办法。但是,如果我的代码足够安全,那么我看不出有理由做出改变。我读到某个地方,默认情况下,mysql_query只允许每个调用一个MySQL查询的安全性原因,是否正确?如果是这样,我的代码看不出有什么注意事项,但如果我的逻辑有缺陷,请让我知道。



2)我正在为该网站写一个管理门户,以便其所有者能够以简单,用户友好的方式在网站(从站点上任何地方没有链接的登录HTML文件)中操纵MySQL数据库。我对这里的安全性的关注是登录过程,由两页组成。首先,收集用户登录信息:

 <!DOCTYPE HTML PUBLIC -  // W3C // DTD XHTML 1.0严格/ / ENhttp://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\"> 
< html xml:lang =enxmlns =http://www.w3.org/1999/xhtmllang =en>
< head>
< title>管理门户< / title>
< meta http-equiv =Content-Typecontent =text / html; charset = utf-8>
< meta name =robotscontent =noindex,nofollow>
< link rel =stylesheettype =text / csshref =http://www.anotherdomain.com/my.css>
< script type =text / javascriptsrc =http://www.anotherdomain.com/my.js>< / script>
< / head>
< form method =postaction =admin / login.php>
< table align =center>
< tr>< th>管理员登录表单< / th>< / tr>
< tr>< td>< / td>< td>< input type =textname =Namesize =30onKeyPress =return aJSFunctionToStopEnterKeyFromWorking(event)> < / TD>< / TR>
< tr>< td>密码< / td>< td>< input type =passwordname =Passwordsize =30onKeyPress =return aJSFunctionToStopEnterKeyFromWorking(event)> < / TD>< / TR>
< tr>< td>< / td>< td>< input type =resetvalue =清除表单> < input type =submitvalue =Login>< / td>< / tr>
< / table>
< / form>

其次,实际登录脚本:

 <?php 
$ inputusername = $ _POST ['Name'];
$ inputpassword = $ _POST ['密码'];

$ username =不明显的用户名;
$ password =至少10个字符长的密码;
$ salt = hash('sha512',我写的奇怪的字符混乱的字符串);

$ hashword = hash('sha512',$ password。$ salt);
$ inputhashword = hash('sha512',$ inputpassword。$ salt);

if($ username == $ inputusername&& $ hashword == $ inputhashword){
session_start();
$ _SESSION ['valid'] = 1;
header('Location:portal.php');
退出;
}
else {echo无效的用户名或密码;}
?>

然后在登录过程之后,每个页面将具有以下内容,以确保管理员已登录:

 <?php 
session_start();
if(!$ _ SESSION ['valid']){header('Location:../admin.html');}
?>
门户页面在这里

由于没有新用户的创建,作为门户的一个用户。我只是想知道这种登录方法对于诸如彩虹表和暴力强制的攻击是多么安全?我假设自从我做了这个哈希和盐都非常大,应该是相当安全的这些类型的攻击,即使用户名是某种方式是一个已知的。



我也是想知道这是否安全的会话劫持,因为这是一个术语,我听到扔过,但我不知道很多...我知道我没有扔一个会话ID或任何类似的东西,所以它似乎很安全。



3)我应该知道/想想的任何其他安全问题?



我真的很感激任何帮助我得到这个!

解决方案

其他要考虑的点:



<强> 1。你很容易遭受暴力



字典攻击会破解您的密码。由于绝大多数用户都有不安全的密码,这只是时间问题。使用验证码或日志无效的条目。或者在密码不正确时添加一些延迟。



正如Colle Shrapnel所说,彩虹表不是你所关心的,因为当有人拥有一堆的哈希和想要破解他们。盐被用来获得对彩虹台的一些保护,这不是你的情况。



2。您正在以明文方式发送密码



如果有人嗅探您的登录信息(例如WiFi),您将注定失败。有一些javascript库可以使用公钥加密任何东西。如果您不想使用SSL,请加密登录/密码,发送到服务器,使用私钥进行解密,并且您更安全。



3 。考虑在MySQL上使用准备语句



使用准备语句有助于防止SQL注入,因为即使使用恶意输入也可以安全运行:

  $ dbc = new mysqli(mysql_server_ip,mysqluser,mysqlpass,dbname); 
$ statement = $ db_connection-> prepare(SELECT * FROM table WHERE thing ='?');
$ statement-> bind_param(i,$ thing);
$ statement-> execute();

4。不要在客户端验证中继续



在您的登录表单上,您可以继续使用JavaScript功能,防止Enter键发挥作用。如果我禁用Javascript怎么办?您可以使用隐藏的字段(例如< input type ='hidden'name ='FormIsValid'value ='0'>),使用您的函数来阻止Enter键,并使用onSubmit()函数将FormIsValid更改为1在发送表单之前。在您的服务器中,验证FormIsValid。



5。你很容易遭受会话劫持



您的会话保存在Cookie上,默认名为PHPSESSID。如果攻击者可以获取该cookie,那么它可以将其发送到您的服务器并窃取您的会话。为了防止这种情况,您可以将用户IP地址和用户代理保存在会话中,并对每个请求中从会话接收的值进行比较。如果值不匹配,则用户IP可能已更改或会话可能已被劫持。



6。您可能容易受到会话固定的困扰



如上所述,如果有人说服您的管理员访问某个网站,并且本网站向您的网站发送请求根据请求的PHPSESSID,您的站点将创建会话,处理登录/密码,并声明凭据错误。直到现在还不错。



之后,您的管理员登录到您的门户,会话已经存在,登录名和密码匹配,会话是UPDATED。变量有效现在是1。



只要更新变量,攻击者就可以完全访问您的门户网站,因为他知道PHPSESSID,您的网站不会阻止会话劫持或会话固定。



为避免会话固定和劫持,请参阅#5。


I'm writing a dynamic site that is powered by PHP and MySQL (to be run on a WAMP server). My current concerns are about the security of the site, however it does not feature any user input being saved and then later output for any users (except by admins), so I'm not really worried about XSS. My main concerns are against SQL injection attacks and protecting an admin login portal against rainbow tables/brute forcing.

1) Does using mysql_real_escape_string in conjunction with sprintf() protect you from SQL injection? e.g.,

$thing = mysql_real_escape_string($_REQUEST['thing'])
$query = sprintf("SELECT * FROM table WHERE thing='%s'", $thing);
$result = mysql_query($query);

Is this sufficiently safe? Of course, no system is perfectly safe, but I know that prepared statement are supposed to be the best way to protect against SQL injection. However, if my code is "safe enough" then I see no reason to make the change over. I read somewhere that mysql_query only allows one MySQL query per call for security reason by default, is that correct? If so, I don't see how any injections could be done on my code, but please let me know if there is a flaw in my logic here.

2) I am writing an admin portal for the site so that the owners of it can manipulate the MySQL database in an easy, user-friendly way on the website (from a login HTML file that isn't linked to from anywhere on the site). My concern for security here is the login process, which consists of two pages. First, gathering the user login information:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<title>Admin Portal</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="robots" content="noindex, nofollow">
<link rel="stylesheet" type="text/css" href="http://www.anotherdomain.com/my.css">
<script type="text/javascript" src="http://www.anotherdomain.com/my.js"></script>
</head>
<form method="post" action="admin/login.php">
<table align="center">
<tr><th>Admin Login Form</th></tr>
<tr><td>Name</td><td><input type="text" name="Name" size="30" onKeyPress="return aJSFunctionToStopEnterKeyFromWorking(event)"></td></tr>
<tr><td>Password</td><td><input type="password" name="Password" size="30" onKeyPress="return aJSFunctionToStopEnterKeyFromWorking(event)"></td></tr>
<tr><td></td><td><input type="reset" value="Clear Form"> <input type="submit" value="Login"></td></tr>
</table>
</form>

Second, the actual login script:

<?php
$inputusername = $_POST['Name'];
$inputpassword = $_POST['Password'];

$username = "a username that is not obvious";
$password = "a password that is at least 10 characters long";
$salt = hash('sha512', "a messed up string with weird characters that I wrote");

$hashword = hash('sha512', $password . $salt);
$inputhashword = hash('sha512', $inputpassword . $salt);

if($username == $inputusername && $hashword == $inputhashword) {
    session_start();
    $_SESSION['valid'] = 1;
    header('Location: portal.php');
    exit;
}
else {echo "Invalid username or password";}
?>

And then after the login process, each page will have the following to ensure that the admin is logged in:

<?php
session_start();
if(!$_SESSION['valid']) {header('Location: ../admin.html');}
?>
Portal page goes here

Since there is no creation of new users, there will only ever be one user for the portal. I am just wondering how safe this method of login is against attacks such as rainbow tables and brute forcing? I assume since I made the hashword and salt both very large it should be quite safe from these sorts of attacks, even if the username were somehow a known.

I am also wondering if this is safe from session hijacking, as that is a term I have heard thrown around but I don't know much about... I know that I'm not ever throwing a session ID around or anything like that, so it seems pretty secure.

3) Any other security concerns I should know/think about?

I really appreciate any help I get with this!

解决方案

Other points to think about:

1. You are vulnerable to bruteforce

A dictionary attack would crack your password. As the vast majority of users have an insecure password, it's only matter of time. Use captcha, or log invalid entries. Or add some delay when the password is incorrect.

As Col. Shrapnel said, a rainbow table isn't a concern to you because they are used when someone have a bunch of hashes and want to crack them. Salt is used to gain some protection against a rainbow table, and this is not your case.

2. You are sending passwords in clear text

If someone sniff your login (wifi, for example), you are doomed. There's some javascript libs which can encrypt anything using public keys. If you don't want to use SSL, encrypt the login/password, send to server, decrypt using the private key, and you are safer.

3. Consider using prepared statements on MySQL

Using prepared statements helps against SQL injection, as it can safely run even with malicious input:

$dbc = new mysqli("mysql_server_ip", "mysqluser", "mysqlpass", "dbname");
$statement = $db_connection->prepare("SELECT * FROM table WHERE thing='?'");
$statement->bind_param("i", $thing);
$statement->execute();

4. Don't relay on client-side validation

On your login form, you relay on a javascript funcion preventing Enter-key to function. What if I disable Javascript? You could use a hidden field (e.g. < input type='hidden' name='FormIsValid' value='0' >), use your function to prevent Enter-key, AND use an onSubmit() function to change FormIsValid to 1 before sending the form. In your server, verify FormIsValid.

5. You are vulnerable to session hijacking

Your session are saved on a cookie, by default named PHPSESSID. If an attacker can get that cookie, it could send it to your server and steal your session. To prevent it, you can save the user IP address and user agent in the session, and compare the value received from the session on every request. If the values doesn't match, the user IP may have changed or the session may have been hijacked.

6. You can be vulnerable to session fixation

As stated above, if someone convinces your admin to access some site, and this site sends a request to your site with a PHPSESSID on the request, your site would create the session, process the login/password, and state that the credentials are wrong. Not bad until now.

Later, your admin logs into your portal, the session already exists, the login and password matches, and the session is UPDATED. The variable valid now is 1.

As soon as the variable are updated, the attacker have full access to your portal, as he knows the PHPSESSID, your site doesn't prevent session hijacking, or session fixation.

To avoid session fixation and hijacking, see #5.

这篇关于动态网站安全问题(PHP + MySQL)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆