实验目的
- 理解网站安全的重要性;
- 了解Url操作攻击、跨站脚本、SQL注入等网站安全问题。
实验内容
【1】实现教材15.1的例子,以演示URL操作攻击实例。
实验简要步骤:
- 安装MySQL数据库服务器,如果机房PC已安装,可以跳过此步骤;
- 创建一个数据库shop,并在shop库创建数据表,字段为order_id、order_date、address,分别用于存储订单编号、订单时间和邮寄地址;
- 创建一个Servlet,用于在URL提交订单号,然后返回指定订单号的订单信息。
假设已知访问的URL为http://ip:端口/目录/display.jsp?order_id=10001有相应的订单,构造另外一个URL,遍历邻近的订单信息。
package gdpu.com;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class Shopping
*/
@WebServlet("/Shopping")
public class Shopping extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public Shopping() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
try {
Class.forName("com.mysql.jdbc.Driver"); // 驱动程序名
String url = "jdbc:mysql://localhost:3306/实验"; // 数据库名
String username = "root"; // 数据库用户名
String password = "0403"; // 数据库用户密码
Connection conn = DriverManager.getConnection(url, username, password); // 连接状态
if (conn != null) {
response.getWriter().print("访问成功!");
response.getWriter().print("<br />");
Statement stmt = null;
ResultSet rs = null;
stmt = conn.createStatement();
String sql = "SELECT * FROM shop;"; //查询语句
rs = stmt.executeQuery(sql);
response.getWriter().print("查询结果:");
response.getWriter().print("<br />");
while (rs.next()) {
response.getWriter().print("订单号:"+rs.getInt(1)+"<br>"+"订单时间:"+rs.getString(2)+"<br>"+"邮寄地址:"+rs.getString(3)+"<br>"); //将查询结果输出
}
} else {
response.getWriter().print("访问失败!");
}
} catch (Exception e) {
response.getWriter().print("数据库连接异常!" + e.getStackTrace().toString());
e.printStackTrace();
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
【2】实现教材15.3的例子,以演示SQL注入攻击实例。
- 利用上题安装的MySQL数据库服务器,创建一个数据库account;
- 结合前面表单提交的实验课程,创建一个用户登录的表单;
- 如果帐号和密码正确,则显示登录成功,否则显示失败;
- 构造一个注入SQL,无论输入的帐号或者密码正确与否,都能顺利登录。
Login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta charset=UTF-8>
<title>GDPU官网登录页面</title>
</head>
<body>
<form action ="./MySQL.html" method ="post">
GDPU账号:<input type = "text" style = "width220px;" name = "username"/><br><br>
账号密码 :<input type = "password" style = "width220px;" name = "password"/><br><br>
<input type = "submit" style = "width:220px;" value = "登录"/>
</form>
</body>
</html>
MySQl.java
package gdpu.com;
import java.sql.*;
import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MySQL extends HttpServlet {
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) {
String usernamex = request.getParameter("username");
String passwordx = request.getParameter("password");
try {
Class.forName("com.mysql.jdbc.Driver"); //驱动程序名
String url = "jdbc:mysql://localhost:3306/实验"; //数据库名
String mysqlusername = "root"; //数据库用户名
String mysqlpassword = "0403"; //数据库用户密码
Connection conn = DriverManager.getConnection(url, mysqlusername,mysqlpassword); //连接状态
//String sql = "SELECT * FROM account WHERE username = ? AND password = ?";
String sql = "SELECT * FROM account WHERE username = '' OR '1'='1'AND password = '' OR '1'='1'";//注入SQL
PreparedStatement st = conn.prepareStatement(sql);
ResultSet rs = st.executeQuery();
if (rs.next()) {
// Login successful
String line=rs.getInt(1)+","+rs.getInt(2);
response.getWriter().print("Login succeeded " + line);
} else {
// Login failed
response.getWriter().print("Login failed");
}
conn.close(); // Close the database connection
} catch (Exception e) {
e.printStackTrace();
}
}
Web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<display-name>JavaWeb</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet-name>MySQl</servlet-name>
<servlet-class>gdpu.com.MySQL</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MySQl</servlet-name>
<url-pattern>/MySQL.html</url-pattern>
</servlet-mapping>
</web-app>
【3】利用【2】中的account表,实现教材15.4的例子,以演示密码加密实例并存库。
MD5.java
package gdpu.com;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.mysql.jdbc.PreparedStatement;
/**
* Servlet implementation class MD5
*/
@WebServlet("/MD5")
public class MD5 extends HttpServlet {
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
String hashedPassword = null;
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(password.getBytes());
byte[] digest = md.digest();
StringBuffer sb = new StringBuffer();
for (byte b : digest) {
sb.append(String.format("%02x", b & 0xff));
}
hashedPassword = sb.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
Connection conn = null;
PreparedStatement stmt = null;
try {
// 获取数据库连接
Class.forName("com.mysql.jdbc.Driver"); //驱动程序名
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/实验", "root", "0403");
stmt = (PreparedStatement) conn.prepareStatement("INSERT INTO account (username, password) VALUES (?, ?)");
stmt.setString(1, username);
stmt.setString(2, hashedPassword);
stmt.executeUpdate();
} catch (SQLException | ClassNotFoundException e) {
e.printStackTrace();
} finally {
try {
if (stmt != null) {
stmt.close();
}
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
Web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<display-name>JavaWeb</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>MD5</servlet-name>
<servlet-class>gdpu.com.MD5</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MD5</servlet-name>
<url-pattern>/MySQlmd.html</url-pattern>
</servlet-mapping>
</web-app>
Login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta charset=UTF-8>
<title>GDPU官网登录页面</title>
</head>
<body>
<form action ="./MySQlmd.html" method ="post">
GDPU账号:<input type = "text" style = "width220px;" name = "username"/><br><br>
账号密码 :<input type = "password" style = "width220px;" name = "password"/><br><br>
<input type = "submit" style = "width:220px;" value = "登录"/>
</form>
</body>
</html>
连接数据库参考代码:
//说明:需要在头部引入java.sql.*包。
try {
Class.forName("com.mysql.jdbc.Driver"); //驱动程序名
String url = "jdbc:mysql://localhost:3306/chg?useUnicode=true&characterEncoding=UTF-8"; //库名
String username = "root"; //数据库用户名
String password = "root"; //数据库用户密码
Connection conn = DriverManager.getConnection(url, username,
password); //连接状态
if (conn != null) {
out.print("数据库连接成功!");
out.print("<br />");
Statement stmt = null;
ResultSet rs = null;
stmt = conn.createStatement();
String sql = "SELECT * FROM teachers;"; //查询语句
rs = stmt.executeQuery(sql);
out.print("查询结果:");
out.print("<br />");
while (rs.next()) {
out.println(rs.getString(1)+rs.getString(2)+"<br>"); //将查询结果输出
}
} else {
out.print("连接失败!");
}
} catch (Exception e) {
out.print("数据库连接异常!" + e.getStackTrace().toString());
e.printStackTrace(new java.io.PrintWriter(out));
}