宣告 SQL 注入邪惡

**請注意,**在此示例中,我們將使用 PostgreSQL DBMS,但你可以使用任何 DBMS

我們將使用資料庫 bd_test 女巫包含 Schema: sch_test 和兩個表 userstest

CREATE TABLE sch_test.users
(
  id serial NOT NULL,
  username character varying,
  password character varying,
  CONSTRAINT utilisateur_pkey PRIMARY KEY (id)
) 

CREATE TABLE sch_test.test
(
  id serial NOT NULL,
  "column" character varying
)

使用 Statement 簡單登入

static String DRIVER = "org.postgresql.Driver";
static String DB_USERNAME = "postgres";
static String DB_PASSWOR = "admin";
static String DB_URL = "jdbc:postgresql://localhost:5432/bd_test";

public static void sqlInjection() {
    try {
        Class.forName(DRIVER);
        Connection connection = DriverManager.getConnection(DB_URL, DB_USERNAME, DB_PASSWOR);
        Statement statement = connection.createStatement();
        String username = "admin";
        String password = "admin";
        String query = "SELECT * FROM sch_test.users where username = '" 
                + username + "' and password = '" + password + "'";

        ResultSet result = statement.executeQuery(query);

        if (result.next()) {
            System.out.println("id = " + result.getInt("id") + " | username = "
                    + result.getString("username") + " | password = " + result.getString("password"));
        }else{
           System.out.println("Login not correct");
        }

    } catch (ClassNotFoundException | SQLException e) {
        e.printStackTrace();
    }
}

到目前為止,每件事都是正常和安全的。

使用假使用者名稱和密碼登入

黑客或測試人員可以使用以下命令登入或列出所有使用者:

String username = " ' or ''='";
String password = " ' or ''='";

插入新使用者

你可以使用以下方法在表中插入資料:

String username = "'; INSERT INTO sch_test.utilisateur(id, username, password) 
                        VALUES (2, 'hack1', 'hack2');--";
String password = "any";

刪除所有使用者

考慮黑客知道你的資料庫的架構,以便他可以刪除你的所有使用者

String username = "'; DELETE FROM sch_test.utilisateur WHERE id>0;--";
String password = "any"; 

DROP 表使用者

黑客也可以刪除你的表

String username = "'; drop table sch_test.table2;--";
String password = "any";

DROP DATABASE

最糟糕的是丟棄資料庫

String username = "'; DROP DATABASE bd_test;--";
String password = "any";

還有很多其他的。

為什麼這一切?

所有這一切,因為 Statement 不夠安全,它執行查詢就像它,因為它建議使用 PreparedStatement 代替,它更安全 Statement

你可以在這裡找到更多細節 PreparedStatement