环境配置:mysql下
create database demo;
use demo;
create table user(username varchar(100),password varchar(100));
create table user(username varchar(100),password varchar(100));
insert into user values("test","test");
send.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<form action="hack.jsp" method="post">
<ul>
<li>模拟sql注入攻击</li>
<li>用户名 <input type="text" name="username" /></li>
<li>密码 <input type="password" name="password" /></li>
<li><input type="submit" value="提交" /> <input type="reset"
value="重置" /></li>
</ul>
</body>
</html>
hack.jsp
<%@ page language="java" import="java.sql.*" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<%
String username=request.getParameter("username");
String password=request.getParameter("password");
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Connection connection=DriverManager.getConnection("jdbc:mysql://localhost/demo","root","123456");
Statement statement=connection.createStatement();
ResultSet resultSet=statement.executeQuery("select * from user where username='"+username+"'and password='"+password+"'");
if(resultSet.next())
{
out.print("<p>用户名:"+resultSet.getString(1)+" 密码"+resultSet.getString(2)+"</p></br>");
out.print("登陆成功");
}
else
out.print("用户名或密码错误");
%>
</body>
</html>
攻击方式
用户名或密码输入:
'or 1=1 or'
即可登陆成功。提示信息:
用户名:test 密码test
登陆成功
优化方法
使用
PreparedStatement来避免SQL攻击,如下,问题解决。
<%@ page language="java" import="java.sql.*" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<%
String username=request.getParameter("username");
String password=request.getParameter("password");
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Connection connection=DriverManager.getConnection("jdbc:mysql://localhost/demo","root","123456");
PreparedStatement preparedStatement=connection.prepareStatement("select * from user where username=? and password=?");
preparedStatement.setString(1, username);
preparedStatement.setString(2, password);
ResultSet resultSet=preparedStatement.executeQuery();
if(resultSet.next())
{
out.print("<p>用户名:"+resultSet.getString(1)+" 密码"+resultSet.getString(2)+"</p></br>");
out.print("登陆成功");
}
else
out.print("用户名或密码错误");
%>
</body>
</html>
send.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<form action="hack.jsp" method="post">
<ul>
<li>模拟sql注入攻击</li>
<li>用户名 <input type="text" name="username" /></li>
<li>密码 <input type="password" name="password" /></li>
<li><input type="submit" value="提交" /> <input type="reset"
value="重置" /></li>
</ul>
</body>
</html>
hack.jsp
<%@ page language="java" import="java.sql.*" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<%
String username=request.getParameter("username");
String password=request.getParameter("password");
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Connection connection=DriverManager.getConnection("jdbc:mysql://localhost/demo","root","123456");
Statement statement=connection.createStatement();
ResultSet resultSet=statement.executeQuery("select * from user where username='"+username+"'and password='"+password+"'");
if(resultSet.next())
{
out.print("<p>用户名:"+resultSet.getString(1)+" 密码"+resultSet.getString(2)+"</p></br>");
out.print("登陆成功");
}
else
out.print("用户名或密码错误");
%>
</body>
</html>
攻击方式
用户名或密码输入:
'or 1=1 or'
即可登陆成功。提示信息:
用户名:test 密码test
登陆成功
优化方法
使用
PreparedStatement来避免SQL攻击,如下,问题解决。
<%@ page language="java" import="java.sql.*" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<%
String username=request.getParameter("username");
String password=request.getParameter("password");
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Connection connection=DriverManager.getConnection("jdbc:mysql://localhost/demo","root","123456");
PreparedStatement preparedStatement=connection.prepareStatement("select * from user where username=? and password=?");
preparedStatement.setString(1, username);
preparedStatement.setString(2, password);
ResultSet resultSet=preparedStatement.executeQuery();
if(resultSet.next())
{
out.print("<p>用户名:"+resultSet.getString(1)+" 密码"+resultSet.getString(2)+"</p></br>");
out.print("登陆成功");
}
else
out.print("用户名或密码错误");
%>
</body>
</html>