2

GitHub の例に基づいて、これは私の Python スクリプトです。

from flask import Flask, render_template, session, request
from flask_socketio import SocketIO, emit

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app, async_mode='eventlet')


@app.route('/')
def index():
    return render_template('index.html')


@socketio.on('my event', namespace='/test')
def test_message(message):
    session['receive_count'] = session.get('receive_count', 0) + 1
    emit('my response',
         {'data': message['data'], 'count': session['receive_count']})

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

これは HTML テンプレートです。

<!DOCTYPE HTML>
<html>
<head>
    <script src="//code.jquery.com/jquery-1.4.2.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.5/socket.io.min.js"></script>

    <script charset="utf-8">
        $(document).ready(function(){
            namespace = '/test'; // change to an empty string to use the global namespace

            // the socket.io documentation recommends sending an explicit package upon connection
            // this is specially important when using the global namespace
            var socket = io.connect('http://' + document.domain + ':' + location.port + namespace);

            // event handler for server sent data
            // the data is displayed in the "Received" section of the page
            socket.on('my response', function(msg) {
                $('#log').append('<br>Received #' + msg.count + ': ' + msg.data);
            });

            // handlers for the different forms in the page
            // these send data to the server in a variety of ways
            $('form#emit').submit(function(event) {
                socket.emit('my event', {data: $('#emit_data').val()});
                return false;
            });
        });
    </script>
</head>
<body>  
    <form id="emit" method="POST" action='#'>
        <input type="text" name="emit_data" id="emit_data" placeholder="Message">
        <input type="submit" value="Echo">
    </form>

    <h2>Receive:</h2>
    <div id="log"></div>
</body>
</html>

すべて正常に動作します。しかし問題は、ユーザーがメッセージ内で任意の HTML タグを使用できることです。

例えば:

例

少し危険だと思います。どのユーザーも JavaScript コードを実行してブロードキャストできるからです。その後、すべてのクライアントがそれを実行します。

とにかくジンジャの自動エスケープを使用して出力をエスケープする方法はありますか、それとも他の方法がありますか?

4

2 に答える 2

1

ただし、私が見つけた方法は、次のようにスクリプト内の HTML 文字をエスケープできることです。

import jinja2

# other code here

@socketio.on('my event', namespace='/test')
def test_message(message):
    session['receive_count'] = session.get('receive_count', 0) + 1
    emit('my response',
         {'data': jinja2.escape(message['data']), 'count': session['receive_count']})
#                 ^^^^^^^^^^^^^^ use jinja2 escape the output before send it to the clients.

デモ出力:

例外出力

于 2015-12-20T04:02:00.327 に答える