<commit_before>"""Web Application Firewall extension for the WebCore web framework.

See also:

* https://en.wikipedia.org/wiki/Web_application_firewall
* https://owasp.org/www-community/Web_Application_Firewall
* https://owasp.org/www-project-little-web-application-firewall/
* https://www.owasp.org/index.php?title=Web_Application_Firewall
* https://www.owasp.org/images/0/0a/Appseceu09-Web_Application_Firewalls.pdf
* https://www.cloudflare.com/en-ca/waf/
"""

from html import escape
from re import compile as re
from socket import inet_aton

from typeguard import check_argument_types
from uri import URI
from webob import Request

from web.core.typing import Any, Union, Callable, ClassVar, Generator, Iterable, Optional
from web.core.typing import Dict, Path, Set, Pattern, MutableSet
from web.core.typing import Context, WSGI, WSGIEnvironment, WSGIStartResponse, Request, Response, Tags
from web.core.context import Context
from web.security.waf import WAFHeuristic
from web.security.exc import HTTPClose


log = __import__('logging').getLogger(__name__)  # A standard logger object.


ClientSet = MutableSet[str]


class WebApplicationFirewallExtension:
	"""A basic rules-based Web Application Firewall implementation.<commit_msg>Add API definition for persistent blacklists.<commit_after>"""Web Application Firewall extension for the WebCore web framework.

See also:

* https://en.wikipedia.org/wiki/Web_application_firewall
* https://owasp.org/www-community/Web_Application_Firewall
* https://owasp.org/www-project-little-web-application-firewall/
* https://www.owasp.org/index.php?title=Web_Application_Firewall
* https://www.owasp.org/images/0/0a/Appseceu09-Web_Application_Firewalls.pdf
* https://www.cloudflare.com/en-ca/waf/
"""

from html import escape
from re import compile as re
from socket import inet_aton

from typeguard import check_argument_types
from uri import URI
from webob import Request

from web.core.typing import Any, Union, Callable, ClassVar, Generator, Iterable, Optional
from web.core.typing import Dict, Path, Set, Pattern, MutableSet
from web.core.typing import Context, WSGI, WSGIEnvironment, WSGIStartResponse, Request, Response, Tags
from web.core.context import Context
from web.security.waf import WAFHeuristic
from web.security.exc import HTTPClose


log = __import__('logging').getLogger(__name__)  # A standard logger object.


ClientSet = MutableSet[bytes]

class PersistentClientSet(ClientSet, metaclass=ABCMeta):
	"""A mutable set exposing two methods for persisting and restoring its contents."""
	
	@abstractmethod
	def persist(self, context:Context) -> None:
		...
	
	@abstractmethod
	def restore(self, context:Context) -> None:
		...


class WebApplicationFirewallExtension:
	"""A basic rules-based Web Application Firewall implementation.
{'fraction_non_alphanumeric': 0.09695885509838999, 'fraction_numerical': 0.0028622540250447226, 'mean_word_length': 5.5174825174825175, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 12, 'lorem ipsum': 0, 'www.': 10, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4960817', 'n_tokens_mistral': 858, 'n_tokens_neox': 824, 'n_words': 229}