설명
메일 헤더에 사용자 입력을 그대로 결합하면 CR/LF로 새 헤더나 본문을 삽입할 수 있습니다. 비밀번호 재설정 링크나 거래 메일 본문을 신뢰하지 않는 URL·호스트 값으로 조립해도 공격자가 메일 내용을 바꿀 수 있습니다.
잠재적 영향
- 피싱 링크 삽입 또는 비밀번호 재설정 흐름 악용이 가능해질 수 있습니다.
- 사용자가 신뢰된 서비스 메일로 오인할 수 있습니다.
해결 방법
- 메일의 기본 URL과 호스트는 신뢰된 서버 설정에서 가져오세요. 재설정 토큰도 서버에서 생성하세요.
- 헤더 값의 CR/LF를 거부하고, 수신자 주소는 주소 형식과 업무상 허용 범위를 검증하세요. HTML 본문의 텍스트와 링크는 각 출력 문맥에 맞게 처리하세요.
- SMTP 수신자 목록과 메시지의 표시용 헤더를 구분해 올바른 수신자를 지정하세요.
예시
To 헤더의 조립 방식만 비교하는 발췌입니다. smtp.SendMail의 실제 SMTP 수신자는 별도 to 인자로 결정됩니다. 인증·전송 보호와 전송 오류 처리는 생략되어 있으며, 변경 후의 고정 주소는 실제 승인된 수신자로 바꾸세요.
변경 전
go
email := r.FormValue("email")
body := "Subject: reset\r\nTo: " + email + "\r\n\r\nhello"
smtp.SendMail(addr, nil, from, to, []byte(body))
변경 후
go
body := "Subject: reset\r\nTo: user@example.com\r\n\r\nhello"
smtp.SendMail(addr, nil, from, to, []byte(body))
설명:
- 변경 전: 검증하지 않은
email을To헤더에 결합하므로 CR/LF를 포함한 입력이 헤더나 본문을 바꿀 수 있습니다. - 변경 후: 이 예시의
To헤더는 사용자 입력으로 조립하지 않습니다. 동적 수신자를 사용할 때도 검증이 필요하며, 재설정 URL의 신뢰성은 별도로 보장해야 합니다.