1713次阅读
sql注入和session

真没想到,一个小小的注册登陆程序竟然出了这么多bug,这次真是脸丢大了。

先来看看sql注入是怎么回事,其实利用欣欣的密码,确实可以随便一个帐号就能登陆,这个密码被称作万能密码,比如用户名填notexist,密码填11' or '1'='1,那么最终执行的sql语句就变成:select * from test where username='notexist' and passwd='11' or '1'='1';,这样的话'1'='1'永远是真,也就全都选出来啦,比较靠谱的方法是,先根据用户名选出记录,再判断密码对不对,这样可以防止sql注入。

然后我们来看看session是怎么回事,其实session是服务器为每个会话保存的一小块内存,那么什么是会话呢?简单说,就是我们打开一个浏览器,去访问一个网站,这就是一个会话,直到我们关闭浏览器为止。

我们来做一个实验:做三个页面,put_session.php往session中放东西,get_session.php获取session,clear_session.php清除session,代码如下:

put_session:

<?php
  session_start();
  $_SESSION['key'] = 'i am session';
?>	
check the result

get_session:

<?php
  session_start();
  if(isset($_SESSION['key'])) {
    echo $_SESSION['key'];
  } else {
    echo "no session found";
  }
?>	
check the result

clear_session:

<?php
  session_start();
  unset($_SESSION['key']);
?>	
check the result

先访问get_session,会发现一开始没有session,再访问put_session,这时向session中放入了东西,这时再访问get_session,就看到东西啦,要想清除session,就访问下clear_session,然后再刷新get_session,东西又没啦。

注意,在php中操作session,一定要先调用session_start()方法,然后就可以通过$_SESSION来操作session了。

这下我们就可以修复原来的3个bug啦,修复后的代码如下:

login.php:

<form action="handler.php" method="post">
  <input type="text" name="username" placeholder="请输入用户名" /><br/>
  <input type="password" name="password" placeholder="请输入密码" /><br/>
  <input type="hidden" name="type" value="login" /><br/>
  <input type="submit" value="登陆" /><br/>
</form>
没账号?去<a href="register.php">注册</a>	
check the result

register.php:

<form action="handler.php" method="post">
  <input type="text" name="username" placeholder="请输入用户名" /><br/>
  <input type="password" name="password" placeholder="请输入密码" /><br/>
  <input type="hidden" name="type" value="register" /><br/>
  <input type="submit" value="注册" /><br/>
</form>
有账号?直接<a href="login.php">登陆</a>	
check the result

welcome.php:

<?php 
  session_start();
  if(isset($_SESSION['username'])) {
    echo "欢迎您 : " . $_SESSION['username'];
  } else {
    header("Location: login.php");
  }
?>	

handler.php:

<?php
  require_once dirname ( __FILE__ ) . '/../../../../common/SQLHelper.class.php';
  if(isset($_POST['type'])) {
    $type = $_POST['type'];
    if(isset($_POST['username']) && isset($_POST['password'])) {
      $sqlHelper = new SQLHelper();
      $username = $_POST['username'];
      $password = $_POST['password'];
      if($type == "login") {
        $sql = "select * from test where username='". $username . "'";
        $res = $sqlHelper->execute_dql_array($sql);
        if(count($res) > 0) {
          if($res[0]['passwd'] == $password) {
            // 密码验证通过
            session_start();
            $_SESSION['username'] = $username;
            header("Location: welcome.php");
          } else {
            header("Location: login.php");
          }
        } else {
          header("Location: login.php");
        }
      } else if($type == "register") {
        $sql = "select * from test where username='". $username . "'";
        $res = $sqlHelper->execute_dql_array($sql);
        var_dump($res);
        if(count($res) > 0) {
          //用户名已存在
          header("Location: login.php");
          exit();
        }
        $sql = "insert into test (username, passwd) values ('" . $username . "', '" . $password . "')";
        $res = $sqlHelper->execute_dqm($sql);
        if($res == 1) {
          session_start();
          $_SESSION['username'] = $username;
          header("Location: welcome.php");
        } else {
          header("Location: login.php");
        }
      }
    } else {
      header("Location: login.php");
    }
  } else {
    header("Location: login.php");
  }
?>	

写后台一定要注意跳转的控制和逻辑,后台最容易出bug,特别是有用户输入的地方,要判断各种情况,很多黑客就是通过输入的时候输入一些特殊东西,破解后台的。

如果您觉得此教程不错,想支持一下,您可以通过支付宝扫码给我们一点,不要超过100元哦!
评论请先登录