Колба, предотвращающая инъекцию формы - PullRequest
2 голосов
/ 23 декабря 2019

Как питон / колба может блокировать инъекции посторонних форм?

Рассмотрим следующее mwe:

app.py

from flask import Flask, request, render template

app = Flask(__name__)

@app.route('/', methods=['GET','POST'])
def helloworld():
    if request.method == 'GET':
        return render_template('index.html') 
    if request.method == 'POST':
        print(request.form['info'])

        ## do something with the info, like write to a database

        return 'nothing'

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

templates /index.html

<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type='text/javascript' src="{{ url_for('static', filename='js/fire.js') }}"></script>
</head>

<body>
<p>Hello world!</p>
</body>
</html>

static / js / fire.js

$(document).click(function() {

    // post data to flask

    $.post('/', {'info': 'test'});

    return false;

};

Мои вопросы:

  1. Возможна ли инъекция с иностранного сайта? Продолжение: как это можно сделать? (например, возможно через форму, которая публикует URL моего сайта?)
  2. Если внедрение возможно, что я могу сделать в сценарии app.py, чтобы заблокировать внедрение?

Edit

Вот очень простой сценарий, который можно использовать для проверки инъекций против вышеуказанного применения колбы. Принятый ответ блокирует этот скрипт:

<!DOCTYPE html>
<html>
<body>

<h2>Malicious Form Injection</h2>

<form action='http://127.0.0.1:5000/' method='post'>
  Input 1:<br>
  <input name="info" value="mal1"><br>
  <input type="submit" value="Submit">
</form>


</body>
</html>

1 Ответ

2 голосов
/ 24 декабря 2019

app.py

from flask import Flask, request, render template
from flask_wtf.csrf import CSRFProtect

app = Flask(__name__)

CSRFProtect(app)

app.config['SECRET_KEY'] = 'somethignrandom'

@app.route('/', methods=['GET','POST'])
def helloworld():
    if request.method == 'GET':
        return render_template('index.html') 
    if request.method == 'POST': # anything post will autocheck csrf
        print(request.form['info'])

        ## do something with the info, like write to a database

        return 'nothing'

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

Нет необходимости передавать секретный ключ в шаблон HTML, поскольку CSRFProtect автоматически передает секретный ключ.

templates / index. html

<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<meta name='csrf-token' content="{{ csrf_token() }}">
<script type='text/javascript' src="{{ url_for('static', filename='js/fire.js') }}"></script>

</head>

<body>
<p>Hello world!</p>
</body>
</html>

script.js

$(document).click(function() {

    // post data to flask

    $.post('/', {'info': 'test', '_csrf_token':$('meta[name="csrf-token"]').attr('content')});

    return false;

};
...