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)

 

 

結果:

控制台輸出:

 

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='')

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:5000

test_url.netloc: 127.0.0.1:5000

test_url.scheme: http

request.full_path: /bar?

 

頁面:

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM