1

私は、セキュリティと、私が言及したような標的型攻撃から保護するための最良の方法について心配しているため、セッション用の 、およびカスタム AAA 記述モジュールをbottle.py使用して Web アプリケーションを作成しています。Beaker

例として、次のコードがあります。

@route('/manage/adddomain',method='POST')
def adddomain():
    #This checks if user has enough power to create a domain
    aaa.require(50,'/forbidden') 

    user = aaa.getusername() # This is retrieved from a server side session
    domainname = request.forms.get('domain')
    description = request.forms.get('description')

    # Additional checks are performed in the sql module 
    # to protect against forged requests with valid login
    return sql.createdomain(user,domainname,description)

Web アプリケーションを保護するために、どのような追加チェックを実行しますか?

4

3 に答える 3

4

必要なことはBlenderでほぼカバーできましたが、別の方法を追加したいと思います。各 POST をチェックする代わりに、次のようなラッパーを追加できます。

def wrap_requires_csrf(*methods):
    def wrapper(fn):
        @wraps(fn)
        def wrapped(*args, **kwargs):
            if request.method in methods:
                if request.method == 'POST':
                    csrf = request.form.get('csrf')
                elif request.method == 'GET':
                    csrf = request.args.get('csrf')
                if not csrf or csrf != session.get('csrf'):
                    abort(400)
                session['csrf'] = generate_csrf_token()
            return fn(*args, **kwargs)
        return wrapped
    return wrapper

@app.route('/some/page', methods=['GET','POST'])
@wrap_requires_csrf('POST')
def some_page():
    ...

次に、テンプレートで、隠しフィールドに

<input name="csrf" type="hidden" name="{{session.csrf}}" />
于 2013-04-16T05:14:09.637 に答える
2

すべての重要なフォーム フィールドに CSRF トークンを含め、テンプレート エンジンですべての出力をサニタイズする必要があります。

以下は、Bottle アプリに適用できるFlask スニペットです。

CSRF攻撃に対する一般的な手法は、ランダムな文字列をセッションに追加し、その文字列を POST の隠しフィールドと照合することです。

@app.before_request
def csrf_protect():
    if request.method == "POST":
        token = session.pop('_csrf_token', None)
        if not token or token != request.form.get('_csrf_token'):
            abort(403)

def generate_csrf_token():
    if '_csrf_token' not in session:
        session['_csrf_token'] = some_random_string()
    return session['_csrf_token']

app.jinja_env.globals['csrf_token'] = generate_csrf_token    

そして、あなたのテンプレートで:

<form method=post action="">
    <input name=_csrf_token type=hidden value="{{ csrf_token() }}">

サニタイズに関しては、テンプレート エンジンに依存します。Jinja2 にはeorescapeフィルターがあります。

<h2>No results for {{ search_query|escape }}</h2>
于 2013-04-15T23:02:00.950 に答える
0

@Blenderのソリューションをボトルに適応させました。これは次のとおりです。

from string import ascii_letters, digits
from random import choice
from bottle import Bottle, request, Jinja2Template, abort

app = Bottle()

@app.hook('before_request')
def csrf_protect():
    if request.method == 'POST':
        sess = request.environ['beaker.session']
        req_token = request.forms.get('csrf_token')

        # if no token is in session or it doesn't match the request one, abort
        if 'csrf_token' not in sess or sess['csrf_token'] != req_token:
            abort(403)

def str_random(length):
    '''Generate a random string using range [a-zA-Z0-9].'''
    chars = ascii_letters + digits
    return ''.join([choice(chars) for i in range(length)])

def gen_token():
    '''Put a generated token in session if none exist and return it.'''
    sess = request.environ['beaker.session']
    if 'csrf_token' not in sess:
        sess['csrf_token'] = str_random(32)
    return sess['csrf_token']

# allow access of the token generator using csrf_token
Jinja2Template.defaults['csrf_token'] = gen_token

Bottle にはデフォルトでセッションが付属していないため、bottle-beakerを使用しています。

すべてのフォームに含める必要がある入力:

<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"> 
于 2016-08-16T10:40:03.683 に答える