예제 #1
0
def edit_proposal(vuln_id: str = None):
    vulnerability_details = _get_vulnerability_details(None,
                                                       vuln_id,
                                                       simplify_id=False)
    view = vulnerability_details.vulnerability_view
    vuln = vulnerability_details.get_or_create_vulnerability()
    ensure(EDIT, vuln)
    form = VulnerabilityDetailsForm(obj=vuln)

    # Populate the form data from the vulnerability view if necessary.
    if form.comment.data == "":
        form.comment.data = view.comment

    if request.method == 'POST' and not form.validate():
        flash_error("Your proposal contains invalid data, please correct.")

    form_submitted = form.validate_on_submit()
    if form_submitted and view.is_creator():
        new_products = update_proposal(vuln, form)
        if new_products is not None:
            view.products = [(p.vendor, p.product) for p in new_products]

    return render_template("profile/edit_proposal.html",
                           vulnerability_details=vulnerability_details,
                           form=form)
예제 #2
0
def delete_proposal(vuln_id: str = None):
    vulnerability_details = get_vulnerability_details(None,
                                                      vuln_id,
                                                      simplify_id=False)
    vuln = vulnerability_details.get_vulnerability()
    if not vuln:
        abort(404)

    if vuln.state == VulnerabilityState.PUBLISHED:
        flash_error("Can't delete a published entry w/o reverting it first")
        return redirect(url_for("profile.view_proposals"))

    if vuln.state == VulnerabilityState.ARCHIVED:
        flash_error("Can't delete an archived")
        return redirect(url_for("profile.view_proposals"))

    ensure(DELETE, vuln)

    if (request.method != "GET"
            and request.form.get("confirm", "false").lower() == "true"):
        db.session.delete(vuln)
        db.session.commit()
        flash("Entry deleted", "success")
        return redirect(url_for("profile.view_proposals"))
    return render_template("vulnerability/delete.html",
                           vuln_view=vulnerability_details.vulnerability_view)
예제 #3
0
def user_profile(user_id=None):
    user: User = User.query.get_or_404(user_id)
    ensure(READ, user)

    vulns = Vulnerability.query.filter(
        Vulnerability.creator == user,
        Vulnerability.state.in_(
            [VulnerabilityState.PUBLISHED, VulnerabilityState.ARCHIVED]),
    ).all()
    return render_template("profile/profile_viewer.html",
                           user=user,
                           vulns=vulns)
예제 #4
0
def index(user_id=None):
    if user_id is None:
        user = g.user
    else:
        user: User = User.query.get_or_404(user_id)
    if request.method == "GET":
        ensure(READ, user)
    else:
        ensure(EDIT, user)
    form = UserProfileForm(obj=user)
    if form.validate_on_submit():
        form.populate_obj(user)
        db.session.add(user)
        db.session.commit()
    return render_template("profile/index.html", form=form, user=user)
예제 #5
0
def index():
    user = g.user
    if request.method == "GET":
        ensure(READ, user)
    else:
        ensure(EDIT, user)
    form = UserProfileForm(obj=user)
    if form.validate_on_submit():
        form.populate_obj(user)
        db.session.add(user)
        db.session.commit()
    vulns = Vulnerability.query.filter(
        Vulnerability.creator == user,
        Vulnerability.state.in_(
            [VulnerabilityState.PUBLISHED, VulnerabilityState.ARCHIVED]),
    ).all()
    return render_template("profile/index.html",
                           form=form,
                           user=user,
                           vulns=vulns)
예제 #6
0
def vuln_review(vcdb_id, vuln_id):
    vulnerability_details = get_vulnerability_details(vcdb_id, simplify_id=False)
    vuln = vulnerability_details.get_or_create_vulnerability()

    proposal_vulnerability_details = get_vulnerability_details(
        None, vuln_id=vuln_id, simplify_id=False
    )
    proposal_vuln = proposal_vulnerability_details.get_or_create_vulnerability()

    ensure(READ, proposal_vuln)

    form_reject = VulnerabilityProposalReject()
    form_approve = VulnerabilityProposalApprove()
    form_assign = VulnerabilityProposalAssign()
    form_unassign = VulnerabilityProposalUnassign()
    form_publish = VulnerabilityProposalPublish()

    if request.method == "POST":
        if (
            request.form["review_response"] == "assign"
            and form_assign.validate_on_submit()
        ):
            ensure(ASSIGN, proposal_vuln)
            if proposal_vuln.is_reviewable:
                proposal_vuln.accept_review(g.user)
                db.session.add(proposal_vuln)
                db.session.commit()
                flash("The review was successfully assigned to you.", "success")
                return redirect(request.url)

            flash_error("This entry is not in a reviewable state.")

        if (
            request.form["review_response"] == "unassign"
            and form_unassign.validate_on_submit()
        ):
            ensure(ASSIGN, proposal_vuln)
            if proposal_vuln.is_reviewer(g.user):
                proposal_vuln.deny_review()
                db.session.add(proposal_vuln)
                db.session.commit()
                flash(
                    "You successfully unassigned yourself from this review.", "success"
                )
                return redirect(request.url)

            flash_error("This entry is not assigned to you.")

        if (
            request.form["review_response"] == "approve"
            and form_approve.validate_on_submit()
        ):
            ensure(APPROVE, proposal_vuln)
            proposal_vuln.accept_change()
            db.session.add(proposal_vuln)
            db.session.commit()
            flash(
                "You approved the proposal. "
                "Waiting for the entry to be published by an admin.",
                "success",
            )
            return redirect(request.url)

        if (
            request.form["review_response"] == "reject"
            and form_reject.validate_on_submit()
        ):
            ensure(REJECT, proposal_vuln)
            proposal_vuln.deny_change(g.user, form_reject.data["review_feedback"])
            db.session.add(proposal_vuln)
            db.session.commit()
            flash("Waiting for the author to address your feedback.", "success")
            return redirect(request.url)

        if (
            request.form["review_response"] == "publish"
            and form_publish.validate_on_submit()
        ):
            ensure("PUBLISH", proposal_vuln)
            proposal_vuln.publish_change()
            db.session.add(proposal_vuln)
            db.session.commit()
            # This might be the first entry of its kind
            # so no archiving is necessary.
            if vuln.state:
                vuln.archive_entry()
                db.session.add(vuln)
                db.session.commit()
            flash("Entry was successfully published.", "success")
            return redirect(request.url)

    # Published entries can't be reviewed.
    # if view.state == VulnerabilityState.PUBLISHED:
    #    raise RequestRedirect("/" + str(vcdb_id))
    return render_template(
        "vulnerability/review/review.html",
        proposal_vulnerability_details=proposal_vulnerability_details,
        vulnerability_details=vulnerability_details,
        form_assign=form_assign,
        form_unassign=form_unassign,
        form_reject=form_reject,
        form_approve=form_approve,
        form_publish=form_publish,
    )
예제 #7
0
def vuln_editor(vcdb_id):
    vulnerability_details = get_vulnerability_details(vcdb_id)
    ensure(ANNOTATE, vulnerability_details.get_vulnerability())
    return view_vuln(vcdb_id, "vulnerability/code_editor.html")
예제 #8
0
def bug_save_editor_data():
    if request.method != "POST":
        return create_json_response("Accepting only POST requests.", 400)

    try:
        vulnerability_details = VulnerabilityDetails()
        vulnerability_details.validate_and_simplify_id()
    except InvalidIdentifierException as ex:
        return create_json_response(str(ex), 400)
    vuln_view = vulnerability_details.vulnerability_view

    if not vuln_view:
        return create_json_response("Please create an entry first", 404)

    if not vuln_view.master_commit:
        current_app.logger.error(
            f"Vuln (id: {vuln_view.id}) has no linked Git commits!")
        return create_json_response("Entry has no linked Git link!", 404)

    ensure(ANNOTATE, vulnerability_details.get_vulnerability())

    master_commit = vulnerability_details.get_master_commit()

    old_files = master_commit.repository_files
    current_app.logger.debug("%d old files", len(old_files))
    # Flush any old custom content of this vulnerability first.
    new_files = []
    for file in request.get_json():
        for old_file in old_files:
            if old_file.file_path == file[
                    "path"] or old_file.file_hash == file["hash"]:
                current_app.logger.debug(
                    "Found old file: %s",
                    (file["path"], file["hash"], file["name"]))
                file_obj = old_file
                break
        else:
            current_app.logger.debug(
                "Creating new file: %s",
                (file["path"], file["hash"], file["name"]))
            file_obj = RepositoryFiles(
                file_name=file["name"],
                file_path=file["path"],
                file_patch="DEPRECATED",
                file_hash=file["hash"],
            )
        # Create comment objects.
        new_comments = []
        for comment in file["comments"]:
            comment_obj = RepositoryFileComments(
                row_from=comment["row_from"],
                row_to=comment["row_to"],
                text=comment["text"],
                sort_pos=comment["sort_pos"],
                creator=g.user,
            )
            new_comments.append(comment_obj)
        update_file_comments(file_obj, new_comments)
        # Create marker objects.
        new_markers = []
        for marker in file["markers"]:
            marker_obj = RepositoryFileMarkers(
                row_from=marker["row_from"],
                row_to=marker["row_to"],
                column_from=marker["column_from"],
                column_to=marker["column_to"],
                marker_class=marker["class"],
                creator=g.user,
            )
            new_markers.append(marker_obj)
        update_file_markers(file_obj, new_markers)
        new_files.append(file_obj)

    current_app.logger.debug("Setting %d files", len(new_files))
    master_commit.repository_files = new_files

    # Update / Insert entries into the database.
    db.session.commit()
    return create_json_response("Update successful.")