PHP / MYSQL安全问题(在线订单,管理员门户)

时间:2011-04-14 13:58:35

标签: php mysql html security

我正在编写一个由PHP和MySQL驱动的动态站点(在WAMP服务器上运行)。我目前的担忧是关于网站的安全性,我有几个问题。我昨天有一个关于它的帖子,得到了大量的帮助!到目前为止,非常感谢大家!但是,由于某些原因,SO阻止我编辑该帖子,所以我不得不重新编写...

1)我正在为该站点编写一个管理门户,以便它的所有者可以在网站上以一种简单,用户友好的方式操作MySQL数据库(从使用HTTPS的登录HTML页面)。门户网站中的每个页面也将使用HTTPS。我对安全性的关注是登录过程,它包括登录页面和PHP登录脚本,然后在登录后对实际门户网站内的页面进行身份验证。首先,收集用户登录信息:

<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>

其次,实际登录脚本:

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

$username = "a username that is not obvious";
$password = "a password that is at least 10 characters long";

if($username == $inputusername && $password == $inputpassword) {
    session_start();
    $_SESSION['valid'] = TRUE;
    $_SESSION['IP'] = $_SERVER["REMOTE_ADDR"];
    $_SESSION['agent'] = $_SERVER['HTTP_USER_AGENT'];
    header('Location: portal.php');
    exit;
}
else {echo  "<center>Invalid username or password<br><a href='../admin.html'>Try Again</a></center>"; exit;}
?>

然后在登录过程之后,门户网站的每个页面都会在文件开头包含以下脚本:

<?php
session_start();
if(!$_SESSION['valid']) {header('Location: ../admin.html'); exit;}
if($_SESSION['IP'] != $_SERVER["REMOTE_ADDR"]) {header('Location: ../admin.html'); exit;}
if($_SESSION['agent'] != $_SERVER['HTTP_USER_AGENT']) {header('Location: ../admin.html'); exit;}
?>

那么每个门户页面都将如下所示:

<?php include('session-authentication-script.php'); ?>
*Actual page goes here*

我还制作了退出脚本:

<?php
include('session-authentication-script.php');
$_SESSION['valid'] = FALSE;
session_destroy();
header('Location: ../admin.html');
exit;
?>

所有这些现在看起来都相对安全吗?或者我的安全仍然存在漏洞......

2)有人提到我仍然容易受到XSS的影响,但我不知道如何。有人可以向我解释这意味着什么:

  

就像echo“请求的文章:”一样简单。$ _ GET ['id']'的东西已经很脆弱了。

我试着谷歌搜索这意味着什么,但我找不到任何与安全相关的内容。如果有人能向我解释,我真的很感激!评论此内容的用户没有任何真实的上下文,所以我甚至不确定它适用于什么(我的最后一个帖子也包括SQL注入攻击...如果你想要更多上下文,这里是旧线程的链接: Dynamic Website Security Questions (PHP+MySQL))。

3)我还有一些脚本会通过电子邮件发送用户输入HTML表单中的敏感数据(信用卡号)。如何确保此数据得到适当保护?表单和脚本都将设置为使用HTTPS。这里基本上是一个简单的例子:

<form name="Order" method="post" action="incl/email_Order.php">
<table>
<tr><td>Name</td><td><input type="text" name="Name" size="30" onKeyPress="return aJSFunctionToStopEnterKeyFromWorking(event)" ></td></tr>

*gather up a bunch more form data in the same fashion*

<tr><td></td><td><input type="reset" value="Clear Form"> <input type="submit" value="Submit Order" ></td></tr></table>

然后,这是电子邮件脚本:

$to = "sales@company.com";
$subject = "Online Order";
$message = "Name: " . $_REQUEST['Name'] . "\r\n" .

*and here is a bunch of other stuff being concatenated to $message in the same fashion*

$headers = 'From: sales@company.com' . "\r\n" .
       'Reply-To: ' . $_REQUEST['Email'] . "\r\n";

if(mail($to, $subject, $message, $headers)) {print "Thank you for your order!";}
else {print "We encountered an error sending your order. Please attempt again.";}
exit;

HTTPS足以保证这种安全吗?这里是否有瑕疵让它开放?

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

我非常感谢我能得到更多的帮助!

4 个答案:

答案 0 :(得分:3)

2)

echo "Requested article: ".$_GET['id'];

如果有人提供

怎么办?
'<script src="bad_script_from_bad_server.js"></script>'

作为id?

在使用之前,您需要验证$ _GET ['id']。

一种方法可能是使用filter_input()

假设id应为整数:

echo "Requested article: ".filter_input ( INPUT_GET, 'id', FILTER_VALIDATE_INT);

答案 1 :(得分:2)

  1. 登录 - 在您的示例中,您没有对数据库进行任何身份验证,您正在比较变量的两个值。没有任何机制可以阻止任何人创建一个试图暴力破解登录脚本的脚本,这意味着重复输入值,直到找到合适的值。 通常,人们允许来自单个IP地址的特定数量的登录,以阻止脚本小子试图强制管理员登录。

  2. 是的,如果您回复“带有ID的文章”。 $ _GET ['id']。“找不到” - 没有任何东西阻止攻击者将JS从他的网站注入您的计算机并以某种方式控制网站。它是推测性的,但有人可能会登录到您的网站(比如说你),如果攻击者为你提供了诸如“/admin.php?id=”之类的链接 - 你将加载HIS javascript,这意味着他可以使用您的会话执行恶意操作 - 例如劫持您的会话以及获取实际的管理访问权限,以便从中删除您的数据。 这是可能发生的“灾难性”事件之一,但它们已经发生在今天并且正在发生 - 如果你可以避免它,那么这样做。始终清理输入 - 粘贴intval($ _ GET ['id'])不会造成伤害,并使您收到的变量属于正确类型。

  3. 通过电子邮件发送信用卡详细信息 - 这是一个很大的问题。处理诸如信用卡之类的高度机密信息必须以不同的方式处理 - 通常,如果您与第三方软件(某种支付网关)进行交互,则在交换数据之前首先建立加密连接。此外,通过电子邮件发送信用卡信息意味着在目标计算机上拥有足够权限的人可以阅读该电子邮件。如果您以这样的方式使用电子邮件,则无法保证目标人员(或服务)阅读该电子邮件,也无法保证其他人。 另一方面,NO ONE应该知道某人的信用卡详细信息,除了某种类型的服务扣除或贷记帐户 - 这意味着除了信用卡所有者之外,任何活着的人都不应该访问这些详细信息。所有支付网关都以这种方式工作。此外,如果您尝试存储信用卡信息以进行重复计费或类似的事情 - 我假设您知道用户首先必须同意这一点,并且您必须加密您正在保存的数据。

  4. 在线应用程序的安全性有很多,特别是用PHP创建的应用程序。您的网站是否在共享主机方案?如果是,会话存储在哪里?它们存储在/ tmp文件夹中吗?如果是,这意味着您可以创建一个脚本来读取/ tmp中保存的所有文件,并基本上获取其他网站的数据。同样,您可以修改现有会话,这些会话会使您在第1节中记录用户的安全计划无效。这只是我想到的一件事,想象一下,如果他/她想把你的网站弄下来,一个坚定的饼干会做什么。

答案 2 :(得分:1)

HTTPS(尝试)保证三件事:

  • 您的用户访问的网站是真实的,并且可靠的第三方(证书颁发者)信任您(即没有网络钓鱼)
  • 离开客户端和访问安全服务器之间的数据是安全的
  • 离开客户端的数据与到达服务器的数据相同。

你必须自己设置。例如,代码中的密码仅与服务器一样安全;如果有人能看到源代码,他们就会有密码。

更安全的选择可能是......

  • 数据库中的密码,因此可以轻松更改;保护数据库,设置约束,使密码必须足够复杂。
  • 检查用户不太可能是机器人(验证码)
  • 检查从一台机器快速重复尝试登录,这可能是暴力攻击的标志
  • 如果所有网站用户的密码相同(这是您的代码所做的),请确保您的用户了解风险。个人登录更安全。
  • 如果您使用密码数据库,请保护其免受SQL注入(http://xkcd.com/327/)

答案 3 :(得分:0)

在输入数据库之前使用标签剥离输入字段:

int main() 
{
    char *s;
    s = malloc(1024 * sizeof(char));
    scanf("%[^\n]", s);
    s = realloc(s, strlen(s) + 1);
    for (int i = 0; s[i] != '\0'; i++)
    {
        printf("%c \n", s[i]);
    }
    return 0;
}