Beispiel #1
0
def multi_upload():
    form = MultiUploadForm()
    if request.method == 'POST':
        filenames = []
        # 验证CSRF令牌
        try:
            validate_csrf(form.csrf_token.data)
        except ValidationError:
            flash('CSRF token error.')
            return redirect(url_for('multi_upload'))
        # 检查文件是否存在
        if 'image' not in request.files:
            flash('This field is required.')
            return redirect(url_for('multi_upload'))
        for f in request.files.getlist('image'):
            # 检查文件类型
            if f and allowed_file(f.filename):
                filename = random_filename(f.filename)
                f.save(os.path.join(app.config['UPLOAD_PATH'], filename ))
                filenames.append(filename)
            else:
                flash('Invalid file type:')
                return redirect(url_for('multi_upload'))
        flash('Upload success.')
        session['filenames'] = filenames
        return redirect(url_for('show_images'))
    return render_template('upload.html', form=form)
Beispiel #2
0
def share():
    """Route for posting image data to IMGUR to share via a link."""
    img = request.values.get('data')

    try:
        validate_csrf(request.headers.get('X-Csrftoken'))
    except ValidationError as e:
        abort(400, str(e))

    result = {'success': True,
              'link': 'https://imgur.com/opoxoisdf.png'}

    # Add the authorization headers
    clientid = current_app.config['IMGUR_CLIENT_ID']
    header = {'Authorization': 'Client-ID %s' % clientid}

    # POST parameters for imgur API
    payload = {'image': img.split('base64,')[-1],
               'type': 'base64'}

    resp = requests.post('https://api.imgur.com/3/image',
                         payload, headers=header)
    respdata = json.loads(resp.text)

    if respdata['success']:
        result = {'success': respdata['success'],
                  'link': respdata['data']['link']}

        return jsonify(result), 200

    else:
        return jsonify({'success': False}), 400
Beispiel #3
0
    def post_attachment(self, workspace_name, vuln_id):
        try:
            validate_csrf(request.form.get('csrf_token'))
        except wtforms.ValidationError:
            flask.abort(403)
        vuln_workspace_check = db.session.query(VulnerabilityGeneric, Workspace.id).join(
            Workspace).filter(VulnerabilityGeneric.id == vuln_id,
                                Workspace.name == workspace_name).first()

        if vuln_workspace_check:
            if 'file' not in request.files:
                flask.abort(400)

            faraday_file = FaradayUploadedFile(request.files['file'].read())
            filename = request.files['file'].filename

            get_or_create(
                db.session,
                File,
                object_id=vuln_id,
                object_type='vulnerability',
                name=filename,
                filename=filename,
                content=faraday_file
            )
            db.session.commit()
            return flask.jsonify({'message': 'Evidence upload was successful'})
        else:
            flask.abort(404, "Vulnerability not found")
Beispiel #4
0
def multiple_file():
    form = Mutiple_File_Form()
    if request.method == 'POST':
        filenames = []  #多文件 用列表存放

        try:
            validate_csrf(form.csrf_token.data)
        except ValidationError:
            flash('CSRF WRONG!')
            return redirect(url_for('multiple_file'))

        if 'photos' not in request.files:
            flash('EMPTY FILE!')
            return redirect(url_for('multiple_file'))

        for file in request.files.getlist('photos'):
            filename = file.filename
            if file and not check_suffix(filename):
                flash('WRONG FILE TYPE!')
                return redirect(url_for('multiple_file'))
            # pass
            filename = random_filename(filename)
            file.save(os.path.join(app.config['UPLOADS_URL'], filename))
            filenames.append(filename)

        session['filenames'] = filenames
        flash('uploads success!')
        return redirect(url_for('show_multi_img'))
    return render_template('multi-file.html', form=form)
Beispiel #5
0
    def post_attachment(self, workspace_name, vuln_id):
        try:
            validate_csrf(request.form.get('csrf_token'))
        except wtforms.ValidationError:
            flask.abort(403)
        vuln_workspace_check = db.session.query(
            VulnerabilityGeneric, Workspace.id).join(Workspace).filter(
                VulnerabilityGeneric.id == vuln_id,
                Workspace.name == workspace_name).first()

        if vuln_workspace_check:
            if 'file' not in request.files:
                flask.abort(400)

            faraday_file = FaradayUploadedFile(request.files['file'].read())
            filename = request.files['file'].filename

            get_or_create(db.session,
                          File,
                          object_id=vuln_id,
                          object_type='vulnerability',
                          name=filename,
                          filename=filename,
                          content=faraday_file)
            db.session.commit()
            return flask.jsonify({'message': 'Evidence upload was successful'})
        else:
            flask.abort(404, "Vulnerability not found")
Beispiel #6
0
def edit(id):
    if request.method == 'GET':
        if id:
            service = find_service(id)
            if service:
                form = ServiceForm()
                for ff in form.__dict__:
                    for sf in service.__dict__:
                        if ff == sf:
                            if isinstance(form.__dict__[ff], TextAreaField):
                                form.__dict__[ff].process_data(
                                    service.__dict__[sf])
                return render_template('splash/actions/services/edit.html',
                                       service=service,
                                       form=form)
        return abort(404)
    else:
        form = ServiceForm(request.form)
        service = find_service(id)
        owner = service.owner_id

        category_items = service.category_items

        validate_csrf(form.csrf_token.data)

        service.__init__(**form.data)
        service.category_items = category_items
        service.owner_id = owner
        service.save()
        if find_service(id):
            return json.dumps({'success': True}), 200, {
                'ContentType': 'application/json'
            }
        return abort(400)
Beispiel #7
0
def change_count():
    # 如果用户未登录,返回相关信息给AJAX,手动处理重定向。
    # 如果交给@login_required自动重定向的话,
    # AJAX不能正确处理这个重定向
    if not current_user.is_authenticated:
        return jsonify({
            'status': 302,
            'location': url_for(
                'auth.login',
                next=request.referrer.replace(
                    url_for('.index', _external=True)[:-1], ''))
        })
    # 以post方式传的数据在存储在的request.form中,以get方式传输的在request.args中~~
    # 同理,csrf token认证也要手动解决重定向
    try:
        validate_csrf(request.headers.get('X-CSRFToken'))
    except ValidationError:
        return jsonify({
            'status': 400,
            'location': url_for(
                'auth.login',
                next=request.referrer.replace(
                    url_for('.index', _external=True)[:-1], ''))
        })
    po_id = int(request.form.get('po_id'))
    count = int(request.form.get('count'))
    ha = Have.query.filter_by(portal_id=po_id,
                              user_id=current_user.id).first()
    if ha is not None:
        ha.count = count
    else:
        ha = Have(portal_id=po_id, user_id=current_user.id, count=count)
    db.session.add(ha)
    return 'ok'
Beispiel #8
0
def multi_upload():
    form = MultiUploadForm()
    if request.method == 'POST':
        filenames = []
        try:
            validate_csrf(form.csrf_token.data)
        except ValidationError:
            flash('CSRF token 错误!')
            return redirect(url_for('multi_upload'))

        if 'photo' not in request.files:
            flash('文件不存在!')
            return redirect(url_for('multi_upload'))

        for f in request.files.getlist('photo'):
            if f and allowed_file(f.filename):
                filename = random_filename(f.filename)
                f.save(os.path.join(app.config['UPLOAD_PATH'], filename))
                filenames.append(filename)
            else:
                flash('文件无效!')
                return redirect(url_for('multi_upload'))
        flash('上传成功!')
        session['filenames'] = filenames
        return redirect(url_for('show_images'))
    return render_template('upload_file.html', form=form)
Beispiel #9
0
def favorites_delete(siret):
    """
    Delete an office from the favorites of a user.
    """

    # Since we are not using a FlaskForm but a hidden input with the token in the
    # form, CSRF validation has to be done manually.
    # CSRF validation can be disabled globally (e.g. in unit tests), so ensure that
    # `WTF_CSRF_ENABLED` is enabled before.
    if current_app.config['WTF_CSRF_ENABLED']:
        csrf.validate_csrf(request.form.get('csrf_token'))

    fav = UserFavoriteOffice.query.filter_by(office_siret=siret,
                                             user_id=current_user.id).first()
    if not fav:
        abort(404)

    fav.delete()

    message = u'"%s - %s" a été supprimé de vos favoris !' % (fav.office.name,
                                                              fav.office.city)
    flash(message, 'success')

    next_url = request.form.get('next')
    if next_url and is_safe_url(next_url):
        return redirect(urllib.unquote(next_url))

    return redirect(url_for('user.favorites_list'))
Beispiel #10
0
def favorites_add(siret):
    """
    Add an office to the favorites of a user.
    """

    # Since we are not using a FlaskForm but a hidden input with the token in the
    # form, CSRF validation has to be done manually.
    # CSRF validation can be disabled globally (e.g. in unit tests), so ensure that
    # `WTF_CSRF_ENABLED` is enabled before.
    if current_app.config['WTF_CSRF_ENABLED']:
        csrf.validate_csrf(request.form.get('csrf_token'))

    office = Office.query.filter_by(siret=siret).first()
    if not office:
        abort(404)

    UserFavoriteOffice.get_or_create(user=current_user, office=office)

    message = u'"%s - %s" a été ajouté à vos favoris !' % (office.name,
                                                           office.city)
    flash(Markup(message), 'success')

    next_url = request.form.get('next')
    if next_url and is_safe_url(next_url):
        return redirect(urllib.unquote(next_url))

    return redirect(url_for('user.favorites_list'))
Beispiel #11
0
def share():
    """Route for posting image data to IMGUR to share via a link."""
    img = request.values.get('data')

    try:
        validate_csrf(request.headers.get('X-Csrftoken'))
    except ValidationError as e:
        abort(400, str(e))

    result = {'success': True,
              'link': 'https://imgur.com/opoxoisdf.png'}

    # Add the authorization headers
    clientid = current_app.config['IMGUR_CLIENT_ID']
    header = {'Authorization': 'Client-ID %s' % clientid}

    # POST parameters for imgur API
    payload = {'image': img.split('base64,')[-1],
               'type': 'base64'}

    resp = requests.post('https://api.imgur.com/3/image',
                         payload, headers=header)
    respdata = json.loads(resp.text)

    if respdata['success']:
        result = {'success': respdata['success'],
                  'link': respdata['data']['link']}

        return jsonify(result), 200

    else:
        return jsonify({'success': False}), 400
Beispiel #12
0
def multi_upload():
    form = MultiUploadForm()

    if request.method == 'POST':
        filenames = []

        # check csrf token
        try:
            validate_csrf(form.csrf_token.data)
        except ValidationError:
            flash('CSRF token error.')
            return redirect(url_for('multi_upload'))

        photos = request.files.getlist('photo')
        # check if user has selected files. If not, the browser
        # will submit an empty file part without filename
        if not photos[0].filename:
            flash('No selected file.')
            return redirect(url_for('multi_upload'))

        for f in photos:
            # check the file extension
            if f and allowed_file(f.filename):
                filename = random_filename(f.filename)
                f.save(os.path.join(app.config['UPLOAD_PATH'], filename))
                filenames.append(filename)
            else:
                flash('Invalid file type.')
                return redirect(url_for('multi_upload'))
        flash('Upload success.')
        session['filenames'] = filenames
        return redirect(url_for('show_images'))
    return render_template('upload.html', form=form)
def get_data():
    payload = request.get_json()
    if not payload:
        raise Exception("No payload provided")
    page = int(payload['page']) or 1
    num_rows = int(payload['num_rows']) or 10

    csrf_token = request.headers.get('X-CSRFToken')
    validate_csrf(csrf_token)

    conn = sqlite3.connect('data.db')
    total = int(
        pd.read_sql_query('select count(*) from data', conn).iloc[0][0])

    offset = (page - 1) * num_rows
    df = pd.read_sql_query('select * from data limit (?), (?)',
                           conn,
                           params=(
                               offset,
                               num_rows,
                           ))
    df = df[df.columns[1:].tolist()]

    res = dict(total=total,
               columns=df.columns.tolist(),
               page=page,
               pagination=[5, 10, 20],
               num_rows=num_rows,
               data=df.to_dict(orient="records"))

    return Response(json.dumps(res), mimetype="application/json")
Beispiel #14
0
def check_csrf():
    """Verifies one of the following is true, or aborts with 400.

  a) the request includes a valid CSRF token
  b) the origin is explicitly allowed
  c) the request includes a valid internal token
  """
    if request.method in ['OPTIONS', 'GET']:
        return

    try:
        validate_csrf(request.headers.get('X-CSRFToken'))

        return
    except ValidationError:
        pass

    if request.headers.get('origin') in ADDITIONAL_ALLOWED_ORIGINS:
        return

    if request.path in csrf_exempt_paths:
        return

    try:
        validate_internal_request(request)

        return
    except InvalidInternalToken:
        pass

    abort(400, 'Invalid CSRF token.')
Beispiel #15
0
def check_csrf():
    has_auth = "Authorization" in flask.request.headers
    no_username = not flask.session.get("username")
    if has_auth or no_username:
        return
    if not config.get("ENABLE_CSRF_PROTECTION", True):
        return
    if flask.request.method != "GET":
        try:
            csrf_header = flask.request.headers.get("x-csrf-token")
            csrf_formfield = flask.request.form.get("csrf_token")
            # validate_csrf checks the input (a signed token) against the raw
            # token stored in session["csrf_token"].
            # (session["csrf_token"] is managed by flask-wtf.)
            # To pass CSRF check, there must exist EITHER an x-csrf-token header
            # OR a csrf_token form field that matches the token in the session.
            assert (csrf_header and validate_csrf(csrf_header) is None or
                    csrf_formfield and validate_csrf(csrf_formfield) is None)

            referer = flask.request.headers.get("referer")
            assert referer, "Referer header missing"
            logger.debug("HTTP REFERER " + str(referer))
        except Exception as e:
            raise UserError(
                "CSRF verification failed: {}. Request aborted".format(e))
Beispiel #16
0
def login_callback():
    code = flask.request.args["code"]
    state = flask.request.args["state"]

    # Avoid CSRF attacks
    validate_csrf(state)

    discharged_token = candid.discharge_token(code)
    candid_macaroon = candid.discharge_macaroon(
        flask.session["publisher-macaroon"], discharged_token)

    # Store bakery authentication
    flask.session["macaroons"] = candid.get_serialized_bakery_macaroon(
        flask.session["publisher-macaroon"], candid_macaroon)

    try:
        publisher = publisher_api.whoami(flask.session)
    except StoreApiResponseErrorList as api_response_error_list:
        return _handle_error_list(api_response_error_list.errors)
    except (StoreApiError, ApiError) as api_error:
        return _handle_error(api_error)

    # whoami is the only Dashboard API endpoint
    # that support Candid.
    return publisher
Beispiel #17
0
def multi():
    form = MultiUploadPhoto()
    if request.method == "POST":
        filenames = []
        #验证CSRF令牌
        try:
            validate_csrf(form.csrf_token.data)
        except:
            flash('CSRF token error')
            return redirect(url_for('multi'))
        #检查文件是否存在
        if 'photo' not in request.files:
            flash("this field is required")
            redirect(url_for('multi'))

        for f in request.files.getlist('photo'):
            # 检查文件类型
            if f and allowed_file(f.filename):
                filename = random_filename(f.filename)
                f.save(os.path.join(app.config['UPLOAD_PATH'], filename))
                filenames.append(filename)
            else:
                flash("Invalid file type")
                return redirect(url_for('multi'))
        flash("Upload success")
        flash(filenames)
        session['photonames'] = filenames
        flash(session["photonames"])
        flash("show start")
        return redirect(url_for('showphoto'))
    return render_template('uploadphoto.html', form=form)
Beispiel #18
0
def login_callback():
    code = flask.request.args["code"]
    state = flask.request.args["state"]

    # Avoid CSRF attacks
    validate_csrf(state)

    discharged_token = candid.discharge_token(code)
    candid_macaroon = candid.discharge_macaroon(
        flask.session["publisher-macaroon"], discharged_token
    )

    # Store bakery authentication
    flask.session["publisher-auth"] = candid.get_serialized_bakery_macaroon(
        flask.session["publisher-macaroon"], candid_macaroon
    )

    flask.session["publisher"] = publisher_api.whoami(
        flask.session["publisher-auth"]
    )

    return flask.redirect(
        flask.session.pop(
            "next_url",
            "/charms",
        ),
        302,
    )
def favorites_add(siret: str, rome_code: Optional[str] = None):
    """
    Add an office to the favorites of a user.
    """
    # Since we are not using a FlaskForm but a hidden input with the token in the
    # form, CSRF validation has to be done manually.
    # CSRF validation can be disabled globally (e.g. in unit tests), so ensure that
    # `WTF_CSRF_ENABLED` is enabled before.
    if current_app.config['WTF_CSRF_ENABLED']:
        csrf.validate_csrf(request.form.get('csrf_token'))

    office = Office.query.filter_by(siret=siret).first()
    if not office:
        abort(404)

    UserFavoriteOffice.add_favorite(user=current_user,
                                    office=office,
                                    rome_code=rome_code)

    message = '"%s - %s" a été ajouté à vos favoris !' % (office.name,
                                                          office.city)
    flash(Markup(message), 'success')
    activity.log('ajout-favori', siret=siret)

    return get_redirect_after_favorite_operation()
Beispiel #20
0
    def bulk_create(self, workspace_name):
        try:
            validate_csrf(flask.request.form.get('csrf_token'))
        except wtforms.ValidationError:
            flask.abort(403)

        def parse_hosts(list_string):
            items = re.findall(r"([.a-zA-Z0-9_-]+)", list_string)
            return items

        workspace = self._get_workspace(workspace_name)

        logger.info("Create hosts from CSV")
        if 'file' not in flask.request.files:
            abort(400, "Missing File in request")
        hosts_file = flask.request.files['file']
        stream = StringIO(hosts_file.stream.read().decode("utf-8"),
                          newline=None)
        FILE_HEADERS = {'description', 'hostnames', 'ip', 'os'}
        try:
            hosts_reader = csv.DictReader(stream)
            if set(hosts_reader.fieldnames) != FILE_HEADERS:
                logger.error("Missing Required headers in CSV (%s)",
                             FILE_HEADERS)
                abort(400,
                      "Missing Required headers in CSV (%s)" % FILE_HEADERS)
            hosts_created_count = 0
            hosts_with_errors_count = 0
            for host_dict in hosts_reader:
                try:
                    hostnames = parse_hosts(host_dict.pop('hostnames'))
                    other_fields = {
                        'owned': False,
                        'mac': u'00:00:00:00:00:00',
                        'default_gateway_ip': u'None'
                    }
                    host_dict.update(other_fields)
                    host = super(HostsView,
                                 self)._perform_create(host_dict,
                                                       workspace_name)
                    host.workspace = workspace
                    for name in hostnames:
                        get_or_create(db.session,
                                      Hostname,
                                      name=name,
                                      host=host,
                                      workspace=host.workspace)
                    db.session.commit()
                except Exception as e:
                    logger.error("Error creating host (%s)", e)
                    hosts_with_errors_count += 1
                else:
                    logger.debug("Host Created (%s)", host_dict)
                    hosts_created_count += 1
            return make_response(
                jsonify(hosts_created=hosts_created_count,
                        hosts_with_errors=hosts_with_errors_count), 200)
        except Exception as e:
            logger.error("Error parsing hosts CSV (%s)", e)
            abort(400, "Error parsing hosts CSV (%s)" % e)
Beispiel #21
0
def multi_upload():
    form = MultiUploadForm()

    if form.validate_on_submit():
        filenames = []
        # check csrf token
        try:
            validate_csrf(form.csrf_token.data)
        except ValidationError:
            flash('CSRF token error.')
            return redirect(url_for('multi_upload'))

        photos = form.photo.data
        if not photos[0].filename:
            flash('No selected fle.')
            return redirect(url_for('multi_upload'))
        for f in photos:
            if f and allowed_file(f.filename):
                filename = random_filename(f.filename)
                f.save(os.path.join(app.config['UPLOAD_PATH'], filename))
                filenames.append(filename)
            else:
                flash('Invalid file type.')
                return redirect(url_for('multi_upload'))
        flash('Upload success')
        session['filenames'] = filenames
        return redirect(url_for('show_images'))
    return render_template('upload.html', form=form)
Beispiel #22
0
def multi_upload():
    form = MultiUploadForm()
    if request.method == 'POST':
        filenames = []
        # 验证CSRF令牌
        try:
            validate_csrf(form.csrf_token.data)
        except:
            flash('CSRF token error.')
            return redirect(url_for('multi_upload'))
        # 检查文件是否存在
        # 如果用户没有选择文件就提交表单则request.files为空,相当于FileRequired验证器
        if 'photo' not in request.files:
            flash('This field is required.')
            return redirect(url_for('multi_upload'))

        # 传入字段的name属性值会返回包含所有上传文件对象的列表
        for f in request.files.getlist('photo'):
            # 检查文件类型
            # 相当于FileAllowed验证器
            if f and allowed_file(f.filename):
                filename = random_filename(f.filename)
                f.save(os.path.join(app.config['UPLOAD_PATH'], filename))
                filenames.append(filename)
            else:
                flash('Invalid file type.')
                return redirect(url_for('multi_upload'))
        flash('Upload success!')
        session['filenames'] = filenames
        return redirect(url_for('show_images'))
    return render_template('upload.html', form=form)
Beispiel #23
0
def admin_login():
    if request.method == 'POST':
        form = LoginForm(request.form)
        validate_csrf(form.csrf_token)
        account = Account.query.filter_by(username=form.username.data, password=generate_hash_pass(form.username.data, form.password.data)).first()
        if account:
            login_user(account)
            account.set_status(online=True).save()
            return redirect(url_for('admin.index'), code=302)
        else:
            return json.dumps(
                {
                    'success': False
                }
            ), 401, {'ContentType':'application/json'}
    else:
        if current_user.is_authenticated and current_user.is_staff():
            redirect(url_for('admin.index'))
            return json.dumps(
                {
                    'success': False
                }
            ), 302, {'ContentType':'application/json'}
        
        print('Rendering page')
        return render_template('admin/pages/login.html', form=LoginForm())
def file_upload(workspace=None):
    """
    Upload a report file to Server and process that report with Faraday client plugins.
    """
    logger.info("Importing new plugin report in server...")
    # Authorization code copy-pasted from server/api/base.py
    ws = Workspace.query.filter_by(name=workspace).first()
    if not ws or not ws.active:
        # Don't raise a 403 to prevent workspace name enumeration
        abort(404, "Workspace disabled: %s" % workspace)

    if 'file' not in request.files:
        abort(400)

    try:
        validate_csrf(request.form.get('csrf_token'))
    except ValidationError:
        abort(403)

    report_file = request.files['file']

    if report_file:

        chars = string.ascii_uppercase + string.digits
        random_prefix = ''.join(random.choice(chars)
                                for x in range(12))  # nosec
        raw_report_filename = '{0}_{1}'.format(
            random_prefix, secure_filename(report_file.filename))

        try:
            file_path = os.path.join(CONST_FARADAY_HOME_PATH,
                                     'uploaded_reports', raw_report_filename)
            with open(file_path, 'wb') as output:
                output.write(report_file.read())
        except AttributeError:
            logger.warning(
                "Upload reports in WEB-UI not configurated, run Faraday client and try again..."
            )
            abort(
                make_response(
                    jsonify(
                        message=
                        "Upload reports not configurated: Run faraday client and start Faraday server again"
                    ), 500))
        else:
            logger.info("Get plugin for file: %s", file_path)
            plugin = report_analyzer.get_plugin(file_path)
            if not plugin:
                logger.info("Could not get plugin for file")
                abort(
                    make_response(jsonify(message="Invalid report file"), 400))
            else:
                logger.info("Plugin for file: %s Plugin: %s", file_path,
                            plugin.id)
                REPORTS_QUEUE.put(
                    (workspace, file_path, plugin.id, flask.g.user))
                return make_response(jsonify(message="ok"), 200)
    else:
        abort(make_response(jsonify(message="Missing report file"), 400))
Beispiel #25
0
def delete_message(id):
    try:
        validate_csrf(request.form.get("csrf_token"))
        db.session.delete(Message.query.get(id))
        db.session.commit()
        return redirect(url_for("index"))
    except ValidationError:
        return redirect(url_for("index"))
def validate_csrf_token():
    post = request.method == "POST"
    patch = request.method == "PATCH"
    delete = request.method == "DELETE"
    if post or patch or delete:
        print("")
        csrf_token = request.headers.get("X-CSRFToken")
        validate_csrf(csrf_token)
Beispiel #27
0
def csrf_cookie_handler(response):
    """ Called at end of every request.
    Uses session to track state (set/clear)

    Ideally we just need to set this once - however by default
    Flask-WTF has a time-out on these tokens governed by `WTF_CSRF_TIME_LIMIT`.
    While we could set that to None - and OWASP implies this is fine - that might
    not be agreeable to everyone.
    So as a basic usability hack - we check if it is expired and re-generate so at least
    the user doesn't have to log out and back in (just refresh).
    We also support a `CSRF_COOKIE_REFRESH_EACH_REQUEST` analogous to Flask's
    `SESSION_REFRESH_EACH_REQUEST`

    It is of course removed on logout/session end.
    Other info on web suggests replacing on every POST and accepting up to 'age' ago.
    """
    csrf_cookie = config_value("CSRF_COOKIE")
    if not csrf_cookie or not csrf_cookie["key"]:
        return response

    op = session.get("fs_cc", None)
    if not op:
        return response

    if op == "clear":
        response.delete_cookie(
            csrf_cookie["key"],
            path=csrf_cookie.get("path", "/"),
            domain=csrf_cookie.get("domain", None),
        )
        session.pop("fs_cc")
        return response

    # Send a cookie if any of:
    # 1) CSRF_COOKIE_REFRESH_EACH_REQUEST is true
    # 2) fs_cc == "set" - this is on first login
    # 3) existing cookie has expired
    send = False
    if op == "set":
        send = True
        session["fs_cc"] = "sent"
    elif config_value("CSRF_COOKIE_REFRESH_EACH_REQUEST"):
        send = True
    elif current_app.config["WTF_CSRF_TIME_LIMIT"]:
        current_cookie = request.cookies.get(csrf_cookie["key"], None)
        if current_cookie:
            # Lets make sure it isn't expired if app doesn't set TIME_LIMIT to None.
            try:
                csrf.validate_csrf(current_cookie)
            except ValidationError:
                send = True

    if send:
        kwargs = {k: v for k, v in csrf_cookie.items()}
        kwargs.pop("key")
        kwargs["value"] = csrf.generate_csrf()
        response.set_cookie(csrf_cookie["key"], **kwargs)
    return response
Beispiel #28
0
    def bulk_create(self):
        try:
            validate_csrf(request.form.get('csrf_token'))
        except wtforms.ValidationError:
            abort(403)
        logger.info("Create vulns template from CSV")
        if 'file' not in request.files:
            abort(400, "Missing File in request")
        vulns_file = request.files['file']
        required_headers = {'name', 'exploitation'}
        io_wrapper = TextIOWrapper(vulns_file,
                                   encoding=request.content_encoding or "utf8")

        vulns_reader = csv.DictReader(io_wrapper, skipinitialspace=True)
        intersect_required = set(
            vulns_reader.fieldnames).intersection(required_headers)
        if intersect_required != required_headers:
            logger.error("Missing Required headers in CSV (%s)",
                         required_headers - intersect_required)
            abort(
                400, "Missing Required headers in CSV (%s)" %
                (required_headers - intersect_required))
        custom_fields = [
            custom_field_schema.field_name for custom_field_schema in
            db.session.query(CustomFieldsSchema).all()
        ]
        vulns_created_count = 0
        vulns_with_errors_count = 0
        schema = self.schema_class()
        for index, vuln_dict in enumerate(vulns_reader):
            vuln_dict['customfields'] = {}
            vuln_dict['impact'] = {}
            for key in vuln_dict.keys():
                if key in custom_fields:
                    vuln_dict['customfields'][key] = vuln_dict[key]

            vuln_dict['impact']['accountability'] = vuln_dict.get(
                'accountability', False)
            vuln_dict['impact']['availability'] = vuln_dict.get(
                'availability', False)
            vuln_dict['impact']['confidentiality'] = vuln_dict.get(
                'confidentiality', False)
            vuln_dict['impact']['integrity'] = vuln_dict.get(
                'integrity', False)
            try:
                vuln_schema = schema.load(vuln_dict)
                super(VulnerabilityTemplateView,
                      self)._perform_create(vuln_schema)
                db.session.commit()
            except ValidationError as e:
                logger.error("Error creating vuln from line (%s): (%s)",
                             str(index), e)
                vulns_with_errors_count += 1
            else:
                vulns_created_count += 1
        return make_response(
            jsonify(vulns_created=vulns_created_count,
                    vulns_with_errors=vulns_with_errors_count), 200)
Beispiel #29
0
def delete(id):
    try:
        validate_csrf(request.form.get('csrf_token'))
        db.session.delete(Employee.query.get(id))
        db.session.commit()
    except ValidationError:
        pass
    finally:
        return redirect(url_for('employees.index'))
def ajax_simple(field):
    if (request.method == "GET"):
        if validate_csrf(request.headers.get(CSRF_TOKEN_H, None)):
            return backend.ajax_get(request, field, timeout=60 * 30)
    elif (request.method == "POST"):
        if validate_csrf(request.headers.get(CSRF_TOKEN_H, None)):
            return backend.ajax_batch_post(request, field, timeout=60 * 30)
    else:
        abort(403)
Beispiel #31
0
def delete(id):
    try:
        validate_csrf(request.form.get("csrf_token"))
        tag = Tag.query.get(id)
        db.session.delete(tag)
        db.session.commit()
        return redirect(url_for("tags.index"))
    except ValidationError:
        return redirect(url_for("tags.index"))
Beispiel #32
0
 def __init__(self, name, csrf_token="", skip_csrf_check=False):
     self.name = name
     if not skip_csrf_check:
         if not csrf_token or csrf_token is None:
             raise TypeError(
                 '__init__() missing 1 required positional argument: \'csrf_token\''
             )
         validate_csrf(csrf_token)
         self.csrf_token = csrf_token
Beispiel #33
0
    def test_csrf_custom_token_key(self):
        with self.app.test_request_context():
            # Generate a normal and a custom CSRF token
            default_csrf_token = generate_csrf()
            custom_csrf_token = generate_csrf(token_key='oauth_state')

            # Verify they are different due to using different session keys
            self.assertNotEqual(default_csrf_token, custom_csrf_token)

            # However, the custom key can validate as well
            validate_csrf(custom_csrf_token, token_key='oauth_state')
Beispiel #34
0
        def _csrf_protect():
            # many things come from django.middleware.csrf
            if not app.config['WTF_CSRF_ENABLED']:
                return

            if request.method not in app.config['WTF_CSRF_METHODS']:
                return

            if self._exempt_views or self._exempt_blueprints:
                if not request.endpoint:
                    return

                if request.endpoint in self._exempt_views:
                    return
                if request.blueprint in self._exempt_blueprints:
                    return

            if not validate_csrf(_get_csrf_token()):
                reason = 'CSRF token missing or incorrect.'
                return self._error_response(reason)

            if request.is_secure and app.config['WTF_CSRF_SSL_STRICT']:
                if not request.referrer:
                    reason = 'Referrer checking failed - no Referrer.'
                    return self._error_response(reason)

                good_referrer = 'https://%s/' % request.host
                if not same_origin(request.referrer, good_referrer):
                    reason = 'Referrer checking failed - origin not match.'
                    return self._error_response(reason)

            request.csrf_valid = True  # mark this request is csrf valid
Beispiel #35
0
def ajax_statistics():
    if validate_csrf(request.headers.get(CSRF_TOKEN_H, None)):
        return backend.ajax_get(
            request,
            app_conf_get("STATISTICS_API_ENDPOINT"), timeout=60 * 60 * 1)
    else:
        abort(403)
def logout(user):
    """Clear the session, and redirect to home."""
    if not validate_csrf(request.args.get('token', '')):
        flash('Missing or incorrect CSRF token.')
        abort(400)
    session.clear()
    flash('You have been logged out.', 'info')
    return redirect(url_for('.home_page'), code=303)
Beispiel #37
0
def file_upload(workspace=None):
    """
    Upload a report file to Server and process that report with Faraday client plugins.
    """
    get_logger(__name__).debug("Importing new plugin report in server...")

    # Authorization code copy-pasted from server/api/base.py
    ws = Workspace.query.filter_by(name=workspace).one()
    if not (ws.active
            ):
        # Don't raise a 403 to prevent workspace name enumeration
        abort(404, "Workspace disabled: %s" % workspace)

    if 'file' not in request.files:
        abort(400)

    try:
        validate_csrf(request.form.get('csrf_token'))
    except ValidationError:
        abort(403)

    report_file = request.files['file']

    if report_file.filename == '':
        abort(400)

    if report_file:

        chars = string.ascii_uppercase + string.digits
        random_prefix = ''.join(random.choice(chars) for x in range(12))
        raw_report_filename = '{0}{1}'.format(random_prefix, secure_filename(report_file.filename))

        try:
            file_path = os.path.join(
                CONF.getConfigPath(),
                'uploaded_reports/{0}'.format(raw_report_filename))
        except AttributeError:
            get_logger().warning(
                "Upload reports in WEB-UI not configurated, run Faraday client and try again...")
            abort(make_response(jsonify(message="Upload reports not configurated: Run faraday client and start Faraday server again"), 500))

        with open(file_path, 'w') as output:
            output.write(report_file.read())

    UPLOAD_REPORTS_QUEUE.put((workspace, file_path, request.cookies))
    return make_response(jsonify(message="ok"), 200)
Beispiel #38
0
def ajax_count(collection=None):
    if validate_csrf(request.headers.get(CSRF_TOKEN_H, None)):
        return backend.ajax_count_get(
            request, app_conf_get("COUNT_API_ENDPOINT"),
            collection,
            timeout=60 * 60
        )
    else:
        abort(403)
Beispiel #39
0
def ajax_batch():
    if validate_csrf(request.headers.get(CSRF_TOKEN_H, None)):
        if request.data:
            return backend.ajax_batch_post(
                request, app_conf_get("BATCH_API_ENDPOINT"), timeout=60 * 20)
        else:
            abort(400)
    else:
        abort(403)
Beispiel #40
0
def ajax_distinct(resource, field):
    if validate_csrf(request.headers.get(CSRF_TOKEN_H, None)):
        # Workaround because the backend uses /test/group/...
        if (resource == "group"):
            resource = "test/group"
        return backend.ajax_get(
            request, "/%s/distinct" % resource, doc_id=field, timeout=60 * 30)
    else:
        abort(403)
Beispiel #41
0
def ajax_version():
    if validate_csrf(request.headers.get(CSRF_TOKEN_H, None)):
        # Cache the version for two days, hard for it to change that often.
        return backend.ajax_get(
            request,
            app_conf_get("VERSION_API_ENDPOINT"),
            timeout=60*60*24*2)
    else:
        abort(400)
Beispiel #42
0
def ajax_bisect_call(doc_id=None):
    if validate_csrf(request.headers.get(CSRF_TOKEN_H, None)):
        return backend.ajax_bisect(
            request,
            doc_id,
            app_conf_get("BISECT_API_ENDPOINT"),
            timeout=60 * 60 * 4
        )
    else:
        abort(403)
Beispiel #43
0
def ajax_job_logs(doc_id=None):
    if validate_csrf(request.headers.get(CSRF_TOKEN_H, None)):
        if doc_id:
            api_path = app_conf_get("JOB_ID_LOGS_ENPOINT")
        else:
            api_path = app_conf_get("JOB_LOGS_ENPOINT")
        return backend.ajax_logs(
            request, api_path, doc_id=doc_id, timeout=60 * 60 * 3)
    else:
        abort(403)
Beispiel #44
0
def process_callback(callback_uri):
    code = request.args.get('code')
    state = request.args.get('state')
    error = request.args.get('error')
    error_desc = request.args.get('error_description', '')

    if error:
        return {'error': 'GitHub auth canceled or failed with error: {}, '
                'description: {}'.format(error, error_desc)}

    if not validate_csrf(state):
        return {'error': 'csrf token mismatch in GitHub callback.'}

    r = requests.post('https://github.com/login/oauth/access_token', data={
        'client_id': current_app.config['GITHUB_CLIENT_ID'],
        'client_secret': current_app.config['GITHUB_CLIENT_SECRET'],
        'code': code,
        'redirect_uri': callback_uri,
        'state': state,
    })

    payload = parse_qs(r.text)
    current_app.logger.debug('auth responses from GitHub %s', payload)
    access_token = payload['access_token'][0]

    r = requests.get('https://api.github.com/user', headers={
        'Authorization': 'token ' + access_token,
    })

    user_info = r.json()
    user_id = str(user_info.get('id'))

    account = Account.query.filter_by(
        service='github', user_id=user_id).first()

    if not account:
        account = Account(service='github', user_id=user_id)
        db.session.add(account)

    account.username = user_info.get('login')
    account.token = access_token
    account.user_info = user_info

    account.update_sites([GitHub(
        url='https://github.com/{}'.format(account.username),
        # overloading "domain" to really mean "user's canonical url"
        domain='github.com/{}'.format(account.username),
        site_id=account.user_id)])

    db.session.commit()
    util.set_authed(account.sites)

    return {'account': account}
Beispiel #45
0
    def test_csrf_url_safe(self):
        with self.app.test_request_context():
            # Generate a normal and URL safe CSRF token
            default_csrf_token = generate_csrf()
            url_safe_csrf_token = generate_csrf(url_safe=True)

            # Verify they are not the same and the URL one is truly URL safe
            assert default_csrf_token != url_safe_csrf_token
            assert '#' not in url_safe_csrf_token
            assert re.match(r'^[a-f0-9]+--[a-f0-9]+$', url_safe_csrf_token)

            # Verify we can validate our URL safe key
            assert validate_csrf(url_safe_csrf_token, url_safe=True)
Beispiel #46
0
def multi_upload():
    form = MultiUploadForm()

    if request.method == 'POST':
        filenames = []

        # check csrf token
        try:
            validate_csrf(form.csrf_token.data)
        except ValidationError:
            flash('CSRF token error.')
            return redirect(url_for('multi_upload'))

        # check if the post request has the file part
        if 'photo' not in request.files:
            flash('This field is required.')
            return redirect(url_for('multi_upload'))

        for f in request.files.getlist('photo'):
            # if user does not select file, browser also
            # submit a empty part without filename
            # if f.filename == '':
            #     flash('No selected file.')
            #    return redirect(url_for('multi_upload'))
            # check the file extension
            if f and allowed_file(f.filename):
                filename = random_filename(f.filename)
                f.save(os.path.join(
                    app.config['UPLOAD_PATH'], filename
                ))
                filenames.append(filename)
            else:
                flash('Invalid file type.')
                return redirect(url_for('multi_upload'))
        flash('Upload success.')
        session['filenames'] = filenames
        return redirect(url_for('show_images'))
    return render_template('upload.html', form=form)
Beispiel #47
0
def votepage(election_id):
    if request.method == 'GET':
        if db.elections.find({'_id': ObjectId(election_id),
            'voters': session.get('email_address', None)}).count() > 0:
            flash(u'Usted ya votó en ésta elección')
            return redirect(url_for('index'))

        selected_election = db.elections.find_one({
                '_id': ObjectId(election_id),
                'selectedCampus': session.get('campus', None)
                },
            projection=['date_from', 'date_until', 'reason', 'electionOptions'],)

        if selected_election is None:
            abort(404)
        else:
            return render_template('elections/vote.html', election=selected_election)
    elif request.method == 'POST' and request.is_xhr:
        if db.elections.find({'_id': ObjectId(election_id),
            'voters': session.get('email_address', None)}).count() > 0:
            return u'Ya votó en dicha elección', 403
        if not csrf.validate_csrf(request.headers['X-CSRF-Token'], None):
            return u'Falta token CSRF', 401
        else:
            vote = request.get_json()
            election_options = db.elections.find_one({
                '_id': ObjectId(election_id),
                'electionOptions.name': unicode(vote.get('selectedOption', None)),
                'selectedCampus': session.get('campus', None)
                }, projection=['electionOptions.name'])

            if election_options is None:
                return u'La opción para la votación no existe o no existe la votación', 404

            db.elections.update_one({'_id': ObjectId(election_id)},
                {
                    '$inc': {'totalVoters': 1},
                    '$push': {
                        'voters': session.get('email_address', None),
                        'votes': {
                                'election': vote['selectedOption'],
                                'date': datetime.now()
                        }
                    }
                }, upsert=True
            )

            return u'Exito', 200
    else:
        return u'No se puede procesar respuesta', 405
Beispiel #48
0
def _check_user_permission(required_tokens, user):
    if "CSRF" not in request.headers:
        return False
    if not csrf.validate_csrf(request.headers.get("CSRF")):
        return False

    for token in required_tokens:
        if not user.has_permission(access_tokens[token]['permission']):
            return False

    request.api_user_method = "browser_session"
    request.api_user = current_user
    request.api_user_name = current_user.name
    return True
Beispiel #49
0
def ajax_compare(doc_id, api):
    if validate_csrf(request.headers.get(CSRF_TOKEN_H, None)):
        api_path = app_conf_get(api)
        if request.method == "GET":
            return backend.ajax_get(
                request, api_path, doc_id=doc_id, timeout=60 * 60 * 2)
        elif any([request.method == "POST", request.method == "OPTIONS"]):
            if request.data:
                return backend.ajax_batch_post(
                    request, api_path, timeout=60 * 60 * 2)
            else:
                abort(400)
        else:
            abort(405)
    else:
        abort(403)
Beispiel #50
0
def delete_account():
    sent_csrf_token = request.args.get("csrf_token")
    if sent_csrf_token != None:
        sent_csrf_token = sent_csrf_token.replace("-", "#")

    if not validate_csrf(sent_csrf_token):
        return csrf_error()

    username = session.get("username")
    if username != None:
        Bill.delete().where(Bill.creator == username).execute()
        QRCode.delete().where(QRCode.creator == username).execute()
        User.delete().where(User.username == username).execute()
        logout_user()
        return render_template(
            "generic.html",
            message="""
        Your account and all associated bills have been deleted. You may recreate
         your account by simply logging back in.
        """,
        )
    else:
        return must_be_logged_in()
Beispiel #51
0
def process_callback(redirect_uri):
    code = request.args.get('code')
    error = request.args.get('error')

    if error:
        return {'error': 'Blogger authorization canceled or '
                'failed with error: {}' .format(error)}

    if not validate_csrf(request.args.get('state')):
        return {'error': 'csrf token mismatch in blogger callback.'}

    r = requests.post(API_TOKEN_URL, data={
        'code': code,
        'client_id': current_app.config['GOOGLE_CLIENT_ID'],
        'client_secret': current_app.config['GOOGLE_CLIENT_SECRET'],
        'redirect_uri': redirect_uri,
        'grant_type': 'authorization_code',
    })

    if util.check_request_failed(r):
        return {'error': 'failed to validate access token'}

    current_app.logger.info('Got Blogger access token response: %s', r.text)

    payload = r.json()
    access_token = payload.get('access_token')
    expires_in = payload.get('expires_in')
    refresh_token = payload.get('refresh_token')

    if expires_in:
        expiry = datetime.datetime.utcnow() + datetime.timedelta(
            seconds=int(expires_in))
    else:
        expiry = None

    current_app.logger.info(
        'Got Blogger access token: %s. expiry: %s. refresh token: %s',
        access_token, expiry, refresh_token)

    r = requests.get(API_SELF_URL, headers={
        'Authorization': 'Bearer ' + access_token,
    })

    if util.check_request_failed(r):
        return {'error': 'failed to fetch {}'.format(API_SELF_URL)}

    payload = r.json()
    username = user_id = payload.get('id')

    # find or create the account
    account = Account.lookup_by_user_id(SERVICE_NAME, user_id)

    if not account:
        account = Account(service=SERVICE_NAME, user_id=user_id)
        db.session.add(account)

    account.username = username
    account.user_info = payload
    account.token = access_token
    account.refresh_token = refresh_token
    account.expiry = expiry

    r = requests.get(API_BLOGS_URL, headers={
        'Authorization': 'Bearer ' + account.token,
    })

    if util.check_request_failed(r):
        return redirect(url_for('views.index'))

    payload = r.json()
    blogs = payload.get('items', [])

    # find or create the sites
    sites = []
    for blog in blogs:
        sites.append(Blogger(
            url=blog.get('url'),
            domain=util.domain_for_url(blog.get('url')),
            site_id=blog.get('id'),
            site_info=blog))
    account.update_sites(sites)

    db.session.commit()
    util.set_authed(account.sites)
    return {'account': account}
Beispiel #52
0
 def test_validate_csrf(self):
     with self.app.test_request_context():
         self.assertRaises(ValidationError, validate_csrf, None)
         self.assertRaises(ValidationError, validate_csrf, 'invalid')
         validate_csrf(generate_csrf())
Beispiel #53
0
def ajax_distinct(resource, field):
    if validate_csrf(request.headers.get(CSRF_TOKEN_H, None)):
        return backend.ajax_get(
            request, "/%s/distinct" % resource, doc_id=field, timeout=60*30)
    else:
        abort(403)
Beispiel #54
0
def ajax_get(api):
    if validate_csrf(request.headers.get(CSRF_TOKEN_H, None)):
        return backend.ajax_get(request, app_conf_get(api), timeout=60 * 20)
    else:
        abort(403)
Beispiel #55
0
def ajax_boot_regressions():
    if validate_csrf(request.headers.get(CSRF_TOKEN_H, None)):
        return backend.ajax_get(
            request, app_conf_get("BOOT_REGRESSIONS_API_ENDPOINT"))
    else:
        abort(403)
Beispiel #56
0
def handle_ajax_get(req, endpoint, timeout=None):
    if validate_csrf(req.headers.get(CSRF_TOKEN_H, None)):
        return backend.ajax_get(req, endpoint, timeout=timeout)
    else:
        abort(403)
Beispiel #57
0
 def test_validate_csrf(self):
     with self.app.test_request_context():
         assert not validate_csrf('ff##dd')
         csrf_token = generate_csrf()
         assert validate_csrf(csrf_token)
Beispiel #58
0
 def test_validate_not_expiring_csrf(self):
     with self.app.test_request_context():
         csrf_token = generate_csrf(time_limit=False)
         assert validate_csrf(csrf_token, time_limit=False)
Beispiel #59
0
def ajax_boot():
    if validate_csrf(request.headers.get(CSRF_TOKEN_H, None)):
        return backend.ajax_get(request, app_conf_get("BOOT_API_ENDPOINT"))
    else:
        abort(400)
Beispiel #60
0
def process_callback(callback_uri):
    code = request.args.get('code')
    state = request.args.get('state')
    error = request.args.get('error')
    error_desc = request.args.get('error_description', '')

    if error:
        return {'error': 'Facebook auth canceled or failed with error: {}, '
                'description: {}'.format(error, error_desc)}

    if not validate_csrf(state):
        return {'error': 'csrf token mismatch in Facebook callback.'}

    r = requests.get('https://graph.facebook.com/oauth/access_token', params={
        'client_id': current_app.config['FACEBOOK_CLIENT_ID'],
        'client_secret': current_app.config['FACEBOOK_CLIENT_SECRET'],
        'redirect_uri': callback_uri,
        'code': code,
        'scope': PERMISSION_SCOPES,
    })

    if r.status_code // 100 != 2:
        error_obj = r.json()
        error = error_obj.get('error')
        error_desc = error_obj.get('error_description')
        return {'error': 'Error ({}) requesting access token: {}, '
                'description: {}' .format(r.status_code, error, error_desc)}

    payload = json.loads(r.text)
    current_app.logger.debug('auth responses from Facebook %s', payload)
    current_app.logger.debug('raw response %s', r.text)
    access_token = payload['access_token']

    r = requests.get('https://graph.facebook.com/v2.5/me', params={
        'access_token': access_token,
        'fields': 'id,name,picture',
    })

    if r.status_code // 100 != 2:
        error_obj = r.json()
        error = error_obj.get('error')
        error_desc = error_obj.get('error_description')
        return {'error': 'Error ({}) requesting authed user info: {}, '
                'description: {}' .format(r.status_code, error, error_desc)}

    user_info = r.json()
    current_app.logger.debug('authed user info from Facebook %s', user_info)

    user_id = user_info.get('id')
    account = Account.query.filter_by(
        service='facebook', user_id=user_id).first()

    if not account:
        account = Account(service='facebook', user_id=user_id,
                          username=user_id)
        db.session.add(account)

    account.user_info = user_info
    account.token = access_token

    account.update_sites([Facebook(
        url='https://www.facebook.com/{}'.format(account.user_id),
        # overloading "domain" to really mean "user's canonical url"
        domain='facebook.com/{}'.format(account.user_id),
        site_id=account.user_id)])

    db.session.commit()
    util.set_authed(account.sites)
    return {'account': account}