flask 對URL進行安全驗證 --

 

對URL進行安全驗證

雖然咱們已經實現了重定向會上一個頁面的功能,可是安全問題不容忽視,鑑於referer和next容易被串篡改的特性,咱們須要對這些值進行驗證,不然會造成開放重定向漏洞
 
以URL中的next參數爲例,next變量以字符串的形式寫在url裏,所以任何人均可以發給某個用戶一個包含next變量指向任何站點的鏈接,那麼就會誤導用戶進入釣魚網站。
 
咱們能夠驗證next變量指向的url地址是否屬於咱們的應用內,不然不容許重定向。
 
確保URL安全的關鍵是判斷URL是否屬於程序內部,能夠經過判斷url的host、協議等信息是否和程序內部的url一致,若是一致則認識是可信的url
 
代碼中is_safe_url()方法接受目標URL做爲參數,經過request.host_url獲取程序內部的主機URL,而後使用urljoin()函數將目標URL轉爲絕對URL。接着,分別使用urlparse模塊提供的urlparse()解析兩個url,最後對目標url的url模式和主機地址進行驗證,確保只屬於程序內部的url纔會被返回。
在執行重定向會上一個頁面的redirect_back()函數中,使用is_safe_url()驗證next和referer的值

from urlparse import urlparse, urljoin #python3須要從urllib.parse導入
from flask import request

@app.route('/bar')
def bar():
    print "request.full_path:",request.full_path
    return '<h1>Bar page</h1><a href="%s">Do something and redirect </a>' % url_for('do_something', next = request.full_path)

@app.route('/do_something_and_redirect')
def do_something():
    return redirect_back()

def is_safe_url(target):
    print "request.host_url:",request.host_url
    ref_url = urlparse(request.host_url)
    print "ref_url:",ref_url
    print "target:",target
    test_url = urlparse(urljoin(request.host_url, target))
    print "test_url:",test_url
    print "ref_url.netloc:",ref_url.netloc
    print "test_url.netloc:",test_url.netloc
    print "test_url.scheme:",test_url.scheme
    return test_url.scheme in ('http', 'https') and ref_url.netloc ==test_url.netloc

def redirect_back(default = 'hello',**kwargs):
    for target in request.args.get('next'),request.referrer:
        if target:
            if is_safe_url(target):
                return redirect(target)
    return redirect(url_for(default,**kwargs))

if __name__ == '__main__':
    app.run(debug = True)

 

 

結果:python

控制檯輸出:flask

 

request.host_url: http://127.0.0.1:5000/安全

ref_url: ParseResult(scheme=u'http', netloc=u'127.0.0.1:5000', path=u'/', params='', query='', fragment='')app

target: /bar?函數

test_url: ParseResult(scheme=u'http', netloc=u'127.0.0.1:5000', path=u'/bar', params='', query='', fragment='')網站

ref_url.netloc: 127.0.0.1:5000url

test_url.netloc: 127.0.0.1:5000.net

test_url.scheme: httpdebug

request.full_path: /bar?3d

 

頁面:

 

相關文章
相關標籤/搜索