From 59a4b477dd922d2f839a717fe199501e7cb71e6e Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Sat, 22 Oct 2022 13:47:40 +0200 Subject: [proxy] simplify usage of class variables of `Policy` subtypes This commit also prevents popup script injection to Haketilo-served pages like `https://hkt.mitm.it/`. --- src/hydrilla/proxy/policies/base.py | 18 +++++++++++++----- src/hydrilla/proxy/policies/misc.py | 14 ++++++-------- src/hydrilla/proxy/policies/payload.py | 14 ++++++-------- src/hydrilla/proxy/policies/payload_resource.py | 11 +++++------ src/hydrilla/proxy/policies/rule.py | 10 +++------- src/hydrilla/proxy/policies/web_ui.py | 6 +++--- 6 files changed, 36 insertions(+), 37 deletions(-) diff --git a/src/hydrilla/proxy/policies/base.py b/src/hydrilla/proxy/policies/base.py index 0c37185..7ce5105 100644 --- a/src/hydrilla/proxy/policies/base.py +++ b/src/hydrilla/proxy/policies/base.py @@ -62,12 +62,20 @@ popup_script = jinja_env.get_template('popup.js.jinja').render() popup_script_sha256_bytes = sha256(popup_script.encode()).digest() popup_script_sha256_b64 = b64encode(popup_script_sha256_bytes).decode() + class PolicyPriority(int, enum.Enum): """....""" _ONE = 1 _TWO = 2 _THREE = 3 + +class MsgProcessOpt(enum.Enum): + """....""" + MUST = True + MUST_NOT = False + + MessageInfo = t.Union[ http_messages.RequestInfo, http_messages.ResponseInfo @@ -91,8 +99,8 @@ BOMs = ( # https://stackoverflow.com/questions/70999513/conflict-between-mix-ins-for-abstract-dataclasses/70999704#70999704 @dc.dataclass(frozen=True) # type: ignore[misc] class Policy(ABC): - _process_request: t.ClassVar[bool] = False - _process_response: t.ClassVar[bool] = False + _process_request: t.ClassVar[t.Optional[MsgProcessOpt]] = None + _process_response: t.ClassVar[t.Optional[MsgProcessOpt]] = None anticache: t.ClassVar[bool] = True priority: t.ClassVar[PolicyPriority] @@ -107,15 +115,15 @@ class Policy(ABC): self, request_info: http_messages.BodylessRequestInfo ) -> bool: - return self._process_request + return self._process_request == MsgProcessOpt.MUST def should_process_response( self, request_info: http_messages.RequestInfo, response_info: http_messages.AnyResponseInfo ) -> bool: - if self._process_response: - return True + if self._process_response is not None: + return self._process_response.value return (self.current_popup_settings.popup_enabled and http_messages.is_likely_a_page(request_info, response_info)) diff --git a/src/hydrilla/proxy/policies/misc.py b/src/hydrilla/proxy/policies/misc.py index af6c144..350f3dc 100644 --- a/src/hydrilla/proxy/policies/misc.py +++ b/src/hydrilla/proxy/policies/misc.py @@ -42,13 +42,11 @@ from .rule import AllowPolicy, BlockPolicy class FallbackAllowPolicy(AllowPolicy): - """.....""" - priority: t.ClassVar[base.PolicyPriority] = base.PolicyPriority._ONE + priority = base.PolicyPriority._ONE class FallbackBlockPolicy(BlockPolicy): - """....""" - priority: t.ClassVar[base.PolicyPriority] = base.PolicyPriority._ONE + priority = base.PolicyPriority._ONE @dc.dataclass(frozen=True) @@ -63,11 +61,11 @@ class MitmItPagePolicy(base.Policy): request and response not to be modified in any way and also (unlike FallbackAllowPolicy) prevents them from being streamed. """ - _process_request: t.ClassVar[bool] = True - _process_response: t.ClassVar[bool] = True - anticache: t.ClassVar[bool] = False + _process_request = base.MsgProcessOpt.MUST + _process_response = base.MsgProcessOpt.MUST + anticache = False - priority: t.ClassVar[base.PolicyPriority] = base.PolicyPriority._THREE + priority = base.PolicyPriority._THREE def consume_request(self, request_info: http_messages.RequestInfo) -> None: return None diff --git a/src/hydrilla/proxy/policies/payload.py b/src/hydrilla/proxy/policies/payload.py index 76a1202..3252c6a 100644 --- a/src/hydrilla/proxy/policies/payload.py +++ b/src/hydrilla/proxy/policies/payload.py @@ -105,10 +105,9 @@ def block_attr(element: bs4.PageElement, attr_name: str) -> None: @dc.dataclass(frozen=True) class PayloadInjectPolicy(PayloadAwarePolicy): - """....""" - _process_response: t.ClassVar[bool] = True + _process_response = base.MsgProcessOpt.MUST - priority: t.ClassVar[base.PolicyPriority] = base.PolicyPriority._TWO + priority = base.PolicyPriority._TWO @property def current_popup_settings(self) -> state.PopupSettings: @@ -179,8 +178,7 @@ class _PayloadHasProblemsError(HaketiloException): pass class AutoPayloadInjectPolicy(PayloadInjectPolicy): - """....""" - priority: t.ClassVar[base.PolicyPriority] = base.PolicyPriority._ONE + priority = base.PolicyPriority._ONE def consume_response(self, http_info: http_messages.FullHTTPInfo) \ -> t.Optional[http_messages.ResponseInfo]: @@ -217,10 +215,10 @@ class AutoPayloadInjectPolicy(PayloadInjectPolicy): @dc.dataclass(frozen=True) class PayloadSuggestPolicy(PayloadAwarePolicy): - """....""" - _process_request: t.ClassVar[bool] = True + _process_request = base.MsgProcessOpt.MUST + _process_response = base.MsgProcessOpt.MUST_NOT - priority: t.ClassVar[base.PolicyPriority] = base.PolicyPriority._ONE + priority = base.PolicyPriority._ONE def consume_request(self, request_info: http_messages.RequestInfo) \ -> http_messages.ResponseInfo: diff --git a/src/hydrilla/proxy/policies/payload_resource.py b/src/hydrilla/proxy/policies/payload_resource.py index d8e5ea5..38cfd21 100644 --- a/src/hydrilla/proxy/policies/payload_resource.py +++ b/src/hydrilla/proxy/policies/payload_resource.py @@ -212,10 +212,9 @@ MessageInfo = t.Union[ @dc.dataclass(frozen=True) class PayloadResourcePolicy(PayloadAwarePolicy): - """....""" - _process_request: t.ClassVar[bool] = True + _process_request = base.MsgProcessOpt.MUST - priority: t.ClassVar[base.PolicyPriority] = base.PolicyPriority._THREE + priority = base.PolicyPriority._THREE def extract_resource_path(self, request_url: ParsedUrl) -> tuple[str, ...]: # Payload resource pattern has path of the form: @@ -370,10 +369,10 @@ resource_blocked_response = http_messages.ResponseInfo.make( @dc.dataclass(frozen=True) class BlockedResponsePolicy(base.Policy): - """....""" - _process_request: t.ClassVar[bool] = True + _process_request = base.MsgProcessOpt.MUST + _process_response = base.MsgProcessOpt.MUST_NOT - priority: t.ClassVar[base.PolicyPriority] = base.PolicyPriority._THREE + priority = base.PolicyPriority._THREE def consume_request(self, request_info: http_messages.RequestInfo) \ -> http_messages.ResponseInfo: diff --git a/src/hydrilla/proxy/policies/rule.py b/src/hydrilla/proxy/policies/rule.py index 2a6d8cb..8c5e69b 100644 --- a/src/hydrilla/proxy/policies/rule.py +++ b/src/hydrilla/proxy/policies/rule.py @@ -40,17 +40,15 @@ from . import base class AllowPolicy(base.Policy): - """....""" - priority: t.ClassVar[base.PolicyPriority] = base.PolicyPriority._TWO + priority = base.PolicyPriority._TWO script_csp_directives = ('script-src', 'script-src-elem', 'script-src-attr') class BlockPolicy(base.Policy): - """....""" - _process_response: t.ClassVar[bool] = True + _process_response = base.MsgProcessOpt.MUST - priority: t.ClassVar[base.PolicyPriority] = base.PolicyPriority._TWO + priority = base.PolicyPriority._TWO @property def current_popup_settings(self) -> state.PopupSettings: @@ -67,13 +65,11 @@ class BlockPolicy(base.Policy): @dc.dataclass(frozen=True) class RuleAllowPolicy(AllowPolicy): - """....""" pattern: ParsedPattern @dc.dataclass(frozen=True) class RuleBlockPolicy(BlockPolicy): - """....""" pattern: ParsedPattern diff --git a/src/hydrilla/proxy/policies/web_ui.py b/src/hydrilla/proxy/policies/web_ui.py index 74a0655..1c32ea9 100644 --- a/src/hydrilla/proxy/policies/web_ui.py +++ b/src/hydrilla/proxy/policies/web_ui.py @@ -41,10 +41,10 @@ from . import base @dc.dataclass(frozen=True) class WebUIPolicy(base.Policy): - """....""" - _process_request: t.ClassVar[bool] = True + _process_request = base.MsgProcessOpt.MUST + _process_response = base.MsgProcessOpt.MUST_NOT - priority: t.ClassVar[base.PolicyPriority] = base.PolicyPriority._THREE + priority = base.PolicyPriority._THREE haketilo_state: state.HaketiloState ui_domain: web_ui.UIDomain -- cgit v1.2.3