1、传统Web应用与新兴移动应用
(1)传统Web应用:浏览器 HTTP 服务器
(2)新兴移动应用:APP HTTP 服务器
从安全角度看,传统Web应用与新兴移动应用没有本质区别
2、Web应用安全的核心问题是什么?
用户提交的数据不可信是Web应用程序核心安全问题
用户可以提交任意输入
例如:
√ 请求参数->多次提交或者不提交
√ 修改Cookie
√ 修改HTTP信息头
√ 请求顺序->跳过或者打乱
3、Web应用防御
(1)完善的异常处理
(2)监控
(3)日志:记录重要业务、异常的详细请求信息
4、对输入的处理
建议采用:白名单
尽量避免:净化或黑名单
0x01 SQL注入
1、原理:
(1)合法输入:
id=1 SELECT * FROM users WHRER id='1';
(2)恶意注入:
id=1' or '1'='1 SELECT * FROM users WHRER id='1' or 'a'='a';
2、Java代码分析(JDBC)
(1)不合规代码(SQL参数拼接)
public class SQLInject { public static void main(String[] args)throws Exception{ //正常输入 select("1"); // 恶意输入 select("' or 'a'='a"); } public static void select(String id){ //声明Connection对象 Connection con; //驱动程序名 String driver = "com.mysql.jdbc.Driver"; //URL指向要访问的数据库名mydata String url = "jdbc:mysql://localhost:3306/mybatis"; //MySQL配置时的用户名 String user = "root"; //MySQL配置时的密码 String password = "budi"; //遍历查询结果集 try { //加载驱动程序 Class.forName(driver); //1.getConnection()方法,连接MySQL数据库!! con = DriverManager.getConnection(url,user,password); if(!con.isClosed()) System.out.println("Succeeded connecting to the Database!"); //2.创建statement类对象,用来执行SQL语句!! Statement statement = con.createStatement(); //要执行的SQL语句 String sql = "select * from users where id='"+id+"'"; //3.ResultSet类,用来存放获取的结果集!! ResultSet rs = statement.executeQuery(sql); System.out.println("-----------------"); System.out.println("执行结果如下所示:"); System.out.println("-----------------"); String age,name; while(rs.next()){ //获取stuname这列数据 name = rs.getString("name"); //获取stuid这列数据 age = rs.getString("age"); //输出结果 System.out.println(name + "\t" + age); } rs.close(); con.close(); } catch(ClassNotFoundException e) { //数据库驱动类异常处理 System.out.println("Sorry,can`t find the Driver!"); e.printStackTrace(); } catch(SQLException e) { //数据库连接失败异常处理 e.printStackTrace(); }catch (Exception e) { // TODO: handle exception e.printStackTrace(); }finally{ System.out.println("数据库数据成功获取!!"); } } }
执行结果:
SQL Paramter:1 ----------------- budi 27 ----------------- SQL Paramter:' or 'a'='a ----------------- budi 27 budisploit 28 -----------------
(2)合规代码(参数化查询)
public class SQLFormat { public static void main(String[] args)throws Exception{ select("1"); select("' or 'a'='a"); } public static void select(String id){ //声明Connection对象 Connection con; //驱动程序名 String driver = "com.mysql.jdbc.Driver"; //URL指向要访问的数据库名mydata String url = "jdbc:mysql://localhost:3306/mybatis"; //MySQL配置时的用户名 String user = "root"; //MySQL配置时的密码 String password = "budi"; //遍历查询结果集 try { //加载驱动程序 Class.forName(driver); //1.getConnection()方法,连接MySQL数据库!! con = DriverManager.getConnection(url,user,password); if(!con.isClosed()) System.out.println("Succeeded connecting to the Database!"); //2.//要执行的SQL语句 String sql = "select * from users where id=?"; //3.创建statement类对象,ResultSet类,用来存放获取的结果集!! PreparedStatement stmt = con.prepareStatement(sql); stmt.setString(1, id); ResultSet rs = stmt.executeQuery(); System.out.println("-----------------"); System.out.println("执行结果如下所示:"); System.out.println("-----------------"); String age,name; while(rs.next()){ //获取stuname这列数据 name = rs.getString("name"); //获取stuid这列数据 age = rs.getString("age"); //输出结果 System.out.println(name + "\t" + age); } rs.close(); con.close(); } catch(ClassNotFoundException e) { //数据库驱动类异常处理 System.out.println("Sorry,can`t find the Driver!"); e.printStackTrace(); } catch(SQLException e) { //数据库连接失败异常处理 e.printStackTrace(); }catch (Exception e) { // TODO: handle exception e.printStackTrace(); }finally{ System.out.println("数据库数据成功获取!!"); } } }