@app.route("/get_last_ip/<string:username>", methods=["GET", "POST"]) defroute_check_ip(username): ifnot current_user.is_authenticated: return"You need to login first." user = User.query.filter_by(username=username).first() ifnot user: return"User not found." return render_template("last_ip.html", last_ip=user.last_ip)
geoip2_reader = geoip2.database.Reader("GeoLite2-Country.mmdb") @app.route("/ip_detail/<string:username>", methods=["GET"]) defroute_ip_detail(username): res = requests.get(f"http://127.0.0.1/get_last_ip/{username}") if res.status_code != 200: return"Get last ip failed." last_ip = res.text try: ip = re.findall(r"\d+\.\d+\.\d+\.\d+", last_ip) country = geoip2_reader.country(ip) except (ValueError, TypeError): country = "Unknown" template = f""" <h1>IP Detail</h1> <div>{last_ip}</div> <p>Country:{country}</p> """ return render_template_string(template)
...
@app.after_request defset_last_ip(response): if current_user.is_authenticated: current_user.last_ip = request.remote_addr db.session.commit() return response
这里逻辑是先访问http://127.0.0.1/get_last_ip/{username},将获得的res.text进行了模板渲染,可以在这里构造ssti。根据最后的set_last_ip()可知last_ip可以通过XFF获取,主要问题就是request.get请求时不会带上session访问,导致每次访问都是You need to login first.