From 0cdf84cac55edf85fb566934a8b4c2176d0336ab Mon Sep 17 00:00:00 2001 From: vakarisz Date: Wed, 25 May 2022 11:31:28 +0300 Subject: [PATCH] Island: Extract jwt_required decorator into separate file --- .../agent_controls/stop_all_agents.py | 2 +- .../cc/resources/attack/attack_report.py | 2 +- .../monkey_island/cc/resources/auth/auth.py | 25 ++------------- .../cc/resources/blackbox/clear_caches.py | 2 +- .../blackbox/log_blackbox_endpoint.py | 2 +- .../blackbox/monkey_blackbox_endpoint.py | 2 +- .../blackbox/telemetry_blackbox_endpoint.py | 2 +- .../cc/resources/configuration_export.py | 2 +- .../cc/resources/configuration_import.py | 2 +- .../exploitations/manual_exploitation.py | 2 +- .../exploitations/monkey_exploitation.py | 2 +- .../cc/resources/island_configuration.py | 2 +- .../monkey_island/cc/resources/island_logs.py | 2 +- .../monkey_island/cc/resources/island_mode.py | 2 +- .../monkey_island/cc/resources/local_run.py | 2 +- monkey/monkey_island/cc/resources/log.py | 2 +- monkey/monkey_island/cc/resources/netmap.py | 2 +- monkey/monkey_island/cc/resources/node.py | 2 +- .../monkey_island/cc/resources/node_states.py | 2 +- .../cc/resources/pba_file_upload.py | 2 +- .../cc/resources/ransomware_report.py | 2 +- .../monkey_island/cc/resources/remote_run.py | 2 +- .../cc/resources/request_authentication.py | 31 +++++++++++++++++++ monkey/monkey_island/cc/resources/root.py | 2 +- .../cc/resources/security_report.py | 2 +- .../monkey_island/cc/resources/telemetry.py | 2 +- .../cc/resources/telemetry_feed.py | 2 +- .../cc/resources/zero_trust/finding_event.py | 2 +- .../resources/zero_trust/zero_trust_report.py | 2 +- 29 files changed, 60 insertions(+), 50 deletions(-) create mode 100644 monkey/monkey_island/cc/resources/request_authentication.py diff --git a/monkey/monkey_island/cc/resources/agent_controls/stop_all_agents.py b/monkey/monkey_island/cc/resources/agent_controls/stop_all_agents.py index c843a3d79..82667ecf2 100644 --- a/monkey/monkey_island/cc/resources/agent_controls/stop_all_agents.py +++ b/monkey/monkey_island/cc/resources/agent_controls/stop_all_agents.py @@ -3,7 +3,7 @@ import json from flask import make_response, request from monkey_island.cc.resources.AbstractResource import AbstractResource -from monkey_island.cc.resources.auth.auth import jwt_required +from monkey_island.cc.resources.request_authentication import jwt_required from monkey_island.cc.resources.utils.semaphores import agent_killing_mutex from monkey_island.cc.services.infection_lifecycle import set_stop_all, should_agent_die diff --git a/monkey/monkey_island/cc/resources/attack/attack_report.py b/monkey/monkey_island/cc/resources/attack/attack_report.py index 95675e5b6..2dffa929d 100644 --- a/monkey/monkey_island/cc/resources/attack/attack_report.py +++ b/monkey/monkey_island/cc/resources/attack/attack_report.py @@ -1,7 +1,7 @@ from flask import current_app, json from monkey_island.cc.resources.AbstractResource import AbstractResource -from monkey_island.cc.resources.auth.auth import jwt_required +from monkey_island.cc.resources.request_authentication import jwt_required from monkey_island.cc.services.attack.attack_report import AttackReportService from monkey_island.cc.services.attack.attack_schema import SCHEMA diff --git a/monkey/monkey_island/cc/resources/auth/auth.py b/monkey/monkey_island/cc/resources/auth/auth.py index e7a2d742e..57c78cfe0 100644 --- a/monkey/monkey_island/cc/resources/auth/auth.py +++ b/monkey/monkey_island/cc/resources/auth/auth.py @@ -6,6 +6,7 @@ from flask import make_response, request from common.utils.exceptions import IncorrectCredentialsError from monkey_island.cc.resources.AbstractResource import AbstractResource from monkey_island.cc.resources.auth.credential_utils import get_username_password_from_request +from monkey_island.cc.resources.request_authentication import create_access_token from monkey_island.cc.services import AuthenticationService logger = logging.getLogger(__name__) @@ -39,30 +40,8 @@ class Authenticate(AbstractResource): try: AuthenticationService.authenticate(username, password) - access_token = _create_access_token(username) + access_token = create_access_token(username) except IncorrectCredentialsError: return make_response({"error": "Invalid credentials"}, 401) return make_response({"access_token": access_token, "error": ""}, 200) - - -def _create_access_token(username): - access_token = flask_jwt_extended.create_access_token(identity=username) - logger.debug(f"Created access token for user {username} that begins with {access_token[:4]}") - - return access_token - - -# See https://flask-jwt-extended.readthedocs.io/en/stable/custom_decorators/ -def jwt_required(fn): - @wraps(fn) - def wrapper(*args, **kwargs): - try: - flask_jwt_extended.verify_jwt_in_request() - return fn(*args, **kwargs) - # Catch authentication related errors in the verification or inside the called function. - # All other exceptions propagate - except (JWTExtendedException, PyJWTError) as e: - return make_response({"error": f"Authentication error: {str(e)}"}, 401) - - return wrapper diff --git a/monkey/monkey_island/cc/resources/blackbox/clear_caches.py b/monkey/monkey_island/cc/resources/blackbox/clear_caches.py index 289a85d04..116bc0f07 100644 --- a/monkey/monkey_island/cc/resources/blackbox/clear_caches.py +++ b/monkey/monkey_island/cc/resources/blackbox/clear_caches.py @@ -3,7 +3,7 @@ import logging import flask_restful from monkey_island.cc.resources.AbstractResource import AbstractResource -from monkey_island.cc.resources.auth.auth import jwt_required +from monkey_island.cc.resources.request_authentication import jwt_required from monkey_island.cc.services.attack.attack_report import AttackReportService from monkey_island.cc.services.reporting.report import ReportService diff --git a/monkey/monkey_island/cc/resources/blackbox/log_blackbox_endpoint.py b/monkey/monkey_island/cc/resources/blackbox/log_blackbox_endpoint.py index aa8f168b2..a2700cc37 100644 --- a/monkey/monkey_island/cc/resources/blackbox/log_blackbox_endpoint.py +++ b/monkey/monkey_island/cc/resources/blackbox/log_blackbox_endpoint.py @@ -3,7 +3,7 @@ from flask import request from monkey_island.cc.database import database, mongo from monkey_island.cc.resources.AbstractResource import AbstractResource -from monkey_island.cc.resources.auth.auth import jwt_required +from monkey_island.cc.resources.request_authentication import jwt_required class LogBlackboxEndpoint(AbstractResource): diff --git a/monkey/monkey_island/cc/resources/blackbox/monkey_blackbox_endpoint.py b/monkey/monkey_island/cc/resources/blackbox/monkey_blackbox_endpoint.py index ac8790e6a..b02cf224f 100644 --- a/monkey/monkey_island/cc/resources/blackbox/monkey_blackbox_endpoint.py +++ b/monkey/monkey_island/cc/resources/blackbox/monkey_blackbox_endpoint.py @@ -3,7 +3,7 @@ from flask import request from monkey_island.cc.database import mongo from monkey_island.cc.resources.AbstractResource import AbstractResource -from monkey_island.cc.resources.auth.auth import jwt_required +from monkey_island.cc.resources.request_authentication import jwt_required class MonkeyBlackboxEndpoint(AbstractResource): diff --git a/monkey/monkey_island/cc/resources/blackbox/telemetry_blackbox_endpoint.py b/monkey/monkey_island/cc/resources/blackbox/telemetry_blackbox_endpoint.py index f20b5f474..e3b91cc46 100644 --- a/monkey/monkey_island/cc/resources/blackbox/telemetry_blackbox_endpoint.py +++ b/monkey/monkey_island/cc/resources/blackbox/telemetry_blackbox_endpoint.py @@ -3,7 +3,7 @@ from flask import request from monkey_island.cc.models.telemetries import get_telemetry_by_query from monkey_island.cc.resources.AbstractResource import AbstractResource -from monkey_island.cc.resources.auth.auth import jwt_required +from monkey_island.cc.resources.request_authentication import jwt_required class TelemetryBlackboxEndpoint(AbstractResource): diff --git a/monkey/monkey_island/cc/resources/configuration_export.py b/monkey/monkey_island/cc/resources/configuration_export.py index 8a7726ff6..e10e5d1a3 100644 --- a/monkey/monkey_island/cc/resources/configuration_export.py +++ b/monkey/monkey_island/cc/resources/configuration_export.py @@ -3,7 +3,7 @@ import json from flask import request from monkey_island.cc.resources.AbstractResource import AbstractResource -from monkey_island.cc.resources.auth.auth import jwt_required +from monkey_island.cc.resources.request_authentication import jwt_required from monkey_island.cc.server_utils.encryption import PasswordBasedStringEncryptor from monkey_island.cc.services.config import ConfigService diff --git a/monkey/monkey_island/cc/resources/configuration_import.py b/monkey/monkey_island/cc/resources/configuration_import.py index 7843a03da..ecf94e986 100644 --- a/monkey/monkey_island/cc/resources/configuration_import.py +++ b/monkey/monkey_island/cc/resources/configuration_import.py @@ -7,7 +7,7 @@ from flask import request from common.utils.exceptions import InvalidConfigurationError from monkey_island.cc.resources.AbstractResource import AbstractResource -from monkey_island.cc.resources.auth.auth import jwt_required +from monkey_island.cc.resources.request_authentication import jwt_required from monkey_island.cc.server_utils.encryption import ( InvalidCiphertextError, InvalidCredentialsError, diff --git a/monkey/monkey_island/cc/resources/exploitations/manual_exploitation.py b/monkey/monkey_island/cc/resources/exploitations/manual_exploitation.py index d15a3a0f0..8006e31af 100644 --- a/monkey/monkey_island/cc/resources/exploitations/manual_exploitation.py +++ b/monkey/monkey_island/cc/resources/exploitations/manual_exploitation.py @@ -1,5 +1,5 @@ from monkey_island.cc.resources.AbstractResource import AbstractResource -from monkey_island.cc.resources.auth.auth import jwt_required +from monkey_island.cc.resources.request_authentication import jwt_required from monkey_island.cc.services.reporting.exploitations.manual_exploitation import ( get_manual_exploitations, ) diff --git a/monkey/monkey_island/cc/resources/exploitations/monkey_exploitation.py b/monkey/monkey_island/cc/resources/exploitations/monkey_exploitation.py index 70468a057..5cbf42a35 100644 --- a/monkey/monkey_island/cc/resources/exploitations/monkey_exploitation.py +++ b/monkey/monkey_island/cc/resources/exploitations/monkey_exploitation.py @@ -1,5 +1,5 @@ from monkey_island.cc.resources.AbstractResource import AbstractResource -from monkey_island.cc.resources.auth.auth import jwt_required +from monkey_island.cc.resources.request_authentication import jwt_required from monkey_island.cc.services.reporting.exploitations.monkey_exploitation import ( get_monkey_exploited, ) diff --git a/monkey/monkey_island/cc/resources/island_configuration.py b/monkey/monkey_island/cc/resources/island_configuration.py index fb9aff16c..21da243ed 100644 --- a/monkey/monkey_island/cc/resources/island_configuration.py +++ b/monkey/monkey_island/cc/resources/island_configuration.py @@ -3,7 +3,7 @@ import json from flask import abort, jsonify, request from monkey_island.cc.resources.AbstractResource import AbstractResource -from monkey_island.cc.resources.auth.auth import jwt_required +from monkey_island.cc.resources.request_authentication import jwt_required from monkey_island.cc.services.config import ConfigService diff --git a/monkey/monkey_island/cc/resources/island_logs.py b/monkey/monkey_island/cc/resources/island_logs.py index 7c9da657d..ec36b7a88 100644 --- a/monkey/monkey_island/cc/resources/island_logs.py +++ b/monkey/monkey_island/cc/resources/island_logs.py @@ -1,7 +1,7 @@ import logging from monkey_island.cc.resources.AbstractResource import AbstractResource -from monkey_island.cc.resources.auth.auth import jwt_required +from monkey_island.cc.resources.request_authentication import jwt_required from monkey_island.cc.services.island_logs import IslandLogService logger = logging.getLogger(__name__) diff --git a/monkey/monkey_island/cc/resources/island_mode.py b/monkey/monkey_island/cc/resources/island_mode.py index 4fa666ca7..fed0d0aff 100644 --- a/monkey/monkey_island/cc/resources/island_mode.py +++ b/monkey/monkey_island/cc/resources/island_mode.py @@ -4,7 +4,7 @@ import logging from flask import make_response, request from monkey_island.cc.resources.AbstractResource import AbstractResource -from monkey_island.cc.resources.auth.auth import jwt_required +from monkey_island.cc.resources.request_authentication import jwt_required from monkey_island.cc.services.config_manipulator import update_config_on_mode_set from monkey_island.cc.services.mode.island_mode_service import ModeNotSetError, get_mode, set_mode from monkey_island.cc.services.mode.mode_enum import IslandModeEnum diff --git a/monkey/monkey_island/cc/resources/local_run.py b/monkey/monkey_island/cc/resources/local_run.py index 320b064eb..7de0b844a 100644 --- a/monkey/monkey_island/cc/resources/local_run.py +++ b/monkey/monkey_island/cc/resources/local_run.py @@ -4,7 +4,7 @@ from flask import jsonify, make_response, request from monkey_island.cc.models import Monkey from monkey_island.cc.resources.AbstractResource import AbstractResource -from monkey_island.cc.resources.auth.auth import jwt_required +from monkey_island.cc.resources.request_authentication import jwt_required from monkey_island.cc.services.node import NodeService from monkey_island.cc.services.run_local_monkey import LocalMonkeyRunService diff --git a/monkey/monkey_island/cc/resources/log.py b/monkey/monkey_island/cc/resources/log.py index 5499e8ac9..541ffb1af 100644 --- a/monkey/monkey_island/cc/resources/log.py +++ b/monkey/monkey_island/cc/resources/log.py @@ -5,8 +5,8 @@ from flask import request from monkey_island.cc.database import mongo from monkey_island.cc.resources.AbstractResource import AbstractResource -from monkey_island.cc.resources.auth.auth import jwt_required from monkey_island.cc.resources.blackbox.utils.telem_store import TestTelemStore +from monkey_island.cc.resources.request_authentication import jwt_required from monkey_island.cc.services.log import LogService from monkey_island.cc.services.node import NodeService diff --git a/monkey/monkey_island/cc/resources/netmap.py b/monkey/monkey_island/cc/resources/netmap.py index a5f08901b..c9d99cfb8 100644 --- a/monkey/monkey_island/cc/resources/netmap.py +++ b/monkey/monkey_island/cc/resources/netmap.py @@ -1,5 +1,5 @@ from monkey_island.cc.resources.AbstractResource import AbstractResource -from monkey_island.cc.resources.auth.auth import jwt_required +from monkey_island.cc.resources.request_authentication import jwt_required from monkey_island.cc.services.netmap.net_edge import NetEdgeService from monkey_island.cc.services.netmap.net_node import NetNodeService diff --git a/monkey/monkey_island/cc/resources/node.py b/monkey/monkey_island/cc/resources/node.py index 1dfa83f45..e8b6e0079 100644 --- a/monkey/monkey_island/cc/resources/node.py +++ b/monkey/monkey_island/cc/resources/node.py @@ -1,7 +1,7 @@ from flask import request from monkey_island.cc.resources.AbstractResource import AbstractResource -from monkey_island.cc.resources.auth.auth import jwt_required +from monkey_island.cc.resources.request_authentication import jwt_required from monkey_island.cc.services.node import NodeService diff --git a/monkey/monkey_island/cc/resources/node_states.py b/monkey/monkey_island/cc/resources/node_states.py index 484c2497a..88b4d7d64 100644 --- a/monkey/monkey_island/cc/resources/node_states.py +++ b/monkey/monkey_island/cc/resources/node_states.py @@ -1,5 +1,5 @@ from monkey_island.cc.resources.AbstractResource import AbstractResource -from monkey_island.cc.resources.auth.auth import jwt_required +from monkey_island.cc.resources.request_authentication import jwt_required from monkey_island.cc.services.utils.node_states import NodeStates as NodeStateList diff --git a/monkey/monkey_island/cc/resources/pba_file_upload.py b/monkey/monkey_island/cc/resources/pba_file_upload.py index 2dada0f71..9f741a039 100644 --- a/monkey/monkey_island/cc/resources/pba_file_upload.py +++ b/monkey/monkey_island/cc/resources/pba_file_upload.py @@ -6,7 +6,7 @@ from werkzeug.utils import secure_filename as sanitize_filename from common.config_value_paths import PBA_LINUX_FILENAME_PATH, PBA_WINDOWS_FILENAME_PATH from monkey_island.cc.resources.AbstractResource import AbstractResource -from monkey_island.cc.resources.auth.auth import jwt_required +from monkey_island.cc.resources.request_authentication import jwt_required from monkey_island.cc.services import FileRetrievalError, IFileStorageService from monkey_island.cc.services.config import ConfigService diff --git a/monkey/monkey_island/cc/resources/ransomware_report.py b/monkey/monkey_island/cc/resources/ransomware_report.py index 676652542..d229361ea 100644 --- a/monkey/monkey_island/cc/resources/ransomware_report.py +++ b/monkey/monkey_island/cc/resources/ransomware_report.py @@ -1,7 +1,7 @@ from flask import jsonify from monkey_island.cc.resources.AbstractResource import AbstractResource -from monkey_island.cc.resources.auth.auth import jwt_required +from monkey_island.cc.resources.request_authentication import jwt_required from monkey_island.cc.services.ransomware import ransomware_report diff --git a/monkey/monkey_island/cc/resources/remote_run.py b/monkey/monkey_island/cc/resources/remote_run.py index 8b57d0e3d..820419487 100644 --- a/monkey/monkey_island/cc/resources/remote_run.py +++ b/monkey/monkey_island/cc/resources/remote_run.py @@ -5,7 +5,7 @@ from botocore.exceptions import ClientError, NoCredentialsError from flask import jsonify, make_response, request from monkey_island.cc.resources.AbstractResource import AbstractResource -from monkey_island.cc.resources.auth.auth import jwt_required +from monkey_island.cc.resources.request_authentication import jwt_required from monkey_island.cc.services import AWSService from monkey_island.cc.services.aws import AWSCommandResults diff --git a/monkey/monkey_island/cc/resources/request_authentication.py b/monkey/monkey_island/cc/resources/request_authentication.py new file mode 100644 index 000000000..6fd97d016 --- /dev/null +++ b/monkey/monkey_island/cc/resources/request_authentication.py @@ -0,0 +1,31 @@ +import logging +from functools import wraps + +import flask_jwt_extended +from flask import make_response +from flask_jwt_extended.exceptions import JWTExtendedException +from jwt import PyJWTError + +logger = logging.getLogger(__name__) + + +def create_access_token(username): + access_token = flask_jwt_extended.create_access_token(identity=username) + logger.debug(f"Created access token for user {username} that begins with {access_token[:4]}") + + return access_token + + +# See https://flask-jwt-extended.readthedocs.io/en/stable/custom_decorators/ +def jwt_required(fn): + @wraps(fn) + def wrapper(*args, **kwargs): + try: + flask_jwt_extended.verify_jwt_in_request() + return fn(*args, **kwargs) + # Catch authentication related errors in the verification or inside the called function. + # All other exceptions propagate + except (JWTExtendedException, PyJWTError) as e: + return make_response({"error": f"Authentication error: {str(e)}"}, 401) + + return wrapper diff --git a/monkey/monkey_island/cc/resources/root.py b/monkey/monkey_island/cc/resources/root.py index 6994fee62..23e39aa49 100644 --- a/monkey/monkey_island/cc/resources/root.py +++ b/monkey/monkey_island/cc/resources/root.py @@ -4,7 +4,7 @@ from flask import jsonify, make_response, request from monkey_island.cc.database import mongo from monkey_island.cc.resources.AbstractResource import AbstractResource -from monkey_island.cc.resources.auth.auth import jwt_required +from monkey_island.cc.resources.request_authentication import jwt_required from monkey_island.cc.services.database import Database from monkey_island.cc.services.infection_lifecycle import get_completed_steps from monkey_island.cc.services.utils.network_utils import local_ip_addresses diff --git a/monkey/monkey_island/cc/resources/security_report.py b/monkey/monkey_island/cc/resources/security_report.py index afcf43add..62b254931 100644 --- a/monkey/monkey_island/cc/resources/security_report.py +++ b/monkey/monkey_island/cc/resources/security_report.py @@ -1,5 +1,5 @@ from monkey_island.cc.resources.AbstractResource import AbstractResource -from monkey_island.cc.resources.auth.auth import jwt_required +from monkey_island.cc.resources.request_authentication import jwt_required from monkey_island.cc.services.reporting.report import ReportService diff --git a/monkey/monkey_island/cc/resources/telemetry.py b/monkey/monkey_island/cc/resources/telemetry.py index 971f39a96..11e4ba06e 100644 --- a/monkey/monkey_island/cc/resources/telemetry.py +++ b/monkey/monkey_island/cc/resources/telemetry.py @@ -9,8 +9,8 @@ from monkey_island.cc.database import mongo from monkey_island.cc.models.monkey import Monkey from monkey_island.cc.models.telemetries import get_telemetry_by_query from monkey_island.cc.resources.AbstractResource import AbstractResource -from monkey_island.cc.resources.auth.auth import jwt_required from monkey_island.cc.resources.blackbox.utils.telem_store import TestTelemStore +from monkey_island.cc.resources.request_authentication import jwt_required from monkey_island.cc.services.node import NodeService from monkey_island.cc.services.telemetry.processing.processing import process_telemetry diff --git a/monkey/monkey_island/cc/resources/telemetry_feed.py b/monkey/monkey_island/cc/resources/telemetry_feed.py index 8314f6576..fa97f3257 100644 --- a/monkey/monkey_island/cc/resources/telemetry_feed.py +++ b/monkey/monkey_island/cc/resources/telemetry_feed.py @@ -8,7 +8,7 @@ from flask import request from common.common_consts.telem_categories import TelemCategoryEnum from monkey_island.cc.database import mongo from monkey_island.cc.resources.AbstractResource import AbstractResource -from monkey_island.cc.resources.auth.auth import jwt_required +from monkey_island.cc.resources.request_authentication import jwt_required from monkey_island.cc.services.node import NodeService logger = logging.getLogger(__name__) diff --git a/monkey/monkey_island/cc/resources/zero_trust/finding_event.py b/monkey/monkey_island/cc/resources/zero_trust/finding_event.py index d232e83d7..d96e741f9 100644 --- a/monkey/monkey_island/cc/resources/zero_trust/finding_event.py +++ b/monkey/monkey_island/cc/resources/zero_trust/finding_event.py @@ -1,7 +1,7 @@ import json from monkey_island.cc.resources.AbstractResource import AbstractResource -from monkey_island.cc.resources.auth.auth import jwt_required +from monkey_island.cc.resources.request_authentication import jwt_required from monkey_island.cc.services.zero_trust.monkey_findings.monkey_zt_finding_service import ( MonkeyZTFindingService, ) diff --git a/monkey/monkey_island/cc/resources/zero_trust/zero_trust_report.py b/monkey/monkey_island/cc/resources/zero_trust/zero_trust_report.py index 9e32b72bd..359328114 100644 --- a/monkey/monkey_island/cc/resources/zero_trust/zero_trust_report.py +++ b/monkey/monkey_island/cc/resources/zero_trust/zero_trust_report.py @@ -4,7 +4,7 @@ import flask_restful from flask import jsonify from monkey_island.cc.resources.AbstractResource import AbstractResource -from monkey_island.cc.resources.auth.auth import jwt_required +from monkey_island.cc.resources.request_authentication import jwt_required from monkey_island.cc.services.zero_trust.zero_trust_report.finding_service import FindingService from monkey_island.cc.services.zero_trust.zero_trust_report.pillar_service import PillarService from monkey_island.cc.services.zero_trust.zero_trust_report.principle_service import (