diff farol/vulnerability.py @ 0:4a9f23230eba

Initial Release
author Benoît Allard <benoit.allard@greenbone.net>
date Wed, 24 Sep 2014 10:07:49 +0200
parents
children fbc413b8a46e
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/farol/vulnerability.py	Wed Sep 24 10:07:49 2014 +0200
@@ -0,0 +1,492 @@
+# -*- encoding: utf-8 -*-
+# Description:
+# Web stuff related to the Vulnerabilities
+#
+# Authors:
+# BenoƮt Allard <benoit.allard@greenbone.net>
+#
+# Copyright:
+# Copyright (C) 2014 Greenbone Networks GmbH
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+
+from flask import (Blueprint, render_template, abort, redirect, request,
+    url_for)
+
+from farolluz.parsers.cvrf import parseDate
+from farolluz.cvrf import (CVRFVulnerability, CVRFVulnerabilityID, CVRFNote,
+    CVRFReference, CVRFAcknowledgment, CVRFCWE, CVRFInvolvement, CVRFThreat,
+    CVRFProductStatus, CVRFCVSSSet, CVRFRemediation)
+from farolluz.renderer import utcnow
+
+from .session import document_required, get_current
+
+
+vulnerability = Blueprint('vulnerability', __name__)
+
+def get_vuln(ordinal):
+    for vulnerability in get_current()._vulnerabilities:
+        if vulnerability._ordinal != ordinal:
+            continue
+        return vulnerability
+    abort(404)
+
+def vuln_from_form(form, vuln=None):
+    if vuln is None:
+        vuln = CVRFVulnerability(int(form['ordinal']))
+    else:
+        vuln._ordinal = int(form['ordinal'])
+    vuln.setTitle(form['title'] or None)
+    vuln_id = None
+    if form['systemname'] or form['id_value']:
+        vuln_id = CVRFVulnerabilityID(form['systemname'], form['id_value'])
+    vuln.setID(vuln_id)
+    date = None
+    if form['discoverydate']:
+        date = parseDate(form['discoverydate'])
+    vuln.setDiscoveryDate(date)
+    date = None
+    if form['releasedate']:
+        date = parseDate(form['releasedate'])
+    vuln.setReleaseDate(date)
+    vuln.setCVE(request.form['cve'] or None)
+    return vuln
+
+def get_groups():
+    """ Return a list of tuple suitable for selectinput2 """
+    cvrf = get_current()
+    groups = []
+    if cvrf._producttree is not None:
+        groups = [(g.getTitle(), g._groupid) for g in cvrf._producttree._groups]
+    return groups
+
+@vulnerability.route('/<int:ordinal>')
+@document_required
+def view(ordinal):
+    return render_template('vulnerability/view.j2', vulnerability=get_vuln(ordinal))
+
+@vulnerability.route('/<int:ordinal>/edit', methods=['GET', 'POST'])
+@document_required
+def edit(ordinal):
+    vuln = get_vuln(ordinal)
+    if request.method != 'POST':
+        return render_template('vulnerability/edit.j2', vulnerability=vuln, now=utcnow())
+
+    vuln_from_form(request.form, vuln)
+    return redirect(url_for('.view', ordinal=vuln._ordinal))
+
+@vulnerability.route('/add', methods=['GET', 'POST'])
+@document_required
+def add():
+    if request.method != 'POST':
+        next_ordinal=1
+        vulns = get_current()._vulnerabilities
+        if vulns:
+            next_ordinal = vulns[-1]._ordinal + 1
+        vuln = CVRFVulnerability(next_ordinal)
+        return render_template('vulnerability/edit.j2', vulnerability=vuln, now=utcnow(), action='Add')
+
+    vuln=vuln_from_form(request.form)
+    get_current().addVulnerability(vuln)
+    return redirect(url_for('.view', ordinal=vuln._ordinal))
+
+@vulnerability.route('/<int:ordinal>/note/<int:note_ordinal>')
+@document_required
+def view_note(ordinal, note_ordinal):
+    for note in get_vuln(ordinal)._notes:
+        if note._ordinal != note_ordinal:
+            continue
+        return render_template('vulnerability/view_note.j2', note=note, ordinal=ordinal)
+    abort(404)
+
+@vulnerability.route('/<int:ordinal>/note/<int:note_ordinal>/edit', methods=['GET', 'POST'])
+@document_required
+def edit_note(ordinal, note_ordinal):
+    note = None
+    for n in get_vuln(ordinal)._notes:
+        if n._ordinal == note_ordinal:
+            note = n
+            break
+    if note is None:
+        abort(404)
+    if request.method != 'POST':
+        return render_template('vulnerability/edit_note.j2', note=note, ordinal=ordinal, types=note.TYPES)
+
+    note._type = request.form['type']
+    note._ordinal = int(request.form['ordinal'])
+    note._note = request.form['note']
+    note._title = request.form['title'] or None
+    note._audience = request.form['audience'] or None
+    return redirect(url_for('.view_note', ordinal=ordinal, note_ordinal=note._ordinal))
+
+@vulnerability.route('/<int:ordinal>/note/add', methods=['GET', 'POST'])
+@document_required
+def add_note(ordinal):
+    if request.method != 'POST':
+        next_ordinal = 1
+        notes = get_vuln(ordinal)._notes
+        if notes:
+            next_ordinal = notes[-1]._ordinal + 1
+        return render_template('vulnerability/edit_note.j2', ordinal=ordinal, note_ordinal=next_ordinal, types=CVRFNote.TYPES, action='Add')
+
+    title = request.form['title'] or None
+    audience = request.form['audience'] or None
+
+    note = CVRFNote(request.form['type'], int(request.form['ordinal']), request.form['note'], title, audience)
+    get_vuln(ordinal).addNote(note)
+    return redirect(url_for('.view', ordinal=ordinal))
+
+
+@vulnerability.route('/<int:ordinal>/involvement/<int:index>')
+@document_required
+def view_involvement(ordinal, index):
+    try:
+        involvement = get_vuln(ordinal)._involvements[index]
+    except IndexError:
+        abort(404)
+    return render_template('vulnerability/view_involvement.j2', involvement=involvement, ordinal=ordinal, index=index)
+
+@vulnerability.route('/<int:ordinal>/involvement/add', methods=['GET', 'POST'])
+@document_required
+def add_involvement(ordinal):
+    if request.method != 'POST':
+        return render_template('vulnerability/edit_involvement.j2', ordinal=ordinal, parties=CVRFInvolvement.PARTIES, statuses=CVRFInvolvement.STATUSES, action='Add')
+
+    inv = CVRFInvolvement(request.form['party'], request.form['status'])
+    inv._description = request.form['description'] or None
+    get_vuln(ordinal).addInvolvement(inv)
+    return redirect(url_for('.view', ordinal=ordinal))
+
+
+@vulnerability.route('/<int:ordinal>/involvement/<int:index>/edit', methods=['GET', 'POST'])
+@document_required
+def edit_involvement(ordinal, index):
+    try:
+        involvement = get_vuln(ordinal)._involvements[index]
+    except IndexError:
+        abort(404)
+    if request.method != 'POST':
+        return render_template('vulnerability/edit_involvement.j2', ordinal=ordinal, index=index, party=involvement._party, status=involvement._status, description=involvement._description, parties=involvement.PARTIES, statuses=involvement.STATUSES)
+
+    involvement._party = request.form['party']
+    involvement._status = request.form['status']
+    involvement._description = request.form['description'] or None
+    return redirect(url_for('.view_involvement', ordinal=ordinal, index=index))
+
+@vulnerability.route('/<int:ordinal>/cwe/<int:index>/edit', methods=['GET', 'POST'])
+@document_required
+def edit_cwe(ordinal, index):
+    try:
+        cwe = get_vuln(ordinal)._cwes[index]
+    except IndexError:
+        abort(404)
+    if request.method != 'POST':
+        return render_template('vulnerability/edit_cwe.j2', ordinal=ordinal, _id=cwe._id, description=cwe._value)
+
+    cwe._id = request.form['id']
+    cwe._value = request.form['description']
+    return redirect(url_for('.view', ordinal=ordinal))
+
+
+@vulnerability.route('/<int:ordinal>/cwe/add', methods=['GET', 'POST'])
+@document_required
+def add_cwe(ordinal):
+    if request.method != 'POST':
+        return render_template('vulnerability/edit_cwe.j2', ordinal=ordinal, action='Add')
+
+    cwe = CVRFCWE(request.form['id'], request.form['description'])
+    get_vuln(ordinal).addCWE(cwe)
+    return redirect(url_for('.view', ordinal=ordinal))
+
+@vulnerability.route('/<int:ordinal>/productstatus/<int:index>')
+@document_required
+def view_status(ordinal, index):
+    try:
+        status = get_vuln(ordinal)._productstatuses[index]
+    except IndexError:
+        abort(404)
+    return render_template('vulnerability/view_productstatus.j2', ordinal=ordinal, index=index, status=status, cvrf=get_current())
+
+@vulnerability.route('/<int:ordinal>/productstatus/add', methods=['GET', 'POST'])
+@document_required
+def add_status(ordinal):
+    if request.method != 'POST':
+        return render_template('vulnerability/edit_productstatus.j2', ordinal=ordinal, statuses=CVRFProductStatus.TYPES, action='Add')
+
+    status = CVRFProductStatus(request.form['status'])
+    for productid in request.form.getlist('products'):
+        status.addProductID(productid)
+    get_vuln(ordinal).addProductStatus(status)
+    return redirect(url_for('.view', ordinal=ordinal))
+
+
+@vulnerability.route('/<int:ordinal>/productstatus/<int:index>/edit', methods=['GET', 'POST'])
+@document_required
+def edit_status(ordinal, index):
+    try:
+        status = get_vuln(ordinal)._productstatuses[index]
+    except IndexError:
+        abort(404)
+    if request.method != 'POST':
+        return render_template('vulnerability/edit_productstatus.j2', ordinal=ordinal, index=index, status=status._type, productids=status._productids, statuses=status.TYPES)
+
+    status._type = request.form['status']
+    status._productids = []
+    for productid in request.form.getlist('products'):
+        status.addProductID(productid)
+    return redirect(url_for('.view', ordinal=ordinal))
+
+
+@vulnerability.route('/<int:ordinal>/threat/<int:index>')
+@document_required
+def view_threat(ordinal, index):
+    try:
+        threat = get_vuln(ordinal)._threats[index]
+    except IndexError:
+        abort(404)
+    return render_template('vulnerability/view_threat.j2', ordinal=ordinal, index=index, threat=threat, cvrf=get_current())
+
+@vulnerability.route('/<int:ordinal>/threat/add', methods=['GET', 'POST'])
+@document_required
+def add_threat(ordinal):
+    cvrf = get_current()
+    if request.method != 'POST':
+        return render_template('vulnerability/edit_threat.j2',
+            ordinal=ordinal,
+            types=CVRFThreat.TYPES, groups=get_groups(), now=utcnow(),
+            action='Add')
+
+    threat = CVRFThreat(request.form['type'], request.form['description'])
+    if request.form['date']:
+        threat.setDate(parseDate(request.form['date']))
+    for productid in request.form.getlist('products'):
+        threat.addProductID(productid)
+    for groupid in request.form.getlist('groups'):
+        threat.addGroupID(groupid)
+    get_vuln(ordinal).addThreat(threat)
+    return redirect(url_for('.view', ordinal=ordinal))
+
+@vulnerability.route('/<int:ordinal>/threat/<int:index>/edit', methods=['GET', 'POST'])
+@document_required
+def edit_threat(ordinal, index):
+    try:
+        threat = get_vuln(ordinal)._threats[index]
+    except IndexError:
+        abort(404)
+    cvrf = get_current()
+    if request.method != 'POST':
+        return render_template('vulnerability/edit_threat.j2',
+            ordinal=ordinal, index=index,
+            type=threat._type, date=threat._date, description=threat._description, productids=threat._productids, groupids=threat._groupids,
+            types=threat.TYPES, groups=get_groups(), now=utcnow())
+
+    threat._type = request.form['type']
+    threat._description = request.form['description']
+    date = None
+    if request.form['date']:
+        date = parseDate(request.form['date'])
+    threat.setDate(date)
+    threat._productids = []
+    threat._groupids = []
+    for productid in request.form.getlist('products'):
+        threat.addProductID(productid)
+    for groupid in request.form.getlist('groups'):
+        threat.addGroupID(groupid)
+    return redirect(url_for('.view', ordinal=ordinal))
+
+
+@vulnerability.route('/<int:ordinal>/cvss/<int:index>')
+@document_required
+def view_cvss(ordinal, index):
+    try:
+        cvss = get_vuln(ordinal)._cvsss[index]
+    except IndexError:
+        abort(404)
+    return render_template('vulnerability/view_cvss.j2', ordinal=ordinal, index=index, cvss=cvss, cvrf=get_current())
+
+@vulnerability.route('/<int:ordinal>/cvss/add', methods=['GET', 'POST'])
+@document_required
+def add_cvss(ordinal):
+    if request.method != 'POST':
+        return render_template('vulnerability/edit_cvss.j2', ordinal=ordinal, action='Add')
+
+    cvss = CVRFCVSSSet(float(request.form['basescore']))
+    tscore = None
+    if request.form['temporalscore']:
+        tscore = float(request.form['temporalscore'])
+    cvss.setTemporalScore(tscore)
+    escore = None
+    if request.form['environmentalscore']:
+        escore = float(request.form['environmentalscore'])
+    cvss.setEnvironmentalScore(escore)
+    cvss.setVector(request.form['vector'] or None)
+    get_vuln(ordinal).addCVSSSet(cvss)
+    return redirect(url_for('.view', ordinal=ordinal))
+
+
+@vulnerability.route('/<int:ordinal>/cvss/<int:index>/edit', methods=['GET', 'POST'])
+@document_required
+def edit_cvss(ordinal, index):
+    try:
+        cvss = get_vuln(ordinal)._cvsss[index]
+    except IndexError:
+        abort(404)
+    if request.method != 'POST':
+        return render_template('vulnerability/edit_cvss.j2',
+            ordinal=ordinal, index=index,
+            basescore=cvss._basescore, temporalscore=cvss._temporalscore, environmentalscore=cvss._environmentalscore, vector=cvss._vector)
+
+    cvss._basescore = float(request.form['basescore'])
+    tscore = None
+    if request.form['temporalscore']:
+        tscore = float(request.form['temporalscore'])
+    cvss.setTemporalScore(tscore)
+    escore = None
+    if request.form['environmentalscore']:
+        escore = float(request.form['environmentalscore'])
+    cvss.setEnvironmentalScore(escore)
+    cvss.setVector(request.form['vector'] or None)
+    return redirect(url_for('.view', ordinal=ordinal))
+
+
+@vulnerability.route('/<int:ordinal>/remediation/<int:index>')
+@document_required
+def view_remediation(ordinal, index):
+    try:
+        remediation = get_vuln(ordinal)._remediations[index]
+    except IndexError:
+        abort(404)
+    return render_template('vulnerability/view_remediation.j2',
+        ordinal=ordinal, index=index,
+        remediation=remediation,
+        cvrf=get_current())
+
+@vulnerability.route('/<int:ordinal>/remediation/add', methods=['GET', 'POST'])
+@document_required
+def add_remediation(ordinal):
+    if request.method != 'POST':
+        return render_template('vulnerability/edit_remediation.j2',
+            ordinal=ordinal,
+            types=CVRFRemediation.TYPES, groups=get_groups(), now=utcnow(),
+            action='Add')
+
+    remediation = CVRFRemediation(request.form['type'], request.form['description'])
+    if request.form['date']:
+        remediation.setDate(parseDate(request.form['date']))
+    if request.form['entitlement']:
+        remediation.setEntitlement(request.form['entitlement'])
+    if request.form['url']:
+        remediation.setURL(request.form['url'])
+    for productid in request.form.getlist('products'):
+        remediation.addProductID(productid)
+    for groupid in request.form.getlist('groups'):
+        remediation.addGroupID(groupid)
+    get_vuln(ordinal).addRemediation(remediation)
+    return redirect(url_for('.view', ordinal=ordinal))
+
+@vulnerability.route('/<int:ordinal>/remediation/<int:index>/edit', methods=['GET', 'POST'])
+@document_required
+def edit_remediation(ordinal, index):
+    try:
+        remediation = get_vuln(ordinal)._remediations[index]
+    except IndexError:
+        abort(404)
+    if request.method != 'POST':
+        return render_template('vulnerability/edit_remediation.j2',
+            ordinal=ordinal, index=index,
+            type=remediation._type, date=remediation._date, description=remediation._description, entitlement=remediation._entitlement, url=remediation._url, productids=remediation._productids, groupids=remediation._groupids,
+            types=remediation.TYPES, groups=get_groups(), now=utcnow())
+
+    remediation._type = request.form['type']
+    remediation._description = request.form['description']
+    date = None
+    if request.form['date']:
+        date = parseDate(request.form['date'])
+    remediation.setDate(date)
+    remediation.setEntitlement(request.form['entitlement'] or None)
+    remediation.setURL(request.form['url'] or None)
+    remediation._productids = []
+    remediation._groupids = []
+    for productid in request.form.getlist('products'):
+        remediation.addProductID(productid)
+    for groupid in request.form.getlist('groups'):
+        remediation.addGroupID(groupid)
+    return redirect(url_for('.view', ordinal=ordinal))
+
+
+@vulnerability.route('/<int:ordinal>/reference/<int:index>/edit', methods=['GET', 'POST'])
+@document_required
+def edit_reference(ordinal, index):
+    try:
+        reference = get_vuln(ordinal)._references[index]
+    except IndexError:
+        abort(404)
+    if request.method != 'POST':
+        return render_template('vulnerability/edit_reference.j2', ordinal=ordinal, _type=reference._type, url=reference._url, description=reference._description, types=('',) + reference.TYPES)
+
+    reference._type = request.form['type'] or None
+    reference._url = request.form['url']
+    reference._description = request.form['description']
+    return redirect(url_for('.view', ordinal=ordinal))
+
+@vulnerability.route('/<int:ordinal>/reference/add', methods=['GET', 'POST'])
+@document_required
+def add_reference(ordinal):
+    if request.method != 'POST':
+        return render_template('vulnerability/edit_reference.j2', action='Add', ordinal=ordinal, types=('',) + CVRFReference.TYPES)
+
+    ref = CVRFReference(request.form['url'], request.form['description'], request.form['type'] or None)
+    get_vuln(ordinal).addReference(ref)
+    return redirect(url_for('.view', ordinal=ordinal))
+
+
+@vulnerability.route('/<int:ordinal>/acknowledgment/<int:index>')
+@document_required
+def view_acknowledgment(ordinal, index):
+    try:
+        ack = get_vuln(ordinal)._acknowledgments[index]
+    except IndexError:
+        abort(404)
+    return render_template('vulnerability/view_acknowledgment.j2', ordinal=ordinal, acknowledgment=ack, index=index, action='Update')
+
+@vulnerability.route('/<int:ordinal>/acknowledgment/<int:index>/edit', methods=['GET', 'POST'])
+@document_required
+def edit_acknowledgment(ordinal, index):
+    try:
+        ack = get_vuln(ordinal)._acknowledgments[index]
+    except IndexError:
+        abort(404)
+    if request.method != 'POST':
+        return render_template('vulnerability/edit_acknowledgment.j2', ordinal=ordinal, name=ack._name, organization=ack._organization, description=ack._description, url=ack._url, action='Update')
+
+    ack._name = request.form['name'] or None
+    ack._organization = request.form['organization'] or None
+    ack._description = request.form['description'] or None
+    ack._url = request.form['url'] or None
+    return redirect(url_for('.view', ordinal=ordinal))
+
+@vulnerability.route('/<int:ordinal>/acknowledgment/add', methods=['GET', 'POST'])
+@document_required
+def add_acknowledgment(ordinal):
+    if request.method != 'POST':
+        return render_template('vulnerability/edit_acknowledgment.j2', action='Add', ordinal=ordinal)
+
+    ack = CVRFAcknowledgment()
+    ack._name = request.form['name'] or None
+    ack._organization = request.form['organization'] or None
+    ack._description = request.form['description'] or None
+    ack._url = request.form['url'] or None
+    get_vuln(ordinal).addAcknowledgment(ack)
+    return redirect(url_for('.view', ordinal=ordinal))

http://farol.wald.intevation.org