在JSP基本登录模块Ⅳ中,如果在密码栏输入“' or '1'='1”,我们发现不知道密码也可以登录成功。
这是因为当我们的密码为“' or '1'='1”时,SQL语句变为:
Select * FROM member Where username='magci' and password='' or '1'='1'
'1'='1'是永真的,这条SQL语句是能通过验证的。
这就是SQL注入攻击。
为了防止SQL注入攻击,可以使用PraparedStatement对象操作数据库。
改进后的登录模块如下:
附加功能:防止SQL注入攻击
登录模块至少需要以下几个页面:
1.检查Cookie页面(index.jsp);
2.输入用户信息页面(login.jsp);
3.用户合法性验证页面(check.jsp);
4.登录成功欢迎页面(pass.jsp)(检查Session设置);
5.登录失败提示页面(failure.jsp);
6.注销登录页面(logout.jsp)。
数据库:member.mdb
结构图:
---------------------------------------------------------------------
index.jsp
|
|判断Cookie中有无用户名、密码
----------------------
| Y N |
| V
| login.jsp<--------------------
| |输入用户名、密码 |
| V |
---------------->check.jsp |
|查询用户名、密码 |
V |
member.mdb |
|返回结果 |
V |
check.jsp |
|判断用户是否合法 |
--------------------- |
| Y N | |
V V |
pass.jsp failure.jsp------->|
| |
| 检查session是否含有用户名 |
----------------- |
| Y N | |
V V |
pass.jsp 跳转------------------------->|
| |
|注销 |
V |
logout.jsp------------------------------------>|
---------------------------------------------------------------------
index.jsp:
程序代码
<%@ page contentType="text/html;charset=GB2312" %>
<html>
<head>
<title>index</title>
</head>
<body>
<%
int i;
//初始化,用于保存Cookie中的用户名、密码
String C_username="";
String C_password="";
//获取全部Cookie
Cookie c[]=request.getCookies();
for(i=0;i<c.length;i++)
{
//在Cookie中查找用户名、密码,如果找到,则分别将其赋值给用户名、密码变量
if("username".equals(c[i].getName()))
C_username=c[i].getValue();
if("password".equals(c[i].getName()))
C_password=c[i].getValue();
}
if(!"".equals(C_username) && !"".equals(C_password))
{
//Cookie中有用户名、密码,将用户名、密码提交到验证页面
response.sendRedirect("check.jsp?username="+C_username+"&password="+C_password);
}
else
{
//Cookie中没有用户名、密码,跳转到登录页面
%>
<jsp:forward page="login.jsp" />
<%
}
%>
</body>
</html>
login.jsp:
程序代码
<%@ page contentType="text/html;charset=GB2312" %>
<html>
<head>
<title>登录</title>
</head>
<body>
<center>
<h1>登录页面</h1>
<hr>
<form action="check.jsp" method="post">
<table>
<tr>
<td>用户名:</td>
<td><input type="text" name="username" /></td>
</tr>
<tr>
<td>密 码:</td>
<td><input type="password" name="password" /></td>
</tr>
<tr>
<td>Cookie选项:</td>
<td>
<input type="radio" name="cookie" value="nosave" checked>不保存
<input type="radio" name="cookie" value="save">保存1分钟
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="登录" />
<input type="reset" value="重置" />
</td>
</tr>
</table>
</form>
</center>
</body>
</html>
check.jsp:
程序代码
<%@ page contentType="text/html;charset=GB2312" %>
<%@ page import="java.sql.*" %>
<html>
<head>
<title>验证页面</title>
</head>
<body>
<%
String Username=request.getParameter("username");
String Password=request.getParameter("password");
String IsCookie=request.getParameter("cookie");
//定义标志,标记是否为合法用户,true为合法,false为非法
Boolean isUser=false;
//定义数据库连接驱动
final String DBDRIVER="sun.jdbc.odbc.JdbcOdbcDriver";
//定义数据库连接地址
final String DBURL="jdbc:odbc:member";
//定义变量存放SQL语句
String sql=null;
//定义数据库连接对象
Connection conn=null;
//定义数据库操作对象
PreparedStatement pstmt=null;
//定义结果集
ResultSet rs=null;
try{
//加载数据库驱动
Class.forName(DBDRIVER);
//连接数据库
conn=DriverManager.getConnection(DBURL);
//预预处SQL语句
sql="Select * FROM member Where username=? and password=?";
//实例化数据库操作对象
pstmt=conn.prepareStatement(sql);
//设置psmt中“?”对应的变量
pstmt.setString(1,Username);
pstmt.setString(2,Password);
//查询数据库,返回结果集
rs=pstmt.executeQuery();
if(rs.next())
{
//数据库中有符合的记录,合法用户
isUser=true;
}
//关闭结果集
rs.close();
//关闭操作
pstmt.close();
//关闭连接
conn.close();
}
catch(Exception e)
{
System.out.println(e);
}
//判断用户名、密码的合法性
if(isUser)
{
//合法用户
if("save".equals(IsCookie))
{
//如果选择了保存Cookie选项,则保存Cookie
Cookie c1=new Cookie("username",Username);
Cookie c2=new Cookie("password",Password);
//设置Cookie保存时间为1分钟
c1.setMaxAge(60);
c2.setMaxAge(60);
response.addCookie(c1);
response.addCookie(c2);
}
//设置session属性
session.setAttribute("username",Username);
//跳转到欢迎页面
%>
<jsp:forward page="pass.jsp"/>
<%
}
else
{
//非法用户,跳转到登录失败页面
%>
<jsp:forward page="failure.jsp" />
<%
}
%>
</body>
</html>
pass.jsp:
程序代码
<%@ page contentType="text/html;charset=GB2312" %>
<html>
<head>
<title>登录成功</title>
</head>
<body>
<center>
<%
//获取session属性值
String Mem_Session=(String)session.getAttribute("username");
if(Mem_Session!=null)
{
//session的username属性里含有用户名,可以浏览此页面
%>
<h1>登录成功!!</h1>
<hr>
<h3>欢迎<font size="12" color="red">
<%--forward跳转为服务器端跳转,跳转后仍在check.jsp页面,可以继续使用usename参数 --%>
<%=request.getParameter("username") %>
</font>光临!</h3>
<p>
<a href="logout.jsp">注销登录</a>
<%
}
else
{
//session的username属性里没有正确的用户名,无法浏览此页面,跳转到登录页面
%>
<h1>您还没有登录!</h1>
3秒之后跳转到登录页面
<p>
如果没有跳转,请点<a href="login.jsp">这里</a>
<%
response.setHeader("refresh","3;URL=login.jsp");
}
%>
</center>
</body>
</html>
failure.jsp:
程序代码
<%@ page contentType="text/html;charset=GB2312" %>
<html>
<head>
<title>登录失败</title>
</head>
<body>
<div align="center">
<h1>登录失败!!</h1>
<hr>
<a href="login.jsp">重新登录</a>
</div>
</body>
</html>
logout.jsp:
程序代码
<%@ page contentType="text/html;charset=GB2312" %>
<html>
<head>
<title>注销登录</title>
</head>
<body>
<%
//使session失效
session.invalidate();
%>
<center>
<h1>注销成功!</h1>
3秒后跳转到登录页面
<p>
如果没有跳转,请点<a href="login.jsp">这里</a>
<%
response.setHeader("refresh","3;URL=login.jsp");
%>
</center>
</body>
</html>
这是因为当我们的密码为“' or '1'='1”时,SQL语句变为:
Select * FROM member Where username='magci' and password='' or '1'='1'
'1'='1'是永真的,这条SQL语句是能通过验证的。
这就是SQL注入攻击。
为了防止SQL注入攻击,可以使用PraparedStatement对象操作数据库。
改进后的登录模块如下:
附加功能:防止SQL注入攻击
登录模块至少需要以下几个页面:
1.检查Cookie页面(index.jsp);
2.输入用户信息页面(login.jsp);
3.用户合法性验证页面(check.jsp);
4.登录成功欢迎页面(pass.jsp)(检查Session设置);
5.登录失败提示页面(failure.jsp);
6.注销登录页面(logout.jsp)。
数据库:member.mdb
结构图:
---------------------------------------------------------------------
index.jsp
|
|判断Cookie中有无用户名、密码
----------------------
| Y N |
| V
| login.jsp<--------------------
| |输入用户名、密码 |
| V |
---------------->check.jsp |
|查询用户名、密码 |
V |
member.mdb |
|返回结果 |
V |
check.jsp |
|判断用户是否合法 |
--------------------- |
| Y N | |
V V |
pass.jsp failure.jsp------->|
| |
| 检查session是否含有用户名 |
----------------- |
| Y N | |
V V |
pass.jsp 跳转------------------------->|
| |
|注销 |
V |
logout.jsp------------------------------------>|
---------------------------------------------------------------------
index.jsp:
程序代码
<%@ page contentType="text/html;charset=GB2312" %>
<html>
<head>
<title>index</title>
</head>
<body>
<%
int i;
//初始化,用于保存Cookie中的用户名、密码
String C_username="";
String C_password="";
//获取全部Cookie
Cookie c[]=request.getCookies();
for(i=0;i<c.length;i++)
{
//在Cookie中查找用户名、密码,如果找到,则分别将其赋值给用户名、密码变量
if("username".equals(c[i].getName()))
C_username=c[i].getValue();
if("password".equals(c[i].getName()))
C_password=c[i].getValue();
}
if(!"".equals(C_username) && !"".equals(C_password))
{
//Cookie中有用户名、密码,将用户名、密码提交到验证页面
response.sendRedirect("check.jsp?username="+C_username+"&password="+C_password);
}
else
{
//Cookie中没有用户名、密码,跳转到登录页面
%>
<jsp:forward page="login.jsp" />
<%
}
%>
</body>
</html>
login.jsp:
程序代码
<%@ page contentType="text/html;charset=GB2312" %>
<html>
<head>
<title>登录</title>
</head>
<body>
<center>
<h1>登录页面</h1>
<hr>
<form action="check.jsp" method="post">
<table>
<tr>
<td>用户名:</td>
<td><input type="text" name="username" /></td>
</tr>
<tr>
<td>密 码:</td>
<td><input type="password" name="password" /></td>
</tr>
<tr>
<td>Cookie选项:</td>
<td>
<input type="radio" name="cookie" value="nosave" checked>不保存
<input type="radio" name="cookie" value="save">保存1分钟
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="登录" />
<input type="reset" value="重置" />
</td>
</tr>
</table>
</form>
</center>
</body>
</html>
check.jsp:
程序代码
<%@ page contentType="text/html;charset=GB2312" %>
<%@ page import="java.sql.*" %>
<html>
<head>
<title>验证页面</title>
</head>
<body>
<%
String Username=request.getParameter("username");
String Password=request.getParameter("password");
String IsCookie=request.getParameter("cookie");
//定义标志,标记是否为合法用户,true为合法,false为非法
Boolean isUser=false;
//定义数据库连接驱动
final String DBDRIVER="sun.jdbc.odbc.JdbcOdbcDriver";
//定义数据库连接地址
final String DBURL="jdbc:odbc:member";
//定义变量存放SQL语句
String sql=null;
//定义数据库连接对象
Connection conn=null;
//定义数据库操作对象
PreparedStatement pstmt=null;
//定义结果集
ResultSet rs=null;
try{
//加载数据库驱动
Class.forName(DBDRIVER);
//连接数据库
conn=DriverManager.getConnection(DBURL);
//预预处SQL语句
sql="Select * FROM member Where username=? and password=?";
//实例化数据库操作对象
pstmt=conn.prepareStatement(sql);
//设置psmt中“?”对应的变量
pstmt.setString(1,Username);
pstmt.setString(2,Password);
//查询数据库,返回结果集
rs=pstmt.executeQuery();
if(rs.next())
{
//数据库中有符合的记录,合法用户
isUser=true;
}
//关闭结果集
rs.close();
//关闭操作
pstmt.close();
//关闭连接
conn.close();
}
catch(Exception e)
{
System.out.println(e);
}
//判断用户名、密码的合法性
if(isUser)
{
//合法用户
if("save".equals(IsCookie))
{
//如果选择了保存Cookie选项,则保存Cookie
Cookie c1=new Cookie("username",Username);
Cookie c2=new Cookie("password",Password);
//设置Cookie保存时间为1分钟
c1.setMaxAge(60);
c2.setMaxAge(60);
response.addCookie(c1);
response.addCookie(c2);
}
//设置session属性
session.setAttribute("username",Username);
//跳转到欢迎页面
%>
<jsp:forward page="pass.jsp"/>
<%
}
else
{
//非法用户,跳转到登录失败页面
%>
<jsp:forward page="failure.jsp" />
<%
}
%>
</body>
</html>
pass.jsp:
程序代码
<%@ page contentType="text/html;charset=GB2312" %>
<html>
<head>
<title>登录成功</title>
</head>
<body>
<center>
<%
//获取session属性值
String Mem_Session=(String)session.getAttribute("username");
if(Mem_Session!=null)
{
//session的username属性里含有用户名,可以浏览此页面
%>
<h1>登录成功!!</h1>
<hr>
<h3>欢迎<font size="12" color="red">
<%--forward跳转为服务器端跳转,跳转后仍在check.jsp页面,可以继续使用usename参数 --%>
<%=request.getParameter("username") %>
</font>光临!</h3>
<p>
<a href="logout.jsp">注销登录</a>
<%
}
else
{
//session的username属性里没有正确的用户名,无法浏览此页面,跳转到登录页面
%>
<h1>您还没有登录!</h1>
3秒之后跳转到登录页面
<p>
如果没有跳转,请点<a href="login.jsp">这里</a>
<%
response.setHeader("refresh","3;URL=login.jsp");
}
%>
</center>
</body>
</html>
failure.jsp:
程序代码
<%@ page contentType="text/html;charset=GB2312" %>
<html>
<head>
<title>登录失败</title>
</head>
<body>
<div align="center">
<h1>登录失败!!</h1>
<hr>
<a href="login.jsp">重新登录</a>
</div>
</body>
</html>
logout.jsp:
程序代码
<%@ page contentType="text/html;charset=GB2312" %>
<html>
<head>
<title>注销登录</title>
</head>
<body>
<%
//使session失效
session.invalidate();
%>
<center>
<h1>注销成功!</h1>
3秒后跳转到登录页面
<p>
如果没有跳转,请点<a href="login.jsp">这里</a>
<%
response.setHeader("refresh","3;URL=login.jsp");
%>
</center>
</body>
</html>