为了给大家将SQL注入的原理,需要大家具备如下的知识:
(1)掌握基本Swing组件的开发
(2)掌握基本JDBC的开发
此课题的视频我们也为大家做好了。在文章的底部,大家可以看看。详细的SQL注入原理可以参考我们论坛的文章:
http://forum.javait.org/viewthread.php?tid=53&extra=page%3D1
1、什么样的SQL语句是SQL注入语句
大家先看如下没有加入SQL注入设计的SQL语句
select * from student where sno = 's001'
根据上面的SQL语句,我们只需要改变一下就能够完成SQL语句的注入
select * from student where sno = 's001' or '1'='1'
2、在编写JDBC程序时候,如何利用上面SQL语句注入,完成输入不存在的学号也可以登录成功???
防止SQL注入的方法:利用JDBC的PreparedStatement来完成
3、代码实现
(1)编写界面窗口
package test;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.SQLException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
/**
*
* @author JavaIT学习室
*
*/
public class TestFrame extends JFrame {
private JLabel sno; //学号
private JTextField sno_t; //学号的文本框
private JButton b; //登录按钮
public TestFrame() {
init(); //创建窗口的相关属性,例如:设置窗口的大小
}
private void init() {
this.setTitle("防止SQL语句注入危险的程序"); //设置窗口标题
this.setSize(300, 200); //设置窗口的高和宽
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //设置窗口的关闭方式
this.setResizable(false); //设置窗口不可最大化,或是设置窗口不可调整大小
//在放置基本组件的时候一定要注意窗口的布局方式
this.setLayout(new FlowLayout()); //设置窗口是流式布局
sno = new JLabel("学号:");
sno_t = new JTextField(8);
b = new JButton("登录");
this.getContentPane().add(sno);
this.getContentPane().add(sno_t);
this.getContentPane().add(b);
b.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
String s = sno_t.getText(); //返回窗口中输入的学号信息
try {
int i = DBUtil.getInstance().check_2(s);
if (i > 0) {
JOptionPane.showMessageDialog(null, "登录成功");
} else {
JOptionPane.showMessageDialog(null, "登录不成功");
}
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} //将学号传入到数据库中进行匹配
} //为按钮添加点击事情
});
this.setVisible(true); //设置窗口可以显示
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new TestFrame();
}
}
(2)数据库代码
package test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/**
* 数据库连接的类,利用JDBC技术完成
* @author JavaIT学习室
*
*/
public class DBUtil {
private static final String USER_NAME = "sa";
private static final String PASSWORD = "123456";
private static final String driverclass = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
private static final String url = "jdbc:sqlserver://localhost:1433;DatabaseName=stu";
private static DBUtil db = null; //它是一个单例的对象
private DBUtil() {
try {
Class.forName(driverclass); //加载驱动,必须将数据库的驱动包导入到工程中,不然会报错。sqljdbc.jar
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 返回主类DBConnectionUtil的对象,因为构造方法被定义为private,所以在初始化主类对象的时候只能用此方法实现
* @return
*/
public static DBUtil getInstance() {
if (db == null) {
db = new DBUtil();
}
return db;
}
/**
* 获取数据库连接Connection的对象
* @return
*/
public Connection getConnection() {
Connection conn = null;
try {
conn = DriverManager.getConnection(url, USER_NAME, PASSWORD);
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
/**
* 关闭数据库连接对象的方法
* @param conn
*/
public void close(Connection conn) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 没有防止SQL注入的代码
* @return
* @throws SQLException
*/
public int check(String sno) throws SQLException {
String sql = "select count(sno) from student where sno = '"+sno+"'";
System.out.println(sql);
Statement stmt = DBUtil.getInstance().getConnection().createStatement();
ResultSet rs = stmt.executeQuery(sql);
if (rs != null && rs.next()) { //对执行的SQL语句的结果集进行遍历
if (rs.getInt(1) > 0) {
return 1; //确认该学生在数据库中存在
}
}
return 0;
}
/**
* PreparedStatement可以防止SQL注意的接口
* @param sno
* @return
* @throws SQLException
*/
public int check_2(String sno) throws SQLException {
String sql = "select count(sno) from student where sno = ?";
PreparedStatement ps = DBUtil.getInstance().getConnection().prepareStatement(sql);
ps.setString(1, sno);
ResultSet rs = ps.executeQuery();
if (rs != null && rs.next()) { //对执行的SQL语句的结果集进行遍历
if (rs.getInt(1) > 0) {
return 1; //确认该学生在数据库中存在
}
}
return 0;
}
}
分享到:
相关推荐
1. **参数化查询**:使用预编译的SQL语句,将用户输入作为参数传递,而不是直接拼接到SQL字符串中。例如,使用ORM框架(如Hibernate、Entity Framework)或数据库提供的存储过程。 2. **输入验证**:对用户输入进行...
sql注入语句sql注入语句sql注入语句sql注入语句sql注入语句sql注入语句sql注入语句sql注入语句sql注入语句sql注入语句sql注入语句sql注入语句sql注入语句sql注入语句sql注入语句sql注入语句sql注入语句sql注入语句...
然而,由于需要手动编写SQL语句,如果不加以防范,则可能会面临SQL注入的风险。 #### MyBatis防止SQL注入的方法 ##### 1. 使用预编译语句(PreparedStatement) MyBatis内部使用了JDBC的PreparedStatement来实现...
使用 PreparedStatement 可以防止 SQL 注入攻击,因为攻击者不能 inject 恶意的 SQL 语句。 3.过滤用户的输入 在 WEB 层我们可以过滤用户的输入来防止 SQL 注入。例如,可以使用 Filter 来过滤全局的表单参数。...
) 和注释符号(--)的语句给替换掉来防止 SQL 注入: public static String TransactSQLInjection(String str){ return str.replaceAll(".*([';]+|(--)+).*", " "); } userName=TransactSQLInjection(userName); ...
为了防止SQL注入,最关键的做法是在构建SQL语句时采用参数化查询或预编译语句,而不是简单地将用户输入拼接进SQL字符串。这种方式可以确保输入被当作值而非可执行代码来处理。 #### 二、设置数据库 本节将通过一个...
使用预编译语句时,SQL语句的结构是固定的,只有参数是可以改变的。例如,在Java中,可以这样使用PreparedStatement: ```java String sql = "SELECT * FROM Users WHERE username = ?"; PreparedStatement ...
这样可以防止恶意代码改变SQL语句的结构。 2. 使用存储过程:通过存储过程与数据库交互,减少直接的SQL命令执行,降低注入风险。 3. 验证和清理输入:对所有用户输入进行验证,确保符合预期格式,并清理可能存在的...
预编译SQL语句是防止SQL注入的一种有效方法。它允许你在编写SQL语句时保留占位符,然后将实际的参数值传递给这些占位符。Python中的数据库API通常支持这种方式。 **示例代码**: ```python import MySQLdb class ...
SQL注入是一种常见的网络安全威胁,它允许攻击者通过输入恶意的SQL语句来操纵数据库,获取、修改或删除敏感数据。防止SQL注入是每个Web开发者必须关注的重要问题。在这个主题中,我们将深入探讨“防止SQL注入工具类...
同时,我们还将提供一些实用的SQL语句,用于检测和防止SQL注入攻击。 检测SQL注入 在DB2数据库中,可以使用以下方法来检测SQL注入: 1. 版本信息:可以使用以下SQL语句来获取DB2数据库的版本信息: ```sql SELECT...
SQL 注入防止方法 SQL 注入是一种常见的攻击手法,攻击者可以通过在输入数据中注入恶意的 SQL 代码,从而获取数据库的敏感信息或控制数据库。为了防止 SQL 注入,需要从多方面入手,包括使用预编译语句、正则表达式...
### 手工SQL注入常用SQL语句 #### 知识点概述 在现代网络环境中,随着业务系统的复杂度增加和技术的不断进步,安全问题日益受到重视。其中,SQL注入是一种常见的攻击方式,它通过将恶意SQL代码插入到应用程序的...
- 使用ORM框架:如Hibernate、MyBatis等,它们在底层处理了SQL注入问题,减少了直接编写SQL语句的机会。 - 输入验证:对用户输入进行校验,限制长度、类型和格式,拒绝不符合规则的输入。 - 使用过滤器(Filter)...
本文将深入探讨DB2数据库中的SQL注入语句,以及如何通过这些语句来猜解数据库结构和数据。 首先,SQL注入的基础原理是通过在合法的SQL查询语句中嵌入恶意代码,以改变原本的查询逻辑。在给定的示例中,攻击者试图猜...
SQL参数化是指在执行SQL语句时,使用参数代替原始的SQL语句,从而防止恶意的SQL语句注入。 在上面的代码中,我们可以看到两个不同的参数化传递方式。第一个方式使用DBHlep类,通过params SqlParameter[] values参数...
本文主要介绍了如何使用JavaScript代码来防止SQL注入,这是为了保证Web应用的安全性,防止恶意用户通过输入特定的SQL语句来破坏数据库。文章从两个方面进行了说明,包括URL地址防注入和输入文本框防注入。 首先,...
此外,使用SQL语句编码也是防止SQL注入的措施之一,但这通常是作为最后的保护措施,因为它依赖于数据库的特定实现。在某些情况下,可以使用存储过程来代替直接的SQL语句,以此来增强安全性。 在代码实现层面,可以...