Skip to content

Commit

Permalink
Bypass row-level security in CVSS scores migrations (#359)
Browse files Browse the repository at this point in the history
This PR is the follow-up to #347. It updates migrations for CVSS scores
to contain needed ACLs to bypass row-level security.

Fixes OSIDB-1455
  • Loading branch information
jobselko authored Oct 20, 2023
2 parents f4aa5bd + cab1fc4 commit 90b5a68
Show file tree
Hide file tree
Showing 2 changed files with 183 additions and 0 deletions.
98 changes: 98 additions & 0 deletions osidb/migrations/0099_fix_flawcvss.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
"""
Written manually on 2023-10-20.
This fixes migration 0092, which was missing the correct ACLs.
"""

from osidb.core import set_user_acls

from django.conf import settings
from django.db import migrations
from itertools import islice

BATCH_SIZE = 1000


def generate_flawcvss(apps):
Flaw = apps.get_model("osidb", "Flaw")
FlawCVSS = apps.get_model("osidb", "FlawCVSS")

for flaw in Flaw.objects.iterator():
# Default values
nist_cvss2_score, nist_cvss2_vector = 0.0, ""
nist_cvss3_score, nist_cvss3_vector = 0.0, ""
rh_cvss2_score, rh_cvss2_vector = 0.0, ""
rh_cvss3_score, rh_cvss3_vector, rh_cvss3_comment = 0.0, "", ""

other_fields = {
"acl_read": flaw.acl_read,
"acl_write": flaw.acl_write,
"created_dt": flaw.created_dt,
"updated_dt": flaw.updated_dt,
}

if flaw.nvd_cvss2:
nist_cvss2_score, nist_cvss2_vector = flaw.nvd_cvss2.split("/", 1)

if flaw.nvd_cvss3:
nist_cvss3_score, nist_cvss3_vector = flaw.nvd_cvss3.split("/", 1)

if flaw.cvss2:
rh_cvss2_score, rh_cvss2_vector = flaw.cvss2.split("/", 1)

if flaw.cvss3:
rh_cvss3_score, rh_cvss3_vector = flaw.cvss3.split("/", 1)

if flaw.meta_attr.get("cvss3_comment"):
rh_cvss3_comment = flaw.meta_attr.get("cvss3_comment")

for issuer, version, vector, score, comment in [
("RH", "V3", rh_cvss3_vector, float(rh_cvss3_score), rh_cvss3_comment),
("RH", "V2", rh_cvss2_vector, float(rh_cvss2_score), ""),
("NIST", "V3", nist_cvss3_vector, float(nist_cvss3_score), ""),
("NIST", "V2", nist_cvss2_vector, float(nist_cvss2_score), ""),
]:
if vector:
yield FlawCVSS(
flaw=flaw,
issuer=issuer,
version=version,
vector=vector,
score=score,
comment=comment,
**other_fields,
)


def forwards_func(apps, schema_editor):
set_user_acls(
settings.PUBLIC_READ_GROUPS
+ [
settings.PUBLIC_WRITE_GROUP,
settings.EMBARGO_READ_GROUP,
settings.EMBARGO_WRITE_GROUP,
]
)

FlawCVSS = apps.get_model("osidb", "FlawCVSS")
# to ensure that everything will be migrated again with correct ACLs
FlawCVSS.objects.all().delete()

generator = generate_flawcvss(apps)
while True:
# Limiting memory usage by using a generator and slicing recommended in
# https://docs.djangoproject.com/en/3.2/ref/models/querysets/#bulk-create
batch = list(islice(generator, BATCH_SIZE))
if not batch:
break

FlawCVSS.objects.bulk_create(batch, BATCH_SIZE, ignore_conflicts=False)


class Migration(migrations.Migration):
dependencies = [
("osidb", "0098_ps_contact_blank"),
]

operations = [
migrations.RunPython(forwards_func, migrations.RunPython.noop, atomic=True),
]
85 changes: 85 additions & 0 deletions osidb/migrations/0100_fix_affectcvss.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
"""
Written manually on 2023-10-20.
This fixes migration 0093, which was missing the correct ACLs.
"""

from osidb.core import set_user_acls

from django.conf import settings
from django.db import migrations
from itertools import islice

BATCH_SIZE = 1000


def generate_affectcvss(apps):
Affect = apps.get_model("osidb", "Affect")
AffectCVSS = apps.get_model("osidb", "AffectCVSS")

for affect in Affect.objects.iterator():
# Default values
cvss2_score, cvss2_vector = 0.0, ""
cvss3_score, cvss3_vector = 0.0, ""

other_fields = {
"acl_read": affect.acl_read,
"acl_write": affect.acl_write,
"created_dt": affect.created_dt,
"updated_dt": affect.updated_dt,
}

if affect.cvss2:
cvss2_score, cvss2_vector = affect.cvss2.split("/", 1)

if affect.cvss3:
cvss3_score, cvss3_vector = affect.cvss3.split("/", 1)

for version, vector, score in [
("V3", cvss3_vector, float(cvss3_score)),
("V2", cvss2_vector, float(cvss2_score)),
]:
if vector:
yield AffectCVSS(
affect=affect,
issuer="RH",
version=version,
vector=vector,
score=score,
comment="",
**other_fields,
)


def forwards_func(apps, schema_editor):
set_user_acls(
settings.PUBLIC_READ_GROUPS
+ [
settings.PUBLIC_WRITE_GROUP,
settings.EMBARGO_READ_GROUP,
settings.EMBARGO_WRITE_GROUP,
]
)

AffectCVSS = apps.get_model("osidb", "AffectCVSS")
# to ensure that everything will be migrated again with correct ACLs
AffectCVSS.objects.all().delete()

generator = generate_affectcvss(apps)
while True:
# Limiting memory usage by using a generator and slicing recommended in
# https://docs.djangoproject.com/en/3.2/ref/models/querysets/#bulk-create
batch = list(islice(generator, BATCH_SIZE))
if not batch:
break

AffectCVSS.objects.bulk_create(batch, BATCH_SIZE, ignore_conflicts=False)


class Migration(migrations.Migration):
dependencies = [
("osidb", "0099_fix_flawcvss"),
]

operations = [
migrations.RunPython(forwards_func, migrations.RunPython.noop, atomic=True),
]

0 comments on commit 90b5a68

Please sign in to comment.