1. 程式人生 > 其它 >SQL注入現象

SQL注入現象

package com.bjpowernode.jdbc;

/*
    實現功能:
        1.需求:模擬使用者登入功能的實現
        2.業務描述:程式執行的時候,提供一個輸入的入口,可以讓使用者輸入使用者名稱和密碼
                  使用者輸入使用者和密碼後,提交資訊,java程式收集到使用者資訊
                  java程式連線資料庫驗證使用者名稱和密碼是否合法
                  合法:顯示登陸成功
                  不合法:顯示登陸失敗
        3.資料的準備:
               在實際開發中,表的設計會使用專業的建模工具,安裝一個建模工具:PowerDesigner
               使用PD工具來進行資料庫表的設計(參見user-login.sql指令碼)
        4.當前程式存在的問題:
            使用者名稱:fdsa
            密碼:fdsa' or '1'='1
            登陸成功
            這種現象被稱為SQL注入(安全隱患)(黑客經常使用)
        5.導致SQL注入的根本原因是什麼?
            使用者輸入的資訊中含有sql語句的關鍵字,並且這些關鍵字參與sql語句的編譯過程,
            導致sql語句的原意背扭曲,進而達到sql注入
 */

import java.sql.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

/**
 * @Author:楊青
 * @Description:
 * @Time:2021/10/25 11:34
 */
public class JDBCTest06 {
    public static void main(String[] args) {
        //初始化一個介面
        Map<String,String> userLoginInfo=userinitUI();
        //驗證使用者名稱和密碼
        boolean loginSuccess=login(userLoginInfo);
        System.out.println(loginSuccess?"登陸成功!":"登陸失敗!");
    }

    /**
     * 使用者登陸
     * @param userLoginInfo 使用者登陸資訊
     * @return  false表示失敗,true表示成功
     */
    private static boolean login(Map<String, String> userLoginInfo) {
        //打標記的意識
        boolean loginSuccess=false;
        //單獨定義變數
        String loginName=userLoginInfo.get("loginName");
        String loginPwd=userLoginInfo.get("loginPwd");
        //JDBC程式碼
        Connection conn=null;
        Statement stmt=null;
        ResultSet rs=null;
        try {
            //1.註冊驅動
            Class.forName("com.mysql.jdbc.Driver");
            //2.獲取連線
            conn= DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode","root","123456");
            //3.獲取資料庫操作物件
            stmt=conn.createStatement();
            //4.執行sql
//            String sql = "select *from t_user where loginName='"+userLoginInfo.get("loginName")+"' and loginPwd='"+userLoginInfo.get("loginPwd")+"'";   //從userLoginInfor中取出loginName和loginPwd
            String sql = "select *from t_user where loginName='"+loginName+"' and loginPwd='"+loginPwd+"'";
            //以上正好完成了sql語句的拼接,以下程式碼的含義是:傳送sql語句給DBMS,DBMS進行sql編譯,
            //正好將使用者提供的‘非法資訊’編譯進去,導致了原sql語句的含義被扭曲了
            rs=stmt.executeQuery(sql);
            //5.處理結果集
            if(rs.next()){
                //登陸成功
                loginSuccess=true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //6.釋放資源
            if(rs!=null)
                try {
                    rs.close();
                }catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            if(stmt!=null)
                try {
                    stmt.close();
                }catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            if(conn!=null)
                try {
                    conn.close();
                }catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
        }


        return loginSuccess;
    }

    /**
     * 初始化使用者介面
     * @return 使用者輸入的使用者名稱和密碼等登陸資訊
     */
    private static Map<String, String> userinitUI() {
        Scanner scanner=new Scanner(System.in);
        System.out.print("使用者名稱:");
        String loginName=scanner.nextLine();    //得到使用者名稱
        System.out.print("密碼:");
        String loginPwd=scanner.nextLine();     //得到密碼
        Map<String ,String> userLoginInfo=new HashMap<>();
        userLoginInfo.put("loginName",loginName);   //將loginName組裝到Map中
        userLoginInfo.put("loginPwd",loginPwd);     //將loginPwd組裝到Map中
        return userLoginInfo;
    }
}