Skip to content

Commit

Permalink
Merge branch 'main' into Page-Updated
Browse files Browse the repository at this point in the history
  • Loading branch information
Rishi-source authored Jan 17, 2025
2 parents 1851616 + 56eb442 commit caab3c0
Show file tree
Hide file tree
Showing 27 changed files with 1,419 additions and 181 deletions.
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ else
SUDO_POSTGRES=
endif

ifeq ($(UNAME), Darwin)
GET_SECRET_KEY=`head /dev/urandom | base64 | head -c50`
endif

virtualenv:
@echo "-> Bootstrap the virtualenv with PYTHON_EXE=${PYTHON_EXE}"
@${PYTHON_EXE} ${VIRTUALENV_PYZ} --never-download --no-periodic-update ${VENV}
Expand Down
2 changes: 2 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ version: "3"
services:
db:
image: postgres:13
command: -c config_file=/etc/postgresql/postgresql.conf
env_file:
- docker.env
volumes:
- db_data:/var/lib/postgresql/data/
- ./etc/postgresql/postgresql.conf:/etc/postgresql/postgresql.conf

vulnerablecode:
build: .
Expand Down
12 changes: 12 additions & 0 deletions etc/postgresql/postgresql.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Default configuration for development build
# DB Version: 13
# OS Type: linux
# DB Type: development
# Data Storage: local

listen_addresses = '*'
max_connections = 100
shared_buffers = 128MB
dynamic_shared_memory_type = posix
max_wal_size = 1GB
min_wal_size = 80MB
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ dateparser==1.1.1
decorator==5.1.1
defusedxml==0.7.1
distro==1.7.0
Django==4.2.16
Django==4.2.17
django-crispy-forms==2.3
django-environ==0.11.2
django-filter==24.3
Expand All @@ -53,7 +53,7 @@ ipython==8.10.0
isort==5.10.1
itypes==1.2.0
jedi==0.18.1
Jinja2==3.1.4
Jinja2==3.1.5
jsonschema==3.2.0
license-expression==30.3.1
lxml==4.9.1
Expand Down
85 changes: 85 additions & 0 deletions vulnerabilities/api_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from rest_framework.response import Response
from rest_framework.reverse import reverse

from vulnerabilities.models import CodeFix
from vulnerabilities.models import Package
from vulnerabilities.models import Vulnerability
from vulnerabilities.models import VulnerabilityReference
Expand Down Expand Up @@ -198,14 +199,25 @@ def get_affected_by_vulnerabilities(self, obj):
Return a dictionary with vulnerabilities as keys and their details, including fixed_by_packages.
"""
result = {}
request = self.context.get("request")
for vuln in getattr(obj, "prefetched_affected_vulnerabilities", []):
fixed_by_package = vuln.fixed_by_packages.first()
purl = None
if fixed_by_package:
purl = fixed_by_package.package_url
# Get code fixed for a vulnerability
code_fixes = CodeFix.objects.filter(
affected_package_vulnerability__vulnerability=vuln
).distinct()
code_fix_urls = [
reverse("codefix-detail", args=[code_fix.id], request=request)
for code_fix in code_fixes
]

result[vuln.vulnerability_id] = {
"vulnerability_id": vuln.vulnerability_id,
"fixed_by_packages": purl,
"code_fixes": code_fix_urls,
}
return result

Expand Down Expand Up @@ -521,3 +533,76 @@ def lookup(self, request):

qs = self.get_queryset().for_purls([purl]).with_is_vulnerable()
return Response(PackageV2Serializer(qs, many=True, context={"request": request}).data)


class CodeFixSerializer(serializers.ModelSerializer):
"""
Serializer for the CodeFix model.
Provides detailed information about a code fix.
"""

affected_vulnerability_id = serializers.CharField(
source="affected_package_vulnerability.vulnerability.vulnerability_id",
read_only=True,
help_text="ID of the affected vulnerability.",
)
affected_package_purl = serializers.CharField(
source="affected_package_vulnerability.package.package_url",
read_only=True,
help_text="PURL of the affected package.",
)
fixed_package_purl = serializers.CharField(
source="fixed_package_vulnerability.package.package_url",
read_only=True,
help_text="PURL of the fixing package (if available).",
)
created_at = serializers.DateTimeField(
format="%Y-%m-%dT%H:%M:%SZ",
read_only=True,
help_text="Timestamp when the code fix was created.",
)
updated_at = serializers.DateTimeField(
format="%Y-%m-%dT%H:%M:%SZ",
read_only=True,
help_text="Timestamp when the code fix was last updated.",
)

class Meta:
model = CodeFix
fields = [
"id",
"commits",
"pulls",
"downloads",
"patch",
"affected_vulnerability_id",
"affected_package_purl",
"fixed_package_purl",
"notes",
"references",
"is_reviewed",
"created_at",
"updated_at",
]
read_only_fields = ["created_at", "updated_at"]


class CodeFixViewSet(viewsets.ReadOnlyModelViewSet):
"""
API endpoint that allows viewing CodeFix entries.
"""

queryset = CodeFix.objects.all()
serializer_class = CodeFixSerializer

def get_queryset(self):
"""
Optionally filter by vulnerability ID.
"""
queryset = super().get_queryset()
vulnerability_id = self.request.query_params.get("vulnerability_id")
if vulnerability_id:
queryset = queryset.filter(
affected_package_vulnerability__vulnerability__vulnerability_id=vulnerability_id
)
return queryset
4 changes: 2 additions & 2 deletions vulnerabilities/importers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
# See https://aboutcode.org for more information about nexB OSS projects.
#

from vulnerabilities.importers import alpine_linux
from vulnerabilities.importers import apache_httpd
from vulnerabilities.importers import apache_kafka
from vulnerabilities.importers import apache_tomcat
Expand Down Expand Up @@ -35,6 +34,7 @@
from vulnerabilities.importers import vulnrichment
from vulnerabilities.importers import xen
from vulnerabilities.pipelines import VulnerableCodeBaseImporterPipeline
from vulnerabilities.pipelines import alpine_linux_importer
from vulnerabilities.pipelines import github_importer
from vulnerabilities.pipelines import gitlab_importer
from vulnerabilities.pipelines import nginx_importer
Expand All @@ -44,7 +44,6 @@
from vulnerabilities.pipelines import pysec_importer

IMPORTERS_REGISTRY = [
alpine_linux.AlpineImporter,
openssl.OpensslImporter,
redhat.RedhatImporter,
debian.DebianImporter,
Expand Down Expand Up @@ -78,6 +77,7 @@
github_importer.GitHubAPIImporterPipeline,
nvd_importer.NVDImporterPipeline,
pysec_importer.PyPIImporterPipeline,
alpine_linux_importer.AlpineLinuxImporterPipeline,
]

IMPORTERS_REGISTRY = {
Expand Down
4 changes: 4 additions & 0 deletions vulnerabilities/improvers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
from vulnerabilities.improvers import valid_versions
from vulnerabilities.improvers import vulnerability_status
from vulnerabilities.pipelines import VulnerableCodePipeline
from vulnerabilities.pipelines import add_cvss31_to_CVEs
from vulnerabilities.pipelines import collect_commits
from vulnerabilities.pipelines import compute_package_risk
from vulnerabilities.pipelines import compute_package_version_rank
from vulnerabilities.pipelines import enhance_with_exploitdb
Expand Down Expand Up @@ -41,6 +43,8 @@
enhance_with_exploitdb.ExploitDBImproverPipeline,
compute_package_risk.ComputePackageRiskPipeline,
compute_package_version_rank.ComputeVersionRankPipeline,
collect_commits.CollectFixCommitsPipeline,
add_cvss31_to_CVEs.CVEAdvisoryMappingPipeline,
]

IMPROVERS_REGISTRY = {
Expand Down
127 changes: 127 additions & 0 deletions vulnerabilities/migrations/0086_codefix.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# Generated by Django 4.2.16 on 2025-01-08 13:28

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
("vulnerabilities", "0085_alter_package_is_ghost_alter_package_version_rank_and_more"),
]

operations = [
migrations.CreateModel(
name="CodeFix",
fields=[
(
"id",
models.AutoField(
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
),
),
(
"commits",
models.JSONField(
blank=True,
default=list,
help_text="List of commit identifiers using VCS URLs associated with the code change.",
),
),
(
"pulls",
models.JSONField(
blank=True,
default=list,
help_text="List of pull request URLs associated with the code change.",
),
),
(
"downloads",
models.JSONField(
blank=True,
default=list,
help_text="List of download URLs for the patched code.",
),
),
(
"patch",
models.TextField(
blank=True,
help_text="The code change as a patch in unified diff format.",
null=True,
),
),
(
"notes",
models.TextField(
blank=True,
help_text="Notes or instructions about this code change.",
null=True,
),
),
(
"references",
models.JSONField(
blank=True,
default=list,
help_text="URL references related to this code change.",
),
),
(
"is_reviewed",
models.BooleanField(
default=False, help_text="Indicates if this code change has been reviewed."
),
),
(
"created_at",
models.DateTimeField(
auto_now_add=True,
help_text="Timestamp indicating when this code change was created.",
),
),
(
"updated_at",
models.DateTimeField(
auto_now=True,
help_text="Timestamp indicating when this code change was last updated.",
),
),
(
"affected_package_vulnerability",
models.ForeignKey(
help_text="The affected package version to which this code fix applies.",
on_delete=django.db.models.deletion.CASCADE,
related_name="code_fix",
to="vulnerabilities.affectedbypackagerelatedvulnerability",
),
),
(
"base_package_version",
models.ForeignKey(
blank=True,
help_text="The base package version to which this code change applies.",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="codechanges",
to="vulnerabilities.package",
),
),
(
"fixed_package_vulnerability",
models.ForeignKey(
blank=True,
help_text="The fixing package version with this code fix",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="code_fix",
to="vulnerabilities.fixingpackagerelatedvulnerability",
),
),
],
options={
"abstract": False,
},
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@

from django.db import migrations

"""
Update the created_by field on Advisory from the old qualified_name
to the new pipeline_id.
"""


def update_created_by(apps, schema_editor):
from vulnerabilities.pipelines.alpine_linux_importer import AlpineLinuxImporterPipeline

Advisory = apps.get_model("vulnerabilities", "Advisory")
Advisory.objects.filter(created_by="vulnerabilities.importers.alpine_linux.AlpineImporter").update(
created_by=AlpineLinuxImporterPipeline.pipeline_id
)


def reverse_update_created_by(apps, schema_editor):
from vulnerabilities.pipelines.alpine_linux_importer import AlpineLinuxImporterPipeline

Advisory = apps.get_model("vulnerabilities", "Advisory")
Advisory.objects.filter(created_by=AlpineLinuxImporterPipeline.pipeline_id).update(
created_by="vulnerabilities.importers.alpine_linux.AlpineImporter"
)


class Migration(migrations.Migration):

dependencies = [
("vulnerabilities", "0086_codefix"),
]

operations = [
migrations.RunPython(update_created_by, reverse_code=reverse_update_created_by),
]
Loading

0 comments on commit caab3c0

Please sign in to comment.