python web Framework Flask-csrf Attack

Keywords: Python Session Attribute network less

What is CSRF?

Cross Site Request Forgery (Cross Site Request Forgery) is a network attack. It was listed as one of the 20 major security risks of the Internet in 2007. It is also known as "One Click Attack" or Session Riding. It is usually abbreviated as CSRF or XSRF. It is a malicious use of the website, which is known as phishing website. Although it sounds like cross-site scripting (XSS), it is very different from XSS and has almost the opposite attack style. XSS makes use of trusted users within the site, while CSRF makes use of trusted sites by disguising requests from trusted users. Compared with XSS attacks, CSRF attacks are often less prevalent (and therefore relatively scarce resources to guard against) and difficult to guard against, so they are considered to be more dangerous than XSS attacks.

What can CSRF do?

CSRF attack: The attacker steals your identity and disguises you as sending a malicious request. CSRF can do things like sending emails, sending messages, stealing your account, even buying goods, transferring virtual money in your name. Problems include personal privacy leaks and property security.

It's so powerful. What's the principle of it?

Brief Introduction of CSRF Principle

When a user visits a website, he will save the user's relevant information in cookies (session can think of encrypted cookies and then save them in cookies). Then the user visits a very dangerous website and the website will send some malicious requests using the cookies left by your previous visit to the website.

CSRF Prevention

I summarized two ways to prevent CSRF attacks: background direct processing of CSRF attacks (personal statement) and front-end ajax requests

Background handling of CSRF attacks

Simply add a hidden input form tag with a name attribute value of csrf_token and a value attribute value of {csrf_token()} to the form.

<form class="form-signin" method="post">
        <h2 class="form-signin-heading">Please login</h2>

        <input type="hidden" name="csrf_token" value="{{ csrf_token() }}">

        <label for="inputEmail" class="sr-only">Mailbox:</label>
        <input type="email" id="inputEmail" class="form-control" name="email" placeholder="Please enter your email address" required autofocus>
        <label for="inputPassword" class="sr-only">Password:</label>
        <input type="password" id="inputPassword" class="form-control" name="password" placeholder="Please input a password" required>
        <div class="checkbox">
          <label>
            <input type="checkbox" name="remember" value="1"> Remember me
          </label>
        </div>
        <button class="btn btn-lg btn-primary btn-block" type="submit">Login immediately</button>
</form>

Background csrftoken needs to be bound to app so that the parameters passed in from the front-end form will not be attacked by CSRF and post parameters can be obtained as usual (the python web framework Flask background login, which is used to deal with CSRF attacks in this way)

def create_app():
    """
    //The main entry file creates app for other blueprints
    :return: Return to one app
    """
    app = Flask(__name__)
    # Prevent csrf Injection attack
    CSRFProtect(app)
    # Registration blueprint module
    app.register_blueprint(cms_bp, url_prefix="/cms")
    app.register_blueprint(common_bp, url_prefix="/common")
    app.register_blueprint(front_bp)

    # Import configuration files
    app.config.from_object(config)
    # data base db Initialization app
    db.init_app(app)
    # Backstage login login_manager Initialization app
    cms_login_manager.init_app(app)
    return app


if __name__ == '__main__':
    app = create_app()
    app.run()

 

Front-end ajax request mode

Front-end Ajax requests are a very good way to refresh pages, but Ajax requests also have CSRF attacks. Preventing CSRF attacks is also simple, requiring only two steps:

1) Add a meta tag with name csrf-token and content {{csrf_token()}} on the current page.

<meta name="csrf-token" content="{{ csrf_token() }}">

2) Rewrite the Ajax request and return a request header containing csrftoken

'use strict';
var cpajax = {
    "get": function(args){
        args["method"] = "get";
        this.ajax(args);
    },
    "post": function(args){
        args["method"] = "post";
        this.ajax(args);
    },
    "ajax": function(args){
        this._ajaxSetup();
        $.ajax(args);
    },
    "_ajaxSetup": function(args){
        $.ajaxSetup({
            "beforeSend": function(xhr, settings){
                if(!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain){
                    var csrftoken = $("meta[name=csrf-token]").attr("content");
                    xhr.setRequestHeader("X-CSRFToken", csrftoken);
                }
            }
        });
    }
};

3) So that the front end can't use the $.post() request (which can't prevent CSRF attacks), but instead use the Ajax request we rewrote.

$(function(){
    $("#submit").on("click", function(event){
        event.preventDefault();

        var oldpwdE = $("input[name=oldpwd]");
        var newpwdE = $("input[name=newpwd]");
        var newpwd2E = $("input[name=newpwd2]");

        var oldpwd = oldpwdE.val();
        var newpwd = newpwdE.val();
        var newpwd2 = newpwd2E.val();

        //1,To be in the template meta Render a tag csrf-token
        //2,stay ajax Request header settings x-CSRFtoken
        console.log("aaaaaaa");
        cpajax.post({
            "url": "/cms/resetpwd",
            "data": {
                "oldpwd": oldpwd,
                "newpwd": newpwd,
                "newpwd2": newpwd2
            },
            "success": function(data){
                console.log(data)
            },
            "fail": function(error){
                console.log(error)
            }
        })
    })
});

Posted by phpnow on Thu, 10 Oct 2019 23:48:03 -0700