[시큐어코딩 가이드] 신뢰되지 않은 URL주소로 자동접속 연결

 

 

 

■ 입력데이터 검증 및 표현

 

프로그램 입력 값에 대한 검증 누락 또는 부적절한 검증, 데이터의 잘못된 형식지정, 일관되지 않은 언어셋 사용 등으로 인해 발생되는 보안약점으로 SQL 삽입, 크로스사이트 스크립트(XSS) 등의 공격을 유발할 수 있다.

 

 

신뢰되지 않은 URL주소로 자동접속 연결

 

■ 개요

 

사용자로부터 입력되는 값을 외부사이트의 주소로 사용하여 자동으로 연결하는 서버 프로그램은 피싱(Phishing) 공격에 노출되는 취약점을 가질 수 있다. 일반적으로 클라이언트에서 전송된 URL 주소로 연결하기 때문에 안전하다고 생각할 수 있으나, 공격자는 해당 폼의 요청을 변조함으로써 사용자가 위험한 URL로 접속할 수 있도록 공격할 수 있다.


Python 프레임워크의 redirect 함수를 사용 할 때에도 해당 프레임워크 버전에서 알려진 취약점이 있는지 확인해야 한다. Flask 프레임워크의 Flask-Security-Too 라이브러리의 경우 get_post_logout_redirect 함수와 get_post_login_redirect 함수가 4.1.0 이전 버전에서 URL 유효성 검사를 우회하고 사용자를 임의의 URL로 리디렉션 할 수 있는 취약점이 존재한다.

 

 

■ 안전한 코딩 기법

 

리디렉션을 허용하는 모든 URL을 서버 측 화이트리스트로 관리하고 사용자 입력 값을 리디렉션 할 URL이 존재하는지 검증해야 한다. 만약 사용자 입력 값이 화이트 리스트로 관리가 불가능하고 리디렉션 URL의 인자 값으로 사용되어야만 하는 경우는 모든 리디렉션에서 프로토콜과 host정보가 들어가지 않는 상대 URL(relative)을 사용해야 하고, 검증해야 한다.

 

또는 절대 URL(absoute URL)을 사용할 경우 리디렉션을 실행하기 전에 사용자 입력 URL https://myhompage.com/ 처럼 서비스하고 있는 URL로 시작하는지를 확인해야 한다.

 

 

코드예제

 

다음은 안전하지 않은 예제로 사용자로부터 입력 받은 url 주소를 검증 없이 reirect함수의 인자로 사용하고 있다. 이 경우 사용자가 의도하지 않은 사이트로 접근하도록 하거나 피싱(Phishing)공격에 노출될 수 있다.

 

안전하지 않은 코드의 예
from django.shortcuts import redirect

def redirect_url(request):
url_string = request.POST.get('url', '')
# 사용자 입력에 포함된 URL 주소로 리다이렉트 하는 경우
# 피싱 사이트로 접속되는 등 사용자가 피싱 공격에 노출될 수 있다
return redirect(url_string)

 

다음은 안전한 코드 예제로 사용자로부터 주소를 입력받아 redirect하고 있는 코드로 위험한 도메인이 포함되어 있을 수 있기 때문에 화이트 리스트로 사전에 정의된 안전한 웹사이트에 한하여 redirect 할 수 있도록 한다.

 

안전한 코드의 예
from django.shortcuts import render, redirect

ALLOW_URL_LIST = [
'127.0.0.1',
'192.168.0.1',
'192.168.0.100',
'https://login.myservice.com',
'/notice'
]

def redirect_url(request):
url_string = request.POST.get('url', '')

# 이동할 수 있는 URL 범위를 제한하여
# 위험한 사이트의 접근을 차단하고 있다
if url_string not in ALLOW_URL_LIST:
return render(request, '/error.html', {'ERROR':'허용되지 않는 주소입니다.})

return redirect(url_string)

 

 

댓글

Designed by JB FACTORY