제시하신 문자열은 SQL 인젝션 시도에 해당합니다. 구체적으로는 PostgreSQL을 대상으로 한 시간 기반 블라인드(Time-based blind) 인젝션 페이로드로 보입니다. 구성 요소와 의미, 위험, 탐지 및 완화 방법을 아래에 정리합니다.
무엇을 시도하는지
- 페이로드: ZjQhAYtz' OR 133=(SELECT 133 FROM PG_SLEEP(15))--
- 의미: 입력값에 작은따옴표(')로 문자열을 닫고 OR 조건을 추가하여 133=(SELECT 133 FROM PG_SLEEP(15))를 평가하도록 합니다. PG_SLEEP(15)는 PostgreSQL에서 15초 동안 지연을 발생시키므로 해당 쿼리가 주입되면 응답 지연이 발생합니다. 뒤의 --는 SQL에서 주석 처리를 하여 나머지 원래 쿼리를 무력화합니다.
- 목적: 데이터 반환이 불가능한 상황에서도 서버의 응답 지연을 관찰해 참/거짓을 판별하는 방식(타임 기반 블라인드)으로, 줄곧 존재 여부나 특정 조건을 확인하는 공격 기법입니다.
위험
- 데이터 누출: 다른 블라인드 또는 에러 기반 기법과 결합하면 민감 데이터 추출이 가능합니다.
- 서비스 거부 유사 효과: 다수의 sleep 호출로 응답 지연을 유발하여 가용성 저하를 초래할 수 있습니다.
- 권한 상승 및 추가 공격 벡터 확보 가능성: 쿼리 실행 권한이 충분하면 시스템 명령 실행이나 다른 악용이 이어질 수 있음.
탐지 포인트
- 입력값에 작은따옴표, OR, SELECT, PG_SLEEP, SLEEP, 시간 지연 관련 함수, SQL 주석(--, /* */)가 결합된 패턴.
- 특정 요청에서 일관된 응답 지연(예: 정상 요청 대비 일정 시간만큼 지연).
- 애플리케이션 로그나 DB 로그에 비정상적으로 긴 쿼리 실행 시간 기록.
- 웹 방화벽(WAF) 경고: SQLi 서명과 일치하는 트래픽.
즉시 적용 가능한 완화 대책
- 파라미터화된 쿼리/준비문 사용:
- 모든 데이터 입력은 직접 쿼리 문자열에 결합하지 말고 준비된 파라미터로 전달합니다.
- 입력 검증(화이트리스트) 및 인코딩:
- 예상 형식(숫자, 이메일 등)만 허용하도록 검증하고, 출력 시 적절히 인코딩합니다.
- 최소 권한 원칙:
- DB 계정에 불필요한 권한(예: 데이터 정의, 시스템 함수 실행 권한)을 부여하지 않습니다.
- 쿼리 타임아웃 설정:
- 데이터베이스 및 애플리케이션 레벨에서 실행 시간 제한을 설정하여 의도적 지연을 방지합니다.
- 웹 애플리케이션 방화벽(WAF) 및 IP/요청 제한:
- 알려진 SQLi 패턴 차단, 비정상 요청 속도 제한 적용.
- 로깅 및 모니터링:
- 비정상적인 쿼리 지연, 오류 빈도 증가, 의심스러운 입력 패턴을 감지하도록 로그 및 알림을 설정합니다.
- 정기적인 보안 점검:
- 코드 리뷰, 정적/동적 애플리케이션 취약점 스캐닝, 침투 테스트 수행.
예시(안전한 쿼리 방식)
- 잘못된 방식(취약): sql = "SELECT * FROM users WHERE username = '" + user_input + "'";
- 안전한 방식(파라미터화): preparedStatement("SELECT * FROM users WHERE username = ?").setString(1, user_input);
권장 우선순위 작업
- 즉시 WAF나 차단 규칙으로 해당 패턴의 유입을 차단하고 비정상 요청을 로그에 남깁니다.
- 애플리케이션의 입력 처리 부분을 점검해 파라미터화 적용 범위를 우선 확장합니다(로그인, 검색, 폼 등).
- DB 계정 권한을 검토하고 불필요한 권한을 제거합니다.
- 쿼리 타임아웃을 설정하고 이상 징후(지연·실패)를 모니터링합니다.
- 코드베이스에 대해 SQL 인젝션을 찾는 정적·동적 스캔과 수동 검토를 시행합니다.
요약
- 제시하신 문자열은 PostgreSQL의 PG_SLEEP을 이용한 시간 기반 SQL 인젝션 시도로, 응답 지연 관찰을 통해 취약점을 확인하거나 데이터를 추출하려는 시도입니다. 파라미터화, 입력 검증, 권한 최소화, 쿼리 타임아웃, WAF 적용 및 모니터링을 통해 위험을 차단하고 탐지할 것을 권고드립니다.