diff --git a/.gitlab/ci/fetch-secrets.yaml b/.gitlab/ci/fetch-secrets.yaml index e5d2c8cd673..e1112cae242 100644 --- a/.gitlab/ci/fetch-secrets.yaml +++ b/.gitlab/ci/fetch-secrets.yaml @@ -9,4 +9,3 @@ - if [ -z "$FARADAY_USER" ]; then export FARADAY_USER="$(vault kv get -field=FARADAY_USER secrets/gitlab/faraday)"; fi; if [ -z "$FARADAY_USER" ]; then exit 1; fi - if [ -z "$FARADAY_PASSWORD" ]; then export FARADAY_PASSWORD="$(vault kv get -field=FARADAY_PASSWORD secrets/gitlab/faraday)"; fi; if [ -z "$FARADAY_PASSWORD" ]; then exit 1; fi - echo $FARADAY_URL - diff --git a/CHANGELOG/4.4.0/community.md b/CHANGELOG/4.4.0/community.md new file mode 100644 index 00000000000..9d25044781a --- /dev/null +++ b/CHANGELOG/4.4.0/community.md @@ -0,0 +1,4 @@ + * [ADD] Now it's possible to modify the host or service assigned of a vulnerability. #7476 + * [MOD] Now `/get_manifest` separates the optional environment variables from the rest. #7481 + * [FIX] Add `not_any` filter operator which will retrieve results that not contains the value requested. #7394 + * [FIX] Make `get_manifest` compatible with all versions of dispatcher. #7500 diff --git a/CHANGELOG/4.4.0/date.md b/CHANGELOG/4.4.0/date.md new file mode 100644 index 00000000000..36a69a848bc --- /dev/null +++ b/CHANGELOG/4.4.0/date.md @@ -0,0 +1 @@ +May 29th, 2023 diff --git a/RELEASE.md b/RELEASE.md index 35f16f3a720..50895f5bcae 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -2,6 +2,13 @@ New features in the latest update ===================================== +4.4.0 [May 29th, 2023]: +--- + * [ADD] Now it's possible to modify the host or service assigned of a vulnerability. #7476 + * [MOD] Now `/get_manifest` separates the optional environment variables from the rest. #7481 + * [FIX] Add `not_any` filter operator which will retrieve results that not contains the value requested. #7394 + * [FIX] Make `get_manifest` compatible with all versions of dispatcher. #7500 + 4.3.5 [Apr 12th, 2023]: --- * [FIX] Modify migration with autocommit. #7487 diff --git a/faraday/__init__.py b/faraday/__init__.py index 4ccc8fbce80..86d60a5cb97 100644 --- a/faraday/__init__.py +++ b/faraday/__init__.py @@ -4,5 +4,5 @@ See the file 'doc/LICENSE' for the license information """ -__version__ = '4.3.5' +__version__ = '4.4.0' __license_version__ = __version__ diff --git a/faraday/migrations/versions/1145efa88414_add_warnings_to_command_model.py b/faraday/migrations/versions/1145efa88414_add_warnings_to_command_model.py new file mode 100644 index 00000000000..c21e8cfbaba --- /dev/null +++ b/faraday/migrations/versions/1145efa88414_add_warnings_to_command_model.py @@ -0,0 +1,28 @@ +"""Add warnings to command model + +Revision ID: 1145efa88414 +Revises: b5065f401599 +Create Date: 2023-03-30 19:49:28.651868+00:00 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '1145efa88414' +down_revision = 'b5065f401599' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('command', sa.Column('warnings', sa.String(length=250), nullable=True)) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('command', 'warnings') + # ### end Alembic commands ### diff --git a/faraday/openapi/faraday_swagger.json b/faraday/openapi/faraday_swagger.json index 515dbc88b37..4f3c77bbe4e 100644 --- a/faraday/openapi/faraday_swagger.json +++ b/faraday/openapi/faraday_swagger.json @@ -1,7 +1,7 @@ { "info": { "description": "The Faraday REST API enables you to interact with [our server](https://github.com/infobyte/faraday).\nUse this API to interact or integrate with Faraday server. This page documents the REST API, with HTTP response codes and example requests and responses.", - "title": "Faraday 4.3.5 API", + "title": "Faraday 4.4.0 API", "version": "v3" }, "security": { @@ -4185,49 +4185,49 @@ "nullable": true, "maxLength": 6 }, - "itime": {}, - "duration": { + "_id": { + "type": "integer", + "readOnly": true + }, + "params": { + "type": "string", "nullable": true }, - "command": { + "metadata": {}, + "itime": {}, + "hostname": { "type": "string", "nullable": true, - "minLength": 1 + "maxLength": 250 + }, + "creator": { + "readOnly": true }, "workspace": { "readOnly": true }, - "params": { + "ip": { "type": "string", - "nullable": true + "nullable": true, + "maxLength": 250 }, "tool": { "type": "string", "nullable": true, "minLength": 1 }, - "user": { + "command": { "type": "string", "nullable": true, - "maxLength": 250 - }, - "_id": { - "type": "integer", - "readOnly": true + "minLength": 1 }, - "hostname": { - "type": "string", - "nullable": true, - "maxLength": 250 + "duration": { + "nullable": true }, - "ip": { + "user": { "type": "string", "nullable": true, "maxLength": 250 - }, - "metadata": {}, - "creator": { - "readOnly": true } }, "required": [ @@ -4239,6 +4239,24 @@ "ActivityFeed": { "type": "object", "properties": { + "sum_created_vulnerability_info": { + "type": "integer", + "readOnly": true + }, + "sum_created_vulnerability_high": { + "type": "integer", + "readOnly": true + }, + "tool": { + "type": "string", + "nullable": true, + "minLength": 1 + }, + "user": { + "type": "string", + "nullable": true, + "maxLength": 250 + }, "import_source": { "enum": [ "report", @@ -4248,57 +4266,48 @@ "nullable": true, "maxLength": 6 }, - "sum_created_vulnerability_unclassified": { - "type": "integer", - "readOnly": true - }, - "workspace": { - "readOnly": true - }, - "sum_created_vulnerability_medium": { - "type": "integer", - "readOnly": true - }, - "sum_created_vulnerability_low": { + "sum_created_vulnerability_critical": { "type": "integer", "readOnly": true }, - "sum_created_hosts": { + "sum_created_services": { "readOnly": true, "nullable": true }, - "command": { - "type": "string", - "nullable": true, - "minLength": 1 + "creator": { + "readOnly": true }, - "tool": { + "ip": { "type": "string", "nullable": true, - "minLength": 1 + "maxLength": 250 }, - "user": { + "command": { "type": "string", "nullable": true, - "maxLength": 250 + "minLength": 1 }, - "_id": { + "itime": {}, + "sum_created_vulnerability_unclassified": { "type": "integer", "readOnly": true }, - "ip": { - "type": "string", - "nullable": true, - "maxLength": 250 + "workspace": { + "readOnly": true }, - "sum_created_services": { + "sum_created_hosts": { "readOnly": true, "nullable": true }, - "creator": { + "sum_created_vulnerabilities": { + "readOnly": true, + "nullable": true + }, + "_id": { + "type": "integer", "readOnly": true }, - "sum_created_vulnerability_critical": { + "sum_created_vulnerability_low": { "type": "integer", "readOnly": true }, @@ -4306,23 +4315,14 @@ "type": "string", "nullable": true }, - "sum_created_vulnerability_high": { + "sum_created_vulnerability_medium": { "type": "integer", "readOnly": true }, - "itime": {}, "hostname": { "type": "string", "nullable": true, "maxLength": 250 - }, - "sum_created_vulnerabilities": { - "readOnly": true, - "nullable": true - }, - "sum_created_vulnerability_info": { - "type": "integer", - "readOnly": true } }, "required": [ @@ -4337,53 +4337,53 @@ "password": { "type": "string" }, - "target": { - "type": "string", + "_id": { + "type": "integer", "readOnly": true }, - "_rev": { - "type": "string", - "readOnly": true + "description": { + "type": "string" }, - "parent": {}, "couchdbid": { "type": "string" }, - "description": { - "type": "string" + "metadata": {}, + "id": { + "type": "integer" }, "service_name": { "type": "string", "readOnly": true }, - "_id": { - "type": "integer", - "readOnly": true - }, "username": { "type": "string", "minLength": 1 }, - "metadata": {}, - "host_ip": { + "name": { + "type": "string", + "nullable": true + }, + "parent": {}, + "_rev": { "type": "string", "readOnly": true }, - "owner": { + "host_ip": { "type": "string", "readOnly": true }, "parent_type": {}, - "id": { - "type": "integer" - }, - "name": { + "owner": { "type": "string", - "nullable": true + "readOnly": true }, "owned": { "type": "boolean", "readOnly": true + }, + "target": { + "type": "string", + "readOnly": true } }, "required": [ @@ -4395,77 +4395,77 @@ "Host": { "type": "object", "properties": { - "_rev": { - "type": "string", - "readOnly": true - }, "services": { "type": "integer", "readOnly": true }, - "credentials": { + "vulns": { "type": "integer", "readOnly": true }, - "metadata": {}, + "service_summaries": { + "readOnly": true + }, "mac": { "type": "string", "nullable": true }, - "vulns": { - "type": "integer", - "readOnly": true + "description": { + "type": "string" }, - "_id": { - "type": "integer", - "readOnly": true + "metadata": {}, + "default_gateway": { + "type": "string", + "nullable": true }, "ip": { "type": "string" }, - "versions": { - "readOnly": true - }, - "service_summaries": { - "readOnly": true + "os": { + "type": "string" }, - "type": { + "owner": { "readOnly": true }, - "hostnames": {}, - "importance": { + "id": { "type": "integer" }, - "severity_counts": { - "readOnly": true + "command_id": { + "type": "integer", + "writeOnly": true }, - "owned": { - "type": "boolean" + "name": { + "type": "string", + "readOnly": true }, - "os": { - "type": "string" + "_rev": { + "type": "string", + "readOnly": true }, - "description": { - "type": "string" + "versions": { + "readOnly": true }, - "default_gateway": { - "type": "string", - "nullable": true + "severity_counts": { + "readOnly": true }, - "owner": { + "_id": { + "type": "integer", "readOnly": true }, - "id": { + "importance": { "type": "integer" }, - "name": { - "type": "string", + "type": { "readOnly": true }, - "command_id": { + "credentials": { "type": "integer", - "writeOnly": true - } + "readOnly": true + }, + "owned": { + "type": "boolean" + }, + "hostnames": {} }, "required": [ "description" @@ -4474,15 +4474,15 @@ "HostCount": { "type": "object", "properties": { - "low": { + "critical": { "type": "integer", "readOnly": true }, - "unclassified": { + "high": { "type": "integer", "readOnly": true }, - "host_id": { + "total": { "type": "integer", "readOnly": true }, @@ -4490,19 +4490,19 @@ "type": "integer", "readOnly": true }, - "critical": { + "med": { "type": "integer", "readOnly": true }, - "total": { + "host_id": { "type": "integer", "readOnly": true }, - "high": { + "unclassified": { "type": "integer", "readOnly": true }, - "med": { + "low": { "type": "integer", "readOnly": true } @@ -4515,46 +4515,10 @@ "Service": { "type": "object", "properties": { - "_rev": { - "type": "string", - "readOnly": true - }, - "host_id": { + "vulns": { "type": "integer", "readOnly": true }, - "credentials": { - "type": "integer", - "readOnly": true - }, - "metadata": {}, - "vulns": { - "type": "integer", - "readOnly": true - }, - "_id": { - "type": "integer", - "readOnly": true - }, - "summary": { - "type": "string", - "readOnly": true - }, - "ports": {}, - "type": { - "readOnly": true - }, - "port": { - "type": "integer", - "readOnly": true, - "minimum": 0 - }, - "owned": { - "type": "boolean" - }, - "parent": { - "type": "integer" - }, "status": { "type": "string", "default": "open", @@ -4564,32 +4528,68 @@ "filtered" ] }, + "host_id": { + "type": "integer", + "readOnly": true + }, "description": { "type": "string", "nullable": true }, - "protocol": { + "summary": { "type": "string", - "nullable": true, - "minLength": 1 + "readOnly": true }, + "metadata": {}, "owner": { "readOnly": true }, - "version": { + "protocol": { "type": "string", - "nullable": true + "nullable": true, + "minLength": 1 }, "id": { "type": "integer" }, + "command_id": { + "type": "integer", + "writeOnly": true + }, "name": { "type": "string", "nullable": true }, - "command_id": { + "_rev": { + "type": "string", + "readOnly": true + }, + "_id": { "type": "integer", - "writeOnly": true + "readOnly": true + }, + "port": { + "type": "integer", + "readOnly": true, + "minimum": 0 + }, + "type": { + "readOnly": true + }, + "credentials": { + "type": "integer", + "readOnly": true + }, + "ports": {}, + "parent": { + "type": "integer" + }, + "owned": { + "type": "boolean" + }, + "version": { + "type": "string", + "nullable": true } }, "required": [ @@ -4601,33 +4601,33 @@ "License": { "type": "object", "properties": { + "start": { + "type": "string", + "format": "date-time" + }, "_id": { "type": "integer", "readOnly": true }, + "id": { + "type": "integer" + }, "lictype": { "type": "string", "nullable": true }, - "end": { + "product": { "type": "string", - "format": "date-time" + "nullable": true, + "minLength": 1 }, - "start": { + "end": { "type": "string", "format": "date-time" }, "notes": { "type": "string", "nullable": true - }, - "id": { - "type": "integer" - }, - "product": { - "type": "string", - "nullable": true, - "minLength": 1 } }, "required": [ @@ -4637,14 +4637,6 @@ "Service1": { "type": "object", "properties": { - "_id": { - "type": "integer", - "readOnly": true - }, - "summary": { - "type": "string", - "readOnly": true - }, "status": { "type": "string", "default": "open", @@ -4654,6 +4646,19 @@ "filtered" ] }, + "_id": { + "type": "integer", + "readOnly": true + }, + "name": { + "type": "string", + "nullable": true + }, + "summary": { + "type": "string", + "readOnly": true + }, + "ports": {}, "protocol": { "type": "string", "nullable": true, @@ -4662,12 +4667,7 @@ "version": { "type": "string", "nullable": true - }, - "name": { - "type": "string", - "nullable": true - }, - "ports": {} + } }, "required": [ "ports", @@ -4677,10 +4677,10 @@ "Reference": { "type": "object", "properties": { - "type": { + "name": { "type": "string" }, - "name": { + "type": { "type": "string" } } @@ -4688,44 +4688,97 @@ "VulnerabilityWeb": { "type": "object", "properties": { - "_rev": { + "severity": { + "type": "string" + }, + "owned": { + "type": "boolean", + "readOnly": true + }, + "request": { + "type": "string" + }, + "path": { + "type": "string" + }, + "impact": {}, + "host_os": { "type": "string", "readOnly": true }, - "custom_fields": {}, - "query": { + "status": { + "enum": [ + "open", + "closed", + "re-opened", + "risk-accepted", + "opened" + ] + }, + "reference_instances": {}, + "tool": { "type": "string" }, - "tags": { + "method": { + "type": "string" + }, + "risk": { "readOnly": true }, - "owasp": { + "cve": { "type": "array", - "readOnly": true, "items": { "type": "string" } }, + "description": { + "type": "string", + "readOnly": true + }, + "tags": { + "readOnly": true + }, "metadata": {}, - "method": { + "service": { + "readOnly": true, + "allOf": [ + { + "$ref": "#/components/schemas/Service1" + } + ] + }, + "owner": { + "readOnly": true + }, + "confirmed": { + "type": "boolean" + }, + "custom_fields": {}, + "website": { "type": "string" }, + "command_id": { + "type": "integer", + "writeOnly": true + }, "obj_id": { "type": "string", "readOnly": true }, - "target": { - "type": "string", - "readOnly": true + "response": { + "type": "string" }, - "parent_type": {}, - "external_id": { + "desc": { + "type": "string" + }, + "name": { "type": "string", - "nullable": true + "nullable": true, + "minLength": 1 }, - "command_id": { - "type": "integer", - "writeOnly": true + "_rev": { + "type": "string", + "readOnly": true }, "easeofresolution": { "type": "string", @@ -4738,133 +4791,80 @@ ], "nullable": true }, - "reference_instances": {}, - "tool": { - "type": "string" + "cvss2": {}, + "cwe": { + "type": "array", + "items": { + "type": "string" + } + }, + "owasp": { + "type": "array", + "readOnly": true, + "items": { + "type": "string" + } }, "_id": { "type": "integer", "readOnly": true }, - "resolution": { - "type": "string", - "nullable": true - }, - "website": { + "params": { "type": "string" }, - "_attachments": {}, - "risk": { + "issuetracker": { "readOnly": true }, - "date": { + "target": { "type": "string", - "format": "date-time", "readOnly": true }, - "response": { - "type": "string" + "data": { + "type": "string", + "nullable": true }, + "type": {}, "cvss3": {}, + "query": { + "type": "string" + }, "status_code": { "type": "integer", "nullable": true }, - "data": { + "resolution": { "type": "string", "nullable": true }, - "host_os": { - "type": "string", - "readOnly": true - }, - "params": { - "type": "string" - }, - "path": { - "type": "string" - }, - "impact": {}, + "parent": {}, "policyviolations": { "type": "array", "items": { "type": "string" } }, - "type": {}, - "hostnames": { - "readOnly": true - }, - "owned": { - "type": "boolean", - "readOnly": true - }, - "severity": { - "type": "string" - }, - "request": { - "type": "string" - }, - "pname": { - "type": "string" - }, - "parent": {}, - "status": { - "enum": [ - "open", - "closed", - "re-opened", - "risk-accepted", - "opened" - ] - }, - "issuetracker": { + "parent_type": {}, + "_attachments": {}, + "date": { + "type": "string", + "format": "date-time", "readOnly": true }, - "description": { + "external_id": { "type": "string", - "readOnly": true + "nullable": true }, - "desc": { + "pname": { "type": "string" }, - "cwe": { - "type": "array", - "items": { - "type": "string" - } - }, - "service": { - "readOnly": true, - "allOf": [ - { - "$ref": "#/components/schemas/Service1" - } - ] - }, - "cvss2": {}, - "owner": { - "readOnly": true - }, "refs": { "type": "array", "items": { "$ref": "#/components/schemas/Reference" } }, - "name": { - "type": "string", - "nullable": true, - "minLength": 1 - }, - "confirmed": { - "type": "boolean" - }, - "cve": { - "type": "array", - "items": { - "type": "string" - } + "hostnames": { + "readOnly": true } }, "required": [ @@ -4878,10 +4878,10 @@ "Evidence": { "type": "object", "properties": { - "content_type": { + "data": { "readOnly": true }, - "data": { + "content_type": { "readOnly": true } } @@ -4889,18 +4889,41 @@ "VulnerabilityTemplate": { "type": "object", "properties": { - "_rev": { - "type": "string", + "creator_id": { + "type": "integer", "readOnly": true }, + "impact": {}, + "description": { + "type": "string", + "nullable": true + }, + "references": {}, "create_at": { "type": "string", "format": "date-time", "readOnly": true }, - "external_id": { + "creator": { + "readOnly": true + }, + "customfields": {}, + "id": { + "type": "integer", + "readOnly": true + }, + "desc": { "type": "string", - "nullable": true + "readOnly": true + }, + "name": { + "type": "string", + "nullable": true, + "minLength": 1 + }, + "_rev": { + "type": "string", + "readOnly": true }, "easeofresolution": { "type": "string", @@ -4913,21 +4936,23 @@ ], "nullable": true }, + "cwe": { + "type": "string", + "readOnly": true + }, + "exploitation": { + "type": "string" + }, "_id": { "type": "integer", "readOnly": true }, - "resolution": { - "type": "string", - "nullable": true - }, - "customfields": {}, "data": { "type": "string" }, - "creator_id": { - "type": "integer", - "readOnly": true + "resolution": { + "type": "string", + "nullable": true }, "policyviolations": { "type": "array", @@ -4935,41 +4960,16 @@ "type": "string" } }, - "impact": {}, - "exploitation": { - "type": "string" - }, - "references": {}, - "description": { + "external_id": { "type": "string", "nullable": true }, - "desc": { - "type": "string", - "readOnly": true - }, "refs": { "type": "array", "readOnly": true, "items": { "type": "string" } - }, - "creator": { - "readOnly": true - }, - "id": { - "type": "integer", - "readOnly": true - }, - "name": { - "type": "string", - "nullable": true, - "minLength": 1 - }, - "cwe": { - "type": "string", - "readOnly": true } }, "required": [ @@ -4992,52 +4992,45 @@ "type": "integer", "readOnly": true }, - "date": { - "type": "string", - "readOnly": true - }, "confirmed": { "type": "integer", "readOnly": true + }, + "date": { + "type": "string", + "readOnly": true } } }, "Workspace": { "type": "object", "properties": { - "customer": { - "type": "string", - "nullable": true, - "maxLength": 250 + "_id": { + "type": "integer", + "readOnly": true }, - "duration": {}, "description": { "type": "string", "nullable": true }, - "last_run_agent_date": { - "type": "string", - "format": "date-time", - "readOnly": true + "public": { + "type": "boolean" + }, + "scope": {}, + "importance": { + "type": "integer" }, "create_date": { "type": "string", "format": "date-time", "readOnly": true }, - "public": { - "type": "boolean" - }, - "stats": {}, - "readonly": { - "type": "boolean" - }, - "_id": { - "type": "integer", + "update_date": { + "type": "string", + "format": "date-time", "readOnly": true }, - "scope": {}, - "importance": { + "id": { "type": "integer" }, "histogram": { @@ -5046,19 +5039,26 @@ "$ref": "#/components/schemas/Histogram" } }, - "active": { + "name": { + "type": "string" + }, + "readonly": { "type": "boolean" }, - "update_date": { + "customer": { + "type": "string", + "nullable": true, + "maxLength": 250 + }, + "last_run_agent_date": { "type": "string", "format": "date-time", "readOnly": true }, - "id": { - "type": "integer" - }, - "name": { - "type": "string" + "duration": {}, + "stats": {}, + "active": { + "type": "boolean" } }, "required": [ @@ -5068,12 +5068,15 @@ "Comment": { "type": "object", "properties": { - "text": { - "type": "string" - }, "id": { "type": "integer" }, + "object_id": { + "type": "integer" + }, + "text": { + "type": "string" + }, "object_type": { "type": "string", "enum": [ @@ -5082,9 +5085,6 @@ "comment", "vulnerability" ] - }, - "object_id": { - "type": "integer" } }, "required": [ @@ -5099,26 +5099,26 @@ "field_order": { "type": "integer" }, + "field_display_name": { + "type": "string" + }, "field_metadata": { "type": "string", "nullable": true }, - "table_name": { - "type": "string" - }, - "field_type": { - "type": "string" + "id": { + "type": "integer", + "readOnly": true }, "field_name": { "type": "string" }, - "field_display_name": { + "table_name": { "type": "string" }, - "id": { - "type": "integer", - "readOnly": true - } + "field_type": { + "type": "string" + } }, "required": [ "field_display_name", @@ -5146,11 +5146,6 @@ "Executor": { "type": "object", "properties": { - "last_run": { - "type": "string", - "format": "date-time", - "readOnly": true - }, "schedules": { "readOnly": true, "allOf": [ @@ -5159,7 +5154,7 @@ } ] }, - "agent_id": { + "id": { "type": "integer", "readOnly": true }, @@ -5167,30 +5162,24 @@ "type": "object", "readOnly": true }, - "id": { - "type": "integer", + "last_run": { + "type": "string", + "format": "date-time", "readOnly": true }, "name": { "type": "string", "readOnly": true + }, + "agent_id": { + "type": "integer", + "readOnly": true } } }, "Agent": { "type": "object", "properties": { - "status": { - "type": "string", - "readOnly": true - }, - "creator": { - "readOnly": true - }, - "active": { - "type": "boolean", - "nullable": true - }, "executors": { "readOnly": true, "allOf": [ @@ -5199,11 +5188,6 @@ } ] }, - "last_run": { - "type": "string", - "format": "date-time", - "readOnly": true - }, "create_date": { "type": "string", "format": "date-time", @@ -5217,14 +5201,30 @@ "id": { "type": "integer" }, + "creator": { + "readOnly": true + }, + "status": { + "type": "string", + "readOnly": true + }, "name": { "type": "string", "nullable": true, "minLength": 1 }, + "last_run": { + "type": "string", + "format": "date-time", + "readOnly": true + }, "is_online": { "type": "boolean", "readOnly": true + }, + "active": { + "type": "boolean", + "nullable": true } }, "required": [ @@ -5234,14 +5234,14 @@ "AgentAuthToken": { "type": "object", "properties": { - "token": { - "type": "string" + "expires_in": { + "type": "number" }, "total_duration": { "type": "number" }, - "expires_in": { - "type": "number" + "token": { + "type": "string" } }, "required": [ @@ -5250,101 +5250,181 @@ "total_duration" ] }, - "Vulnerability": { + "BulkCommand": { "type": "object", "properties": { - "_rev": { + "import_source": { + "enum": [ + "report", + "shell", + "agent" + ], + "nullable": true, + "maxLength": 6 + }, + "params": { "type": "string", - "readOnly": true + "nullable": true }, - "custom_fields": {}, - "tags": { - "readOnly": true + "hostname": { + "type": "string", + "nullable": true, + "maxLength": 250 }, - "owasp": { - "type": "array", - "readOnly": true, - "items": { - "type": "string" - } + "creator": {}, + "start_date": { + "type": "string", + "format": "date-time" }, - "metadata": {}, - "obj_id": { + "ip": { "type": "string", - "readOnly": true + "nullable": true, + "maxLength": 250 }, - "run_date": {}, - "target": { + "tool": { "type": "string", - "readOnly": true + "nullable": true, + "minLength": 1 }, - "external_id": { + "command": { "type": "string", - "nullable": true + "nullable": true, + "minLength": 1 }, - "command_id": { + "duration": { "type": "integer", - "writeOnly": true + "x-unit": "microseconds" }, - "easeofresolution": { + "user": { + "type": "string", + "nullable": true, + "maxLength": 250 + } + }, + "required": [ + "command", + "start_date", + "tool" + ] + }, + "BulkCredential": { + "type": "object", + "properties": { + "password": { "type": "string", - "enum": [ - "trivial", - "simple", - "moderate", - "difficult", - "infeasible" - ], "nullable": true }, - "reference_instances": {}, - "tool": { - "type": "string" + "name": { + "type": "string", + "nullable": true }, - "_id": { + "description": { + "type": "string", + "nullable": true + }, + "username": { + "type": "string", + "nullable": true + } + } + }, + "BulkService": { + "type": "object", + "properties": { + "vulns": { "type": "integer", "readOnly": true }, - "resolution": { + "status": { "type": "string", - "nullable": true + "default": "open", + "enum": [ + "open", + "closed", + "filtered" + ] }, - "_attachments": {}, - "risk": { + "host_id": { + "type": "integer", "readOnly": true }, - "date": { + "description": { + "type": "string", + "nullable": true + }, + "summary": { "type": "string", - "format": "date-time", "readOnly": true }, - "cvss3": {}, - "data": { + "metadata": {}, + "owner": { + "readOnly": true + }, + "protocol": { + "type": "string", + "nullable": true, + "minLength": 1 + }, + "id": { + "type": "integer" + }, + "command_id": { + "type": "integer", + "writeOnly": true + }, + "name": { "type": "string", "nullable": true }, - "host_os": { + "_rev": { "type": "string", "readOnly": true }, - "policyviolations": { + "_id": { + "type": "integer", + "readOnly": true + }, + "port": { + "type": "integer", + "minimum": 0 + }, + "vulnerabilities": { + "default": [] + }, + "type": { + "readOnly": true + }, + "credentials": { + "default": [], "type": "array", "items": { - "type": "string" + "$ref": "#/components/schemas/BulkCredential" } }, - "impact": {}, - "type": {}, - "hostnames": { - "readOnly": true - }, "owned": { - "type": "boolean", - "readOnly": true + "type": "boolean" }, + "version": { + "type": "string", + "nullable": true + } + }, + "required": [ + "port", + "protocol" + ] + }, + "Vulnerability": { + "type": "object", + "properties": { "severity": { "type": "string" }, + "impact": {}, + "host_os": { + "type": "string", + "readOnly": true + }, "status": { "enum": [ "open", @@ -5354,23 +5434,28 @@ "opened" ] }, - "description": { - "type": "string", - "readOnly": true + "reference_instances": {}, + "tool": { + "type": "string" }, - "issuetracker": { + "risk": { "readOnly": true }, - "desc": { - "type": "string" - }, - "cwe": { + "cve": { "type": "array", "items": { "type": "string" } }, - "service": { + "description": { + "type": "string", + "readOnly": true + }, + "tags": { + "readOnly": true + }, + "metadata": {}, + "service": { "readOnly": true, "allOf": [ { @@ -5378,158 +5463,119 @@ } ] }, - "cvss2": {}, + "confirmed": { + "type": "boolean" + }, "owner": { "readOnly": true }, - "refs": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Reference" - } - }, - "name": { - "type": "string", - "nullable": true, - "minLength": 1 - }, - "confirmed": { - "type": "boolean" + "run_date": {}, + "custom_fields": {}, + "command_id": { + "type": "integer", + "writeOnly": true }, - "cve": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "name", - "severity", - "type" - ] - }, - "BulkCredential": { - "type": "object", - "properties": { - "password": { + "obj_id": { "type": "string", - "nullable": true + "readOnly": true }, - "username": { - "type": "string", - "nullable": true + "desc": { + "type": "string" }, "name": { "type": "string", - "nullable": true - }, - "description": { - "type": "string", - "nullable": true - } - } - }, - "BulkService": { - "type": "object", - "properties": { - "vulnerabilities": { - "default": [] + "nullable": true, + "minLength": 1 }, "_rev": { "type": "string", "readOnly": true }, - "host_id": { - "type": "integer", - "readOnly": true + "easeofresolution": { + "type": "string", + "enum": [ + "trivial", + "simple", + "moderate", + "difficult", + "infeasible" + ], + "nullable": true }, - "credentials": { - "default": [], + "cvss2": {}, + "cwe": { "type": "array", "items": { - "$ref": "#/components/schemas/BulkCredential" + "type": "string" } }, - "metadata": {}, - "vulns": { - "type": "integer", - "readOnly": true + "owasp": { + "type": "array", + "readOnly": true, + "items": { + "type": "string" + } }, "_id": { "type": "integer", "readOnly": true }, - "summary": { - "type": "string", + "issuetracker": { "readOnly": true }, - "type": { + "target": { + "type": "string", "readOnly": true }, - "port": { - "type": "integer", - "minimum": 0 - }, - "owned": { - "type": "boolean" - }, - "status": { + "data": { "type": "string", - "default": "open", - "enum": [ - "open", - "closed", - "filtered" - ] + "nullable": true }, - "description": { + "type": {}, + "cvss3": {}, + "resolution": { "type": "string", "nullable": true }, - "protocol": { - "type": "string", - "nullable": true, - "minLength": 1 + "policyviolations": { + "type": "array", + "items": { + "type": "string" + } }, - "owner": { + "_attachments": {}, + "date": { + "type": "string", + "format": "date-time", "readOnly": true }, - "version": { + "external_id": { "type": "string", "nullable": true }, - "id": { - "type": "integer" + "owned": { + "type": "boolean", + "readOnly": true }, - "name": { - "type": "string", - "nullable": true + "refs": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Reference" + } }, - "command_id": { - "type": "integer", - "writeOnly": true + "hostnames": { + "readOnly": true } }, "required": [ - "port", - "protocol" + "name", + "severity", + "type" ] }, "HostBulk": { "type": "object", "properties": { - "vulnerabilities": { - "default": [], - "type": "array", - "items": { - "$ref": "#/components/schemas/Vulnerability" - } - }, - "_rev": { - "type": "string", - "readOnly": true - }, "services": { "default": [], "type": "array", @@ -5537,140 +5583,94 @@ "$ref": "#/components/schemas/BulkService" } }, - "credentials": { - "default": [], - "type": "array", - "items": { - "$ref": "#/components/schemas/BulkCredential" - } - }, - "metadata": {}, - "mac": { - "type": "string", - "nullable": true - }, "vulns": { "type": "integer", "readOnly": true }, - "_id": { - "type": "integer", - "readOnly": true - }, - "ip": { - "type": "string" - }, - "versions": { - "readOnly": true - }, "service_summaries": { "readOnly": true }, - "type": { - "readOnly": true - }, - "hostnames": {}, - "importance": { - "type": "integer" - }, - "severity_counts": { - "readOnly": true - }, - "owned": { - "type": "boolean" - }, - "os": { - "type": "string" + "mac": { + "type": "string", + "nullable": true }, "description": { "type": "string" }, + "metadata": {}, "default_gateway": { "type": "string", "nullable": true }, + "ip": { + "type": "string" + }, + "os": { + "type": "string" + }, "owner": { "readOnly": true }, "id": { "type": "integer" }, - "name": { - "type": "string", - "readOnly": true - }, "command_id": { "type": "integer", "writeOnly": true - } - }, - "required": [ - "description", - "ip" - ] - }, - "BulkCommand": { - "type": "object", - "properties": { - "import_source": { - "enum": [ - "report", - "shell", - "agent" - ], - "nullable": true, - "maxLength": 6 }, - "start_date": { + "name": { "type": "string", - "format": "date-time" - }, - "duration": { - "type": "integer", - "x-unit": "microseconds" + "readOnly": true }, - "command": { + "_rev": { "type": "string", - "nullable": true, - "minLength": 1 + "readOnly": true }, - "params": { - "type": "string", - "nullable": true + "versions": { + "readOnly": true }, - "tool": { - "type": "string", - "nullable": true, - "minLength": 1 + "severity_counts": { + "readOnly": true }, - "user": { - "type": "string", - "nullable": true, - "maxLength": 250 + "_id": { + "type": "integer", + "readOnly": true }, - "hostname": { - "type": "string", - "nullable": true, - "maxLength": 250 + "importance": { + "type": "integer" }, - "ip": { - "type": "string", - "nullable": true, - "maxLength": 250 + "vulnerabilities": { + "default": [], + "type": "array", + "items": { + "$ref": "#/components/schemas/Vulnerability" + } + }, + "type": { + "readOnly": true + }, + "credentials": { + "default": [], + "type": "array", + "items": { + "$ref": "#/components/schemas/BulkCredential" + } }, - "creator": {} + "owned": { + "type": "boolean" + }, + "hostnames": {} }, "required": [ - "command", - "start_date", - "tool" + "description", + "ip" ] }, "BulkCreate": { "type": "object", "properties": { - "execution_id": { - "type": "integer" + "command": { + "$ref": "#/components/schemas/BulkCommand" }, "hosts": { "type": "array", @@ -5678,8 +5678,8 @@ "$ref": "#/components/schemas/HostBulk" } }, - "command": { - "$ref": "#/components/schemas/BulkCommand" + "execution_id": { + "type": "integer" } }, "required": [ @@ -5694,7 +5694,7 @@ "type": "string", "nullable": true }, - "user_query": { + "name": { "type": "string", "nullable": true }, @@ -5702,7 +5702,7 @@ "type": "integer", "readOnly": true }, - "name": { + "user_query": { "type": "string", "nullable": true } @@ -5791,4 +5791,4 @@ "name": "settings" } ] -} +} \ No newline at end of file diff --git a/faraday/server/api/modules/agent.py b/faraday/server/api/modules/agent.py index a4c16e50f76..735399cc4f2 100644 --- a/faraday/server/api/modules/agent.py +++ b/faraday/server/api/modules/agent.py @@ -282,7 +282,20 @@ def manifests_get(self): description: Ok """ try: - return flask.jsonify(get_manifests(request.args.get("agent_version"))) + manifest = get_manifests(request.args.get("agent_version")).copy() + if "BURP_API_PULL_INTERVAL" in manifest.get("burp", {}).get("environment_variables", ""): + manifest["burp"]["optional_environment_variables"] = [ + manifest["burp"].get("environment_variables").pop( + manifest["burp"]["environment_variables"].index("BURP_API_PULL_INTERVAL") + ) + ] + if "TENABLE_PULL_INTERVAL" in manifest.get("tenableio", {}).get("environment_variables", ""): + manifest["tenableio"]["optional_environment_variables"] = [ + manifest["tenableio"]["environment_variables"].pop( + manifest["tenableio"]["environment_variables"].index("TENABLE_PULL_INTERVAL") + ) + ] + return flask.jsonify(manifest) except ValueError as e: flask.abort(400, e) diff --git a/faraday/server/api/modules/vulns.py b/faraday/server/api/modules/vulns.py index bff21f7cfc2..de6b6510a4c 100644 --- a/faraday/server/api/modules/vulns.py +++ b/faraday/server/api/modules/vulns.py @@ -353,7 +353,6 @@ def load_parent(value): # sometimes api requests send str or unicode. value = int(value) except ValueError: - raise ValidationError("Invalid parent type") return value @@ -379,20 +378,33 @@ def post_load_parent(self, data, **kwargs): parent_field = None parent_type = data.pop('parent_type', None) parent_id = data.pop('parent', None) - if not (parent_type and parent_id): - # Probably a partial load, since they are required + + if not parent_type and not parent_id: return data + if parent_id and parent_type is None: + raise ValidationError('Trying to modify parent with no parent_type') + if parent_type and parent_id is None: + raise ValidationError('Trying to modify parent_type but parent not sent') + if parent_type == 'Host': parent_class = Host parent_field = 'host_id' + data['service_id'] = None if parent_type == 'Service': parent_class = Service parent_field = 'service_id' + data['host_id'] = None if not parent_class: raise ValidationError('Unknown parent type') - if parent_type == 'Host' and data['type'] == 'vulnerability_web': - raise ValidationError('Trying to set a host for a vulnerability web') - + if parent_type == 'Host': + if 'type' in data: + if data['type'] == 'vulnerability_web': + raise ValidationError('Trying to set a host for a vulnerability web') + elif kwargs.get("partial", False): + vulnerability = self.context.get("object", None) + if vulnerability: + if vulnerability.type == 'vulnerability_web': + raise ValidationError('Trying to set a host for a vulnerability web') try: parent = db.session.query(parent_class).join(Workspace).filter( Workspace.name == self.context['workspace_name'], @@ -1028,6 +1040,7 @@ def _generate_filter_query(vulnerability_class, filters, hostname_filters, works joinedload(Vulnerability.host), joinedload(Vulnerability.service), joinedload(VulnerabilityWeb.service), + joinedload(VulnerabilityGeneric.cwe), ) return vulns diff --git a/faraday/server/api/modules/workspaces.py b/faraday/server/api/modules/workspaces.py index 5835d43fd65..34833ef1632 100644 --- a/faraday/server/api/modules/workspaces.py +++ b/faraday/server/api/modules/workspaces.py @@ -84,7 +84,7 @@ def validate_workspace_name(name): blacklist = ["filter"] if name in blacklist: raise ValidationError(f"Not possible to create workspace of name: {name}") - if not re.match(r"^[a-z0-9][a-z0-9_$()+-]{0,250}$", name): + if not re.match(r"^[A-z0-9][A-z0-9_$()+-]{0,250}$", name): raise ValidationError("The workspace name must validate with the regex " "^[a-z0-9][a-z0-9_$()+-]{0,250}$") diff --git a/faraday/server/models.py b/faraday/server/models.py index 39a906c38f6..c458fe0458e 100644 --- a/faraday/server/models.py +++ b/faraday/server/models.py @@ -1090,6 +1090,7 @@ class Command(Metadata): foreign_keys=[workspace_id], backref=backref('commands', cascade="all, delete-orphan") ) + warnings = Column(String(250), nullable=True) sum_created_vulnerabilities = _make_created_objects_sum('vulnerability') sum_created_vulnerabilities_web = _make_created_objects_sum_joined('vulnerability', diff --git a/faraday/server/utils/filters.py b/faraday/server/utils/filters.py index 082ecb351dd..58f8ba2d78c 100644 --- a/faraday/server/utils/filters.py +++ b/faraday/server/utils/filters.py @@ -128,7 +128,7 @@ def _validate_filter_types(self, filter_): raise ValidationError('Relationship attribute to compare to must be a string') return [filter_] # has and any should be used with fields that has a relationship with other table - if filter_['op'].lower() in ['has', 'any']: + if filter_['op'].lower() in ['has', 'any', 'not_any']: return [filter_] else: raise ValidationError('Field does not support in operator') diff --git a/faraday/server/utils/search.py b/faraday/server/utils/search.py index e0252afe5ea..ecb3c473df6 100644 --- a/faraday/server/utils/search.py +++ b/faraday/server/utils/search.py @@ -155,6 +155,7 @@ def _sub_operator(model, argument, fieldname): # Operators which accept three arguments. 'has': lambda f, a, fn: f.has(_sub_operator(f, a, fn)), 'any': lambda f, a, fn: f.any(_sub_operator(f, a, fn)), + 'not_any': lambda f, a, fn: ~f.any(_sub_operator(f, a, fn)), } diff --git a/pynixify/packages/faraday-plugins/default.nix b/pynixify/packages/faraday-plugins/default.nix index 9831c0d0f82..b159cff66f7 100644 --- a/pynixify/packages/faraday-plugins/default.nix +++ b/pynixify/packages/faraday-plugins/default.nix @@ -11,6 +11,7 @@ , html2text , lib , lxml +, markdown , packaging , pytz , requests @@ -22,7 +23,7 @@ buildPythonPackage rec { pname = "faraday-plugins"; version = - "1.11.0"; + "1.12.0"; src = fetchPypi { @@ -30,7 +31,7 @@ buildPythonPackage rec { pname version; sha256 = - "1yzvhzc4rm473057dvwmc2kv6yzp9zp9hhhaj7knn0jbc7rapv2i"; + "0g4nfdyd4zmv7kdly1489q7mmsdm506hps1hs5l1sf4db37jwh17"; }; propagatedBuildInputs = @@ -46,6 +47,7 @@ buildPythonPackage rec { colorama tabulate packaging + markdown ]; # TODO FIXME diff --git a/pynixify/packages/faradaysec/default.nix b/pynixify/packages/faradaysec/default.nix index b2fc4424875..23974b17865 100644 --- a/pynixify/packages/faradaysec/default.nix +++ b/pynixify/packages/faradaysec/default.nix @@ -70,7 +70,7 @@ buildPythonPackage rec { pname = "faradaysec"; version = - "4.3.5"; + "4.4.0"; src = lib.cleanSource diff --git a/pynixify/packages/flask-socketio/default.nix b/pynixify/packages/flask-socketio/default.nix index 3a569c3a589..220fd9c7e38 100644 --- a/pynixify/packages/flask-socketio/default.nix +++ b/pynixify/packages/flask-socketio/default.nix @@ -13,7 +13,7 @@ buildPythonPackage rec { pname = "flask-socketio"; version = - "5.3.3"; + "5.3.4"; src = fetchPypi { @@ -22,7 +22,7 @@ buildPythonPackage rec { pname = "Flask-SocketIO"; sha256 = - "0pgfxy2rp45bxnmf384c87mxnw26vmhqckqzq35icsdps4npciwg"; + "0321g4l7k4w87xyl998kblvacbwj10bx0l27rixw72pnkff3gg8w"; }; propagatedBuildInputs = diff --git a/pynixify/packages/pyjwt/default.nix b/pynixify/packages/pyjwt/default.nix index a2bdabc7c8c..869a67c808b 100644 --- a/pynixify/packages/pyjwt/default.nix +++ b/pynixify/packages/pyjwt/default.nix @@ -11,7 +11,7 @@ buildPythonPackage rec { pname = "pyjwt"; version = - "2.6.0"; + "2.7.0"; src = fetchPypi { @@ -20,7 +20,7 @@ buildPythonPackage rec { pname = "PyJWT"; sha256 = - "1z85kwr945rbzrn5wabrsmck5x8disa9wc7b3y5gci7w65z5qa39"; + "0x70qffax798pbkcn3yd9kh99yzqzlss1ra98cnilp18qjis8v5x"; }; # TODO FIXME diff --git a/pynixify/packages/python-engineio/default.nix b/pynixify/packages/python-engineio/default.nix index 9827098c25c..12f2b5681f2 100644 --- a/pynixify/packages/python-engineio/default.nix +++ b/pynixify/packages/python-engineio/default.nix @@ -11,7 +11,7 @@ buildPythonPackage rec { pname = "python-engineio"; version = - "4.4.0"; + "4.4.1"; src = fetchPypi { @@ -19,7 +19,7 @@ buildPythonPackage rec { pname version; sha256 = - "1wjcs180yj6pq9cgml5dm9ngllbcradg37nlrz1sqc6c1v3kbh5w"; + "0a8c29h93npf5svbg3w15h4wv17z5mqnyf16nlk5j680ngn66dpb"; }; # TODO FIXME diff --git a/requirements.txt b/requirements.txt index 18755a71e2a..6a915c24462 100644 --- a/requirements.txt +++ b/requirements.txt @@ -36,7 +36,7 @@ syslog-rfc5424-formatter>=1.1.1 simplekv>=0.13.0 Flask-KVSession-fork>=0.6.4 distro>=1.4.0 -faraday-plugins>=1.10.0,<2.0.0 +faraday-plugins>=1.12.0,<2.0.0 apispec>=4.0.0,<5.0.0 apispec-webframeworks>=0.5.0 pyyaml diff --git a/tests/factories.py b/tests/factories.py index e196939ba30..3c680805bd8 100644 --- a/tests/factories.py +++ b/tests/factories.py @@ -262,7 +262,7 @@ class VulnerabilityGenericFactory(WorkspaceObjectFactory): class HasParentHostOrService(WorkspaceObjectFactory): """ Mixins for objects that must have either a host or a service, - but ont both, as a parent. + but not both, as a parent. By default it randomly select one of them and set the other to None, but this behavior can be modified as with other factory diff --git a/tests/test_api_agent.py b/tests/test_api_agent.py index 16223e47f89..a8824f8f527 100644 --- a/tests/test_api_agent.py +++ b/tests/test_api_agent.py @@ -410,4 +410,6 @@ def test_get_manifests(self, session, csrf_token, test_client): session.add(agent) session.commit() res = test_client.get(join(self.url(), 'get_manifests')) + assert "BURP_API_PULL_INTERVAL" in res.json["burp"]["optional_environment_variables"] + assert "TENABLE_PULL_INTERVAL" in res.json["tenableio"]["optional_environment_variables"] assert res.status_code == 200 diff --git a/tests/test_api_vulnerability.py b/tests/test_api_vulnerability.py index 7096d28aa2f..d8f480bc32a 100644 --- a/tests/test_api_vulnerability.py +++ b/tests/test_api_vulnerability.py @@ -1616,6 +1616,46 @@ def test_create_vuln_with_cve(self, cve_list, host_with_hostnames, test_client, assert session.query(CVE).count() == cve_list['cve']['count'] assert vuln_count_previous + 1 == session.query(Vulnerability).count() + @pytest.mark.usefixtures("ignore_nplusone") + def test_filter_vulns_not_contains_cve(self, test_client, session, host, vulnerability_factory, + vulnerability_web_factory): + VulnerabilityGeneric.query.delete() + session.commit() + + cve1 = CVE(name="CVE-2014-0160") + session.add(cve1) + + cve2 = CVE(name="CVE-2014-0161") + session.add(cve2) + + session.commit() + + vuln = vulnerability_factory.create(name="first_cve", host=host, workspace=self.workspace) + vuln.cve = [cve1.name] + session.add(vuln) + + vuln = vulnerability_factory.create(name="with_both_cve", host=host, workspace=self.workspace) + vuln.cve = [cve1.name, cve2.name] + session.add(vuln) + + vuln_web = vulnerability_web_factory.create(name="second_cve", host=host, workspace=self.workspace) + vuln_web.cve = [cve2.name] + session.add(vuln_web) + + vuln_web = vulnerability_web_factory.create(name="with_no_cve", host=host, workspace=self.workspace) + session.add(vuln_web) + session.commit() + + data = { + 'q': '{"filters":[{"name":"cve_instances","op":"not_any","val":{"name":"name","op":"eq","val":"CVE-2014-0160"}}]}' + } + res = test_client.get(f'/v3/ws/{self.workspace.name}/vulns/filter', query_string=data) + + assert res.status_code == 200 + assert len(res.json['vulnerabilities']) == 2 + assert 'first_cve' not in res.json['vulnerabilities'][0]['value']['name'] + assert 'first_cve' not in res.json['vulnerabilities'][1]['value']['name'] + # TODO: Esta repetido este test? def test_patch_vuln_with_cve_list(self, host_with_hostnames, test_client, session): session.commit() # flush host_with_hostnames @@ -2092,6 +2132,147 @@ def test_create_vuln_with_invalid_severity(self, assert vuln_count_previous == session.query(Vulnerability).count() assert b'Invalid severity type.' in res.data + def test_modify_parent(self, test_client, session, workspace): + host = HostFactory.create(ip='127.0.0.1', workspace=workspace) + session.add(host) + session.commit() + vulnerability = VulnerabilityFactory.create( + name='test', + host=host, + service=None, + workspace=workspace, + severity='low' + ) + session.add(vulnerability) + session.commit() + + assert vulnerability.host_id == host.id + + new_host = HostFactory(ip="192.168.10.1", workspace=workspace) + session.add(new_host) + session.commit() + + data = { + "parent": new_host.id, + "parent_type": "Host" + } + res = test_client.patch(f'{self.url(workspace=workspace)}/{vulnerability.id}', data=data) + assert res.status_code == 200 + assert res.json['parent'] == new_host.id + + def test_modify_parent_with_no_parent_type_or_parent(self, test_client, session, workspace): + host = HostFactory.create(ip='127.0.0.1', workspace=workspace) + session.add(host) + session.commit() + + service = ServiceFactory.create(name="ssh", workspace=workspace) + session.add(service) + session.commit() + + vulnerability = VulnerabilityFactory.create( + name='test', + host=host, + service=None, + workspace=workspace, + severity='low' + ) + session.add(vulnerability) + session.commit() + + assert vulnerability.host_id == host.id + + new_host = HostFactory(ip="192.168.10.1", workspace=workspace) + session.add(new_host) + session.commit() + + data = { + "parent": new_host.id, + } + res = test_client.patch(f'{self.url(workspace=workspace)}/{vulnerability.id}', data=data) + assert res.status_code == 400 + + data = { + "parent_type": "Service", + } + res = test_client.patch(f'{self.url(workspace=workspace)}/{vulnerability.id}', data=data) + assert res.status_code == 400 + + def test_modify_web_vuln_parent_with_host_parent_type(self, test_client, session, workspace): + service = ServiceFactory.create(name="ssh", workspace=workspace) + session.add(service) + session.commit() + vulnerability = VulnerabilityWebFactory.create( + name='test', + host=None, + service=service, + workspace=workspace, + severity='low' + ) + session.add(vulnerability) + session.commit() + + assert vulnerability.service_id == service.id + + new_host = HostFactory(ip="192.168.10.1", workspace=workspace) + session.add(new_host) + session.commit() + + data = { + "parent": new_host.id, + "parent_type": "Host" + } + res = test_client.patch(f'{self.url(workspace=workspace)}/{vulnerability.id}', data=data) + assert res.status_code == 400 + assert vulnerability.parent.id == service.id + + def test_modify_vulnerability_parent_from_host_parent_to_service_parent(self, test_client, session, workspace): + host = HostFactory.create(ip='127.0.0.1', workspace=workspace) + session.add(host) + session.commit() + + vulnerability = VulnerabilityFactory.create( + name='test', + host=host, + service=None, + workspace=workspace, + severity='low' + ) + session.add(vulnerability) + session.commit() + assert vulnerability.host_id == host.id + + service = ServiceFactory.create(name="ssh2", workspace=workspace) + session.add(service) + session.commit() + web_vulnerability = VulnerabilityWebFactory.create( + name='test', + host=None, + service=service, + workspace=workspace, + severity='low' + ) + session.add(web_vulnerability) + session.commit() + assert web_vulnerability.service_id == service.id + + new_service = ServiceFactory.create(name="ssh1", workspace=workspace) + session.add(new_service) + session.commit() + + data = { + "parent": new_service.id, + "parent_type": "Service" + } + res = test_client.patch(f'{self.url(workspace=workspace)}/{vulnerability.id}', data=data) + assert res.status_code == 200 + assert res.json['parent'] == new_service.id + assert res.json['parent_type'] == "Service" + + res = test_client.patch(f'{self.url(workspace=workspace)}/{web_vulnerability.id}', data=data) + assert res.status_code == 200 + assert res.json['parent'] == new_service.id + assert res.json['parent_type'] == "Service" + def test_create_vuln_with_invalid_ease_of_resolution(self, host_with_hostnames, test_client, @@ -3281,9 +3462,8 @@ def test_add_vuln_without_parent_id(self, test_client): refs=[], policyviolations=[], ) - with pytest.raises(Exception) as err: - res = test_client.post(self.url(), data=raw_data) - assert err.typename in ['AssertionError', 'ValueError'] + res = test_client.post(self.url(), data=raw_data) + assert res.status_code == 400 def test_add_vuln_with_unknown_parent_type(self, test_client, session, host_with_hostnames): session.commit() diff --git a/tests/test_api_workspace.py b/tests/test_api_workspace.py index 5269fea90d4..34ba65dff72 100644 --- a/tests/test_api_workspace.py +++ b/tests/test_api_workspace.py @@ -539,12 +539,12 @@ def test_create_fails_with_valid_duration(self, session, test_client): assert res.json['duration']['start_date'] == start_date assert res.json['duration']['end_date'] == end_date - def test_create_fails_with_mayus(self, session, test_client): + def test_create_succeeds_with_mayus(self, session, test_client): workspace_count_previous = session.query(Workspace).count() raw_data = {'name': 'sWtr'} res = test_client.post(self.url(), data=raw_data) - assert res.status_code == 400 - assert workspace_count_previous == session.query(Workspace).count() + assert res.status_code == 201 + assert workspace_count_previous + 1 == session.query(Workspace).count() def test_create_fails_with_special_character(self, session, test_client): workspace_count_previous = session.query(Workspace).count()