You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何防止用户篡改重发Ajax POST请求至Flask应用伪造数据?

防止Flask地理定位请求伪造的可行方案

针对你遇到的「用户篡改Geolocation坐标后重发POST请求录入虚假数据」的问题,结合你提到的现有方案缺陷,这里给出几个实用的解决思路:

  • 绑定一次性授权令牌到会话
    核心思路是让合法的坐标提交必须和「用户授权获取定位」这个行为绑定,且令牌只能用一次:

    1. 前端在用户授权定位成功后,先向Flask请求一个一次性定位令牌;
    2. 后端生成随机UUID存入用户会话,返回给前端;
    3. 前端携带坐标和令牌一起POST到/submit_location;
    4. 后端验证令牌与会话中的值匹配,验证通过后立即销毁会话中的令牌(防止复用)。

    代码示例:
    后端(Flask):

    from flask import session, jsonify, request
    import uuid
    
    @app.route('/get_location_token', methods=['GET'])
    def get_location_token():
        # 无登录场景下用临时会话标识用户,已登录可直接用用户ID
        if 'session_id' not in session:
            session['session_id'] = str(uuid.uuid4())
        # 生成一次性令牌
        token = str(uuid.uuid4())
        session['location_token'] = token
        return jsonify({'token': token})
    
    @app.route('/submit_location', methods=['POST'])
    def submit_location():
        data = request.get_json()
        submitted_token = data.get('token')
        # 验证令牌并立即销毁,避免重复使用
        if submitted_token != session.pop('location_token', None):
            return jsonify({'error': '无效或重复使用的请求'}), 403
        # 处理坐标存储逻辑
        save_coords(data['lat'], data['lng'])
        return jsonify({'status': 'success'})
    

    前端JS:

    navigator.geolocation.getCurrentPosition(async (pos) => {
        try {
            // 获取一次性令牌
            const tokenResp = await fetch('/get_location_token');
            const tokenData = await tokenResp.json();
            // 提交坐标和令牌
            await fetch('/submit_location', {
                method: 'POST',
                headers: {'Content-Type': 'application/json'},
                body: JSON.stringify({
                    lat: pos.coords.latitude,
                    lng: pos.coords.longitude,
                    token: tokenData.token
                })
            });
        } catch (err) {
            console.error('提交失败:', err);
        }
    }, (err) => {
        console.error('定位授权失败:', err);
    });
    
  • 校验坐标的合理性
    即使令牌验证通过,也可以给坐标加一层合理性校验:

    • 限制坐标在业务允许的地理范围内(比如服务只覆盖国内,就直接拒绝境外坐标);
    • 结合position.coords.accuracy字段,拒绝精度过低的坐标(比如精度大于1000米,说明定位结果不可靠);
    • 如果有用户历史位置数据,可检查是否存在不合理的位置跳转(比如1分钟内跨越大半个国家)。
  • 带时效性的请求签名
    可以在后端生成包含会话ID、时间戳的HMAC签名,前端提交时必须携带该签名:

    1. 前端请求令牌时,后端同时返回签名(用后端环境变量中的密钥生成,比如hmac.new(SECRET_KEY, f"{session_id}{timestamp}".encode(), hashlib.sha256).hexdigest());
    2. 前端提交坐标时,附带签名和时间戳;
    3. 后端重新计算签名比对,同时检查时间戳是否在有效期内(比如5分钟),防止旧请求被重发。
  • 前端行为校验辅助
    可以在前端记录一些用户操作轨迹(比如触发定位的按钮点击时间、页面停留时长),随请求一起提交,后端验证这些行为是否符合正常逻辑——比如禁止页面加载后立即提交坐标,避免脚本自动伪造请求。

这些方案组合起来,能大幅提高伪造请求的成本,同时避开你提到的现有方案的缺陷。

内容的提问来源于stack exchange,提问作者Nils Deschrijver

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 16:20:02