Skip to content

Commit

Permalink
Merge pull request from GHSA-rjmv-52mp-gjrr
Browse files Browse the repository at this point in the history
Fix that tasks are not created if the input encryption status does no…
  • Loading branch information
bartvanb committed Jan 18, 2024
2 parents 3fcc6e6 + 4ed8ecf commit 6383283
Showing 1 changed file with 63 additions and 3 deletions.
66 changes: 63 additions & 3 deletions vantage6-server/vantage6/server/resource/task.py
Expand Up @@ -11,6 +11,7 @@

from vantage6.common.globals import STRING_ENCODING
from vantage6.common.task_status import TaskStatus, has_task_finished
from vantage6.common.encryption import DummyCryptor
from vantage6.server import db
from vantage6.server.permission import (
RuleCollection,
Expand Down Expand Up @@ -490,6 +491,7 @@ def post(self):
"""
return self.post_task(request.get_json(), self.socketio, self.r)

# TODO this function should be refactored to make it more readable
@staticmethod
def post_task(data: dict, socketio: SocketIO, rules: RuleCollection):
"""
Expand Down Expand Up @@ -562,10 +564,8 @@ def post_task(data: dict, socketio: SocketIO, rules: RuleCollection):
"you are participating in!"
}, HTTPStatus.UNAUTHORIZED

# Create the new task in the database
image = data.get('image', '')

# verify permissions
image = data.get('image', '')
if g.user and not rules.can_for_col(P.CREATE, collaboration.id):
return {'msg': 'You lack the permission to do that!'}, \
HTTPStatus.UNAUTHORIZED
Expand All @@ -577,6 +577,17 @@ def post_task(data: dict, socketio: SocketIO, rules: RuleCollection):
return {"msg": "Container-token is not valid"}, \
HTTPStatus.UNAUTHORIZED

# check that the input is valid. If the collaboration is encrypted, it
# should not be possible to read the input, and we should not save it
# to the database as it may be sensitive information. Vice versa, if
# the collaboration is not encrypted, we should not allow the user to
# send encrypted input.
is_valid_input, error_msg = Tasks._check_input_encryption(
organizations_json_list, collaboration
)
if not is_valid_input:
return {"msg": error_msg}, HTTPStatus.BAD_REQUEST

# permissions ok, create task record and TaskDatabase records
task = db.Task(collaboration=collaboration, name=data.get('name', ''),
description=data.get('description', ''), image=image,
Expand Down Expand Up @@ -740,6 +751,55 @@ def _node_doesnt_allow_user_task(
return False
return has_limitations

@staticmethod
def _check_input_encryption(
organizations_json_list: list[dict], collaboration: db.Collaboration
) -> tuple[bool, str]:
"""
Check if the input encryption status matches the expected status for
the collaboration. Also, check that if the input is not encrypted, it
can be read as a string.
Parameters
----------
organizations_json_list : list[dict]
List of organizations which contains the input per organization.
collaboration : db.Collaboration
Collaboration object.
Returns
-------
bool
True if the input is encrypted.
str
Error message if the input is valid.
"""
dummy_cryptor = DummyCryptor()
for org in organizations_json_list:
input_ = org.get('input')
decrypted_input = dummy_cryptor.decrypt_str_to_bytes(input_)
is_input_readable = False
try:
decrypted_input.decode(STRING_ENCODING)
is_input_readable = True
except UnicodeDecodeError:
pass

if collaboration.encrypted and is_input_readable:
return False, (
"Your collaboration requires encryption, but input is not "
"encrypted! Please encrypt your input before sending it."
),
elif not collaboration.encrypted and not is_input_readable:
return False, (
"Your task's input cannot be parsed. Your input should be "
"a base64 encoded JSON string. Note that if you are using "
"the user interface or Python client, this should be done "
"for you. Also, make sure not to encrypt your input, "
"as your collaboration is set to not use encryption."
)
return True, ''


class Task(TaskBase):
"""Resource for /api/task"""
Expand Down

0 comments on commit 6383283

Please sign in to comment.