728x90
데이터베이스와 연동된 웹 어플리케이션에서 입력된 데이터에 대한 유효성 검증을 하지 않을 경우,
공격자가 입력 폼 및 URL 입력란에 SQL 문을 삽입하여 DB로부터 정보를 열람하거나 조작할 수 있는 보안약점을 말한다.
1) preparedStatement 클래스와 하위 메소드 executeQuery(), execute(), executeUpdate()를 사용하는 것이 바람직하다.
안전하지 않은 코드▼
String query = " SELECT * FROM " + tableName + " WHERE Name = " + name;
외부로부터 tableName 과 name 의 값을 받아서 SQL 쿼리를 생성하고 있다.
안전한 코드 ▼
String query = "SELECT * FROM ? WHERE Name = ? ";
stmt = con.prepareStatement(query);
stmt.setString(1, tableName);
stmt.setString(2, name);
인자 부분을 set메소드로 설정하여 외부의 입력이 쿼리문의 구조를 바꾸는 것을 방지한다.
2) preparedStatement 클래스를 사용할 수 없는 환경이라면, 입력값을 필터링 처리한 후 사용한다.
(SQL 구문 제한, 특수문자 제한, 길이제한을 복합적으로 사용)
makeSecureString 함수
- 문자열의 길이 제한을 낮춘다.
- 정규식에 포함되는 단어의 개수를 높인다. (악용 가능성이 있는 SQL procedure명이나 SQL 명령어들을 필터링할 정규식에 포함)
안전한 코드 ▼
public class SqlInjectionSample extends HttpServlet
{
//작업의 type을 지정한다
private final String GET_USER_INFO_CMD = "get_user_info";
private Connection con;
//id 와 password의 최대 길이제헌을 8character와 16character로 제한한다.
private final static int MAX_USER_ID_LENGTH = 8;
private final static int MAX_PASSWORD_LENGTH = 16;
//select delete update insert 등 기본 명령어의 알파벳,
//숫자를 제외한 다른 문자들(인젝션에 사용되는 특수문자 포함)을 검출하는 정규식 설정
private final static String UNSECURED_CHAR_REGULAR_EXPRESSION =
"[^\\p[Alnum]]|select|delete|update|insert|create|after|drop";
private Pattern unsecuredCharPattern;
//정규식을 초기화한다.
public void initialize()
{
unsecuredCharPattern.compile(UNSECURED_CHAR_REGULAR_EXPRESSION,Pattern.CASE_INSENSITIVE);
}
//입력값을 정규식을 이용해 필터링한 후 의심되는 부분을 없앤다.
private String makeSecureString(final String str, int maxLength)
{
String secureStr = str.substring(0, maxxLength);
Matcheer matcher = unsecuredCharPattern.matcher(secureStr);
return matcher.replaceAll("");
}
//입력값을 받아 필터링한 후 쿼리로 만들어 처리한다.
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
String command = request.getParameter("command");
if (command.equals(GET_USER_INFO_CMD))
{
Statement stmt = conn.createStatement();
String userId = request.getParameter("user_id");
String password = request.getParameter("new_password");
String query = "SELECT * FROM members WHERE username= '" + makeSecureString(userId, MAX_USER_ID_LENGTH)
+ "' AND password = '" + makeSecureString(password, MAX_PASSWORD_LENGTH) + "'";
stmt.executeUpdate(query);
}
}
}
728x90
'△ > SecureCoding' 카테고리의 다른 글
크로스사이트 요청 위조 (0) | 2022.11.16 |
---|---|
신뢰 되지 않는 URL 주소로 자동 접속 연결 (0) | 2022.11.15 |
위험한 형식 파일 업로드 (0) | 2022.11.15 |
크로스 사이트 스크립트 (0) | 2022.11.11 |
자원 삽입 (0) | 2022.11.11 |
댓글