정상 요청이 403이면, 먼저 “어떤 룰이 걸었는지”를 로그에서 특정한다
WAF 오탐은 추측으로 풀면 끝이 없다. 거의 모든 WAF(모드시큐리티/CRS, 클라우드 WAF)는 감사 로그에 매칭된 rule id와 matched data를 남긴다. 이걸 먼저 집는 것이 8할이다.
# ModSecurity audit log 예: 어떤 룰과 어떤 데이터가 걸렸는지
grep -A5 "<요청 고유값>" /var/log/modsec_audit.log | grep -E "id "|Matched Data"
흔한 오탐 패턴
- 본문·파라미터의 정상 텍스트가 SQLi/XSS 시그니처에 우연히 매칭(예: 게시글에
SELECT,--,<script같은 단어). - 파일 업로드, JSON/GraphQL 본문, base64 페이로드, rich text 에디터 입력.
- 이중 인코딩·정규화 차이로 정상 값이 공격 패턴처럼 보이는 경우.
튜닝은 “전체 끄기”가 아니라 “좁혀서 예외”
룰을 특정했으면 그 rule id를 특정 경로·파라미터에서만 예외 처리한다. 전체 비활성이나 WAF off는 보호를 통째로 버리는 것이라 피한다. CRS라면 paranoia level과 anomaly score 임계값을 조정하는 것도 방법이다.
# 예: 특정 경로의 특정 파라미터에서만 해당 룰 제거
SecRuleUpdateTargetById 942100 "!ARGS:comment"
정리
audit log에서 rule id 특정 → 오탐 데이터 확인 → 경로/파라미터 한정 예외 → 필요하면 정규화·paranoia 조정. “어느 룰인지”를 모른 채 손대는 순간 시간이 몇 배로 든다.
빠른 진단 체크리스트
- 추측 대신 감사 로그에서 걸린 rule id를 먼저 특정한다
- matched data로 어떤 입력이 걸렸는지 확인한다
- 정상 텍스트의 SQL 키워드·특수문자가 시그니처에 걸리는지 본다
- 파일 업로드·JSON·base64·rich text 입력을 의심한다
- 이중 인코딩·정규화 차이로 오탐이 나는지 본다
- 전체 비활성 대신 rule id를 경로·파라미터에 한정해 예외한다
- CRS면 paranoia level·anomaly 임계값을 조정한다
- 근본은 입력 정규화로, 예외는 최소 범위로 둔다