Skip to content

Security — Guards, Sanitizers & Validators

TaipanStack's security layer provides input validation, sanitization, and security guards to prevent common attack vectors.


Guards

Runtime guards for protection against errors and AI hallucinations.

These guards provide runtime protection against common security issues and programming errors that can occur from incorrect AI-generated code. All guards raise SecurityError on violation.

SecurityError

SecurityError(
    message: str,
    guard_name: str = "unknown",
    value: str | None = None,
)

Bases: Exception

Raised when a security guard detects a violation.

ATTRIBUTE DESCRIPTION
guard_name

Name of the guard that was triggered.

message

Description of the violation.

value

The offending value (if safe to log).

Initialize SecurityError.

PARAMETER DESCRIPTION
message

Description of the violation.

TYPE: str

guard_name

Name of the guard that triggered.

TYPE: str DEFAULT: 'unknown'

value

The offending value (sanitized).

TYPE: str | None DEFAULT: None

guard_path_traversal

guard_path_traversal(
    path: Path | str,
    base_dir: Path | str | None = None,
    *,
    allow_symlinks: bool = False,
) -> Path

Prevent path traversal attacks.

Ensures that the given path does not escape the base directory using techniques like '..' or symlinks.

PARAMETER DESCRIPTION
path

The path to validate.

TYPE: Path | str

base_dir

The base directory to constrain to. Defaults to cwd.

TYPE: Path | str | None DEFAULT: None

allow_symlinks

Whether to allow symlinks (default: False).

TYPE: bool DEFAULT: False

RETURNS DESCRIPTION
Path

The resolved, validated path.

RAISES DESCRIPTION
SecurityError

If path traversal is detected.

Example

guard_path_traversal("../etc/passwd", Path("/app")) SecurityError: [path_traversal] Path escapes base directory

guard_command_injection

guard_command_injection(
    command: Sequence[str],
    *,
    allowed_commands: Sequence[str] | None = None,
) -> list[str]

Prevent command injection attacks.

Validates that command arguments don't contain shell metacharacters that could lead to command injection.

PARAMETER DESCRIPTION
command

The command and arguments as a sequence.

TYPE: Sequence[str]

allowed_commands

Optional whitelist of allowed base commands.

TYPE: Sequence[str] | None DEFAULT: None

RETURNS DESCRIPTION
list[str]

The validated command as a list.

RAISES DESCRIPTION
SecurityError

If command injection is detected.

Example

guard_command_injection(["echo", "hello; rm -rf /"]) SecurityError: [command_injection] Dangerous characters detected

guard_file_extension

guard_file_extension(
    filename: str | Path,
    *,
    allowed_extensions: Sequence[str] | None = None,
    denied_extensions: Sequence[str] | None = None,
) -> Path

Validate file extension against allow/deny lists.

PARAMETER DESCRIPTION
filename

The filename to check.

TYPE: str | Path

allowed_extensions

Extensions to allow (with or without dot).

TYPE: Sequence[str] | None DEFAULT: None

denied_extensions

Extensions to deny (with or without dot).

TYPE: Sequence[str] | None DEFAULT: None

RETURNS DESCRIPTION
Path

The filename as a Path.

RAISES DESCRIPTION
SecurityError

If extension is not allowed or is denied.

guard_env_variable

guard_env_variable(
    name: str,
    *,
    allowed_names: Sequence[str] | None = None,
    denied_names: Sequence[str] | None = None,
) -> str

Guard against accessing sensitive environment variables.

PARAMETER DESCRIPTION
name

The environment variable name.

TYPE: str

allowed_names

Variable names to allow.

TYPE: Sequence[str] | None DEFAULT: None

denied_names

Variable names to deny.

TYPE: Sequence[str] | None DEFAULT: None

RETURNS DESCRIPTION
str

The environment variable value if safe.

RAISES DESCRIPTION
SecurityError

If variable access is not allowed.

guard_hash_algorithm

guard_hash_algorithm(
    algorithm: str,
    *,
    allowed_algorithms: Sequence[str] | None = None,
) -> str

Validate hash algorithm against a whitelist of secure ones.

PARAMETER DESCRIPTION
algorithm

The name of the hash algorithm to validate.

TYPE: str

allowed_algorithms

Optional whitelist of allowed algorithms. Defaults to a secure set (SHA-256, SHA-512, etc.).

TYPE: Sequence[str] | None DEFAULT: None

RETURNS DESCRIPTION
str

The normalized (lowercase) algorithm name.

RAISES DESCRIPTION
SecurityError

If the algorithm is potentially weak or not allowed.

guard_ssrf

guard_ssrf(
    url: str,
    *,
    allowed_schemes: frozenset[str] = _ALLOWED_SSRF_SCHEMES,
) -> Result[str, SecurityError]

Validate a URL against Server-Side Request Forgery (SSRF) attacks.

Parse the URL, resolve its hostname via DNS, and reject it when the resulting IP address falls inside a private, loopback, link-local, or otherwise reserved network range.

PARAMETER DESCRIPTION
url

The URL string to validate.

TYPE: str

allowed_schemes

Set of URL schemes considered safe. Defaults to {"http", "https"}.

TYPE: frozenset[str] DEFAULT: _ALLOWED_SSRF_SCHEMES

RETURNS DESCRIPTION
Result[str, SecurityError]

Ok(url) when the URL is safe to fetch.

Result[str, SecurityError]

Err(SecurityError) when an SSRF risk is detected.

RAISES DESCRIPTION
TypeError

If url is not a :class:str.

Example

guard_ssrf("https://example.com") Ok('https://example.com') guard_ssrf("http://169.254.169.254/metadata") Err(SecurityError('[ssrf] ...))


Sanitizers

Input sanitizers for cleaning untrusted data.

Provides functions to sanitize strings, filenames, and paths to remove potentially dangerous characters.

sanitize_string

sanitize_string(
    value: str,
    *,
    max_length: int | None = None,
    allow_html: bool = False,
    allow_unicode: bool = True,
    strip_whitespace: bool = True,
) -> str

Sanitize a string by removing dangerous characters.

PARAMETER DESCRIPTION
value

The string to sanitize.

TYPE: str

max_length

Maximum length to truncate to.

TYPE: int | None DEFAULT: None

allow_html

Whether to keep HTML tags (default: False).

TYPE: bool DEFAULT: False

allow_unicode

Whether to keep non-ASCII characters.

TYPE: bool DEFAULT: True

strip_whitespace

Whether to strip leading/trailing whitespace.

TYPE: bool DEFAULT: True

RETURNS DESCRIPTION
str

The sanitized string.

Example
sanitize_string("<script>alert('xss')</script>Hello")
# Returns: "scriptalert('xss')/scriptHello"

sanitize_filename

sanitize_filename(
    filename: str,
    *,
    max_length: int = 255,
    replacement: str = "_",
    preserve_extension: bool = True,
) -> str

Sanitize a filename to be safe for filesystem use.

Removes or replaces characters that are: - Not allowed in filenames on various OSes - Potentially dangerous (path separators, etc.)

PARAMETER DESCRIPTION
filename

The filename to sanitize.

TYPE: str

max_length

Maximum length for the filename.

TYPE: int DEFAULT: 255

replacement

Character to replace invalid chars with.

TYPE: str DEFAULT: '_'

preserve_extension

Keep original extension.

TYPE: bool DEFAULT: True

RETURNS DESCRIPTION
str

The sanitized filename.

Example
sanitize_filename("my/../file<>:name.txt")
# Returns: 'my_file_name.txt'

sanitize_path

sanitize_path(
    path: str | Path,
    *,
    base_dir: Path | None = None,
    max_depth: int | None = 10,
    resolve: bool = False,
) -> Path

Sanitize a path to prevent traversal and normalize it.

PARAMETER DESCRIPTION
path

The path to sanitize.

TYPE: str | Path

base_dir

Optional base directory to constrain to.

TYPE: Path | None DEFAULT: None

max_depth

Maximum directory depth allowed.

TYPE: int | None DEFAULT: 10

resolve

Whether to resolve the path (requires it to exist).

TYPE: bool DEFAULT: False

RETURNS DESCRIPTION
Path

The sanitized Path object.

RAISES DESCRIPTION
ValueError

If path is invalid or too deep.

sanitize_env_value

sanitize_env_value(
    value: str,
    *,
    max_length: int = 4096,
    allow_multiline: bool = False,
) -> str

Sanitize a value for use as an environment variable.

PARAMETER DESCRIPTION
value

The value to sanitize.

TYPE: str

max_length

Maximum length allowed.

TYPE: int DEFAULT: 4096

allow_multiline

Whether to allow newlines.

TYPE: bool DEFAULT: False

RETURNS DESCRIPTION
str

The sanitized value.

RAISES DESCRIPTION
TypeError

If value is not a string.

sanitize_sql_identifier

sanitize_sql_identifier(identifier: str) -> str

Sanitize a SQL identifier (table/column name).

Note: This is NOT for SQL values - use parameterized queries for those!

PARAMETER DESCRIPTION
identifier

The identifier to sanitize.

TYPE: str

RETURNS DESCRIPTION
str

The sanitized identifier.

RAISES DESCRIPTION
TypeError

If identifier is not a string.

ValueError

If identifier is empty or too long.


Validators

Input validators for type-safe validation.

Provides validation functions for common input types like email, project names, URLs, etc. All validators raise ValueError on invalid input.

validate_project_name

validate_project_name(
    name: str,
    *,
    max_length: int = 100,
    allow_hyphen: bool = True,
    allow_underscore: bool = True,
) -> str

Validate a project name.

PARAMETER DESCRIPTION
name

The project name to validate.

TYPE: str

max_length

Maximum allowed length.

TYPE: int DEFAULT: 100

allow_hyphen

Allow hyphens in name.

TYPE: bool DEFAULT: True

allow_underscore

Allow underscores in name.

TYPE: bool DEFAULT: True

RETURNS DESCRIPTION
str

The validated project name.

RAISES DESCRIPTION
ValueError

If the name is invalid.

Example

validate_project_name("my_project") 'my_project' validate_project_name("123project") ValueError: Project name must start with a letter

validate_python_version

validate_python_version(version: str) -> str

Validate Python version string.

PARAMETER DESCRIPTION
version

Version string like "3.12" or "3.10".

TYPE: str

RETURNS DESCRIPTION
str

The validated version string.

RAISES DESCRIPTION
ValueError

If version format is invalid or unsupported.

validate_email

validate_email(email: str) -> str

Validate email address format.

Uses a reasonable regex pattern that covers most valid emails without being overly strict.

PARAMETER DESCRIPTION
email

The email address to validate.

TYPE: str

RETURNS DESCRIPTION
str

The validated email address.

RAISES DESCRIPTION
ValueError

If email format is invalid.

validate_url

validate_url(
    url: str,
    *,
    allowed_schemes: tuple[str, ...] = ("http", "https"),
    require_tld: bool = True,
) -> str

Validate URL format and scheme.

PARAMETER DESCRIPTION
url

The URL to validate.

TYPE: str

allowed_schemes

Tuple of allowed URL schemes.

TYPE: tuple[str, ...] DEFAULT: ('http', 'https')

require_tld

Whether to require a TLD in the domain.

TYPE: bool DEFAULT: True

RETURNS DESCRIPTION
str

The validated URL.

RAISES DESCRIPTION
ValueError

If URL format is invalid.


Types

Pydantic-compatible security types.

Provide Annotated type aliases that integrate TaipanStack's runtime security guards with Pydantic v2 validation, enabling declarative, type-safe input validation inside BaseModel definitions.

SafeUrl module-attribute

SafeUrl = Annotated[
    str,
    AfterValidator(_validate_safe_url_format),
    AfterValidator(_validate_safe_url),
]

A URL validated for correct format and safe from SSRF attacks.

SafePath module-attribute

SafePath = Annotated[
    str, AfterValidator(_validate_safe_path)
]

A filesystem path validated against path-traversal attacks.

SafeCommand module-attribute

SafeCommand = Annotated[
    str, AfterValidator(_validate_safe_command)
]

A command string validated against shell-injection attacks.

SafeProjectName module-attribute

SafeProjectName = Annotated[
    str, AfterValidator(_validate_safe_project_name)
]

A project name validated for safe naming conventions.

SafeHtml module-attribute

SafeHtml = Annotated[
    str, AfterValidator(_sanitize_safe_html)
]

A string sanitized for safe inclusion in HTML templates.

SafeSqlIdentifier module-attribute

SafeSqlIdentifier = Annotated[
    str, AfterValidator(_validate_safe_sql_identifier)
]

A string validated as a safe dynamic SQL identifier (e.g., table or column name).


Decorators

Security decorators for robust Python applications.

Provides decorators for input validation, exception handling, timeout control, and other security patterns. Compatible with any Python framework (Flask, FastAPI, Django, etc.).

ValidatorFunc

Bases: Protocol[V_contra, V_co]

Protocol defining the signature of input validators.

__call__

__call__(value: V_contra) -> V_co

Validate an input value.

OperationTimeoutError

OperationTimeoutError(
    seconds: float, func_name: str = "function"
)

Bases: Exception

Raised when a function exceeds its timeout limit.

Initialize OperationTimeoutError.

PARAMETER DESCRIPTION
seconds

The timeout that was exceeded.

TYPE: float

func_name

Name of the function that timed out.

TYPE: str DEFAULT: 'function'

ValidationError

ValidationError(
    message: str,
    param_name: str | None = None,
    value: object = None,
)

Bases: Exception

Raised when input validation fails.

Initialize ValidationError.

PARAMETER DESCRIPTION
message

Description of the validation failure.

TYPE: str

param_name

Name of the parameter that failed.

TYPE: str | None DEFAULT: None

value

The invalid value (sanitized).

TYPE: object DEFAULT: None

validate_inputs

validate_inputs(
    **validators: ValidatorFunc[Any, Any],
) -> Callable[[Callable[P, R]], Callable[P, R]]

Decorator to validate function inputs.

Validates function arguments using provided validator functions. Validators should raise ValueError or ValidationError on invalid input.

PARAMETER DESCRIPTION
**validators

Mapping of parameter names to validator functions.

TYPE: ValidatorFunc[Any, Any] DEFAULT: {}

RETURNS DESCRIPTION
Callable[[Callable[P, R]], Callable[P, R]]

Decorated function with input validation.

Example

from taipanstack.security.validators import validate_email, validate_port @validate_inputs(email=validate_email, port=validate_port) ... def connect(email: str, port: int) -> None: ... pass connect(email="invalid", port=8080) ValidationError: Invalid email format: invalid

guard_exceptions

guard_exceptions(
    *,
    catch: tuple[type[Exception], ...] = (Exception,),
    reraise_as: type[Exception] | None = None,
    default: T | None = None,
    log_errors: bool = True,
) -> Callable[
    [Callable[P, R]], Callable[P, R | T | None]
]

Decorator to safely handle exceptions.

Catches exceptions and optionally re-raises as a different type or returns a default value.

PARAMETER DESCRIPTION
catch

Exception types to catch.

TYPE: tuple[type[Exception], ...] DEFAULT: (Exception,)

reraise_as

Exception type to re-raise as (None = don't reraise).

TYPE: type[Exception] | None DEFAULT: None

default

Default value to return if exception caught and not reraised.

TYPE: T | None DEFAULT: None

log_errors

Whether to log caught exceptions.

TYPE: bool DEFAULT: True

RETURNS DESCRIPTION
Callable[[Callable[P, R]], Callable[P, R | T | None]]

Decorated function with exception handling.

Example

@guard_exceptions(catch=(IOError,), reraise_as=SecurityError) ... def read_file(path: str) -> str: ... return open(path).read() read_file("/nonexistent") SecurityError: [guard_exceptions] ...

timeout

timeout(
    seconds: float, *, use_signal: bool = True
) -> Callable[[Callable[P, R]], Callable[P, R]]

Decorator to limit function execution time.

Uses signal-based timeout on Unix or thread-based on Windows. Signal-based is more reliable but only works in main thread.

PARAMETER DESCRIPTION
seconds

Maximum execution time in seconds.

TYPE: float

use_signal

Use signal-based timeout (Unix only, main thread only).

TYPE: bool DEFAULT: True

RETURNS DESCRIPTION
Callable[[Callable[P, R]], Callable[P, R]]

Decorated function with timeout.

Example

@timeout(5.0) ... def slow_operation() -> str: ... import time ... time.sleep(10) ... return "done" slow_operation() TimeoutError: slow_operation timed out after 5.0 seconds

deprecated

deprecated(
    message: str = "", *, removal_version: str | None = None
) -> Callable[[Callable[P, R]], Callable[P, R]]

Mark a function as deprecated.

Emits a warning when the decorated function is called.

PARAMETER DESCRIPTION
message

Additional deprecation message.

TYPE: str DEFAULT: ''

removal_version

Version when function will be removed.

TYPE: str | None DEFAULT: None

RETURNS DESCRIPTION
Callable[[Callable[P, R]], Callable[P, R]]

Decorated function that warns on use.

Example

@deprecated("Use new_function instead", removal_version="2.0") ... def old_function() -> None: ... pass

require_type

require_type(
    **type_hints: type,
) -> Callable[[Callable[P, R]], Callable[P, R]]

Decorator to enforce runtime type checking.

Validates that arguments match specified types at runtime.

PARAMETER DESCRIPTION
**type_hints

Mapping of parameter names to expected types.

TYPE: type DEFAULT: {}

RETURNS DESCRIPTION
Callable[[Callable[P, R]], Callable[P, R]]

Decorated function with type checking.

Example

@require_type(name=str, count=int) ... def greet(name: str, count: int) -> None: ... print(f"Hello {name}" * count) greet(name=123, count=2) TypeError: Parameter 'name' expected str, got int


JWT

Secure JWT Utility module.

Provides explicitly secure wrappers around PyJWT encoding and decoding, enforcing strict validation of algorithms, expiration, and audience claims. All operations return Result types.

encode_jwt

encode_jwt(
    payload: JWTPayload,
    secret_key: str,
    algorithm: str = "HS256",
) -> str

Encode a payload into a JWT securely.

Explicitly rejects the "none" algorithm to prevent bypass vulnerabilities.

PARAMETER DESCRIPTION
payload

Dictionary containing the JWT claims.

TYPE: JWTPayload

secret_key

The secret key for signing the token.

TYPE: str

algorithm

The signing algorithm (default "HS256").

TYPE: str DEFAULT: 'HS256'

RETURNS DESCRIPTION
str

The encoded JWT string.

RAISES DESCRIPTION
ValueError

If the "none" algorithm is specified.

PyJWTError

If encoding fails.

decode_jwt

decode_jwt(
    token: str,
    secret_key: str,
    algorithms: list[str],
    audience: str | Iterable[str],
) -> JWTPayload

Decode a JWT securely with strict claim validation.

Enforces that 'exp' (expiration) and 'aud' (audience) claims are present and validated. Explicitly rejects the "none" algorithm.

PARAMETER DESCRIPTION
token

The encoded JWT string.

TYPE: str

secret_key

The secret key for verifying the signature.

TYPE: str

algorithms

List of exactly accepted algorithms.

TYPE: list[str]

audience

The expected audience(s).

TYPE: str | Iterable[str]

RETURNS DESCRIPTION
JWTPayload

The decoded payload dictionary.

RAISES DESCRIPTION
ValueError

If the "none" algorithm is present in the algorithms list.

PyJWTError

If the token is invalid, expired, or has incorrect claims.


Models

Secure base models.

SecureBaseModel

Bases: BaseModel

Secure base model that redacts sensitive fields when dumped.

__str__

__str__() -> str

Return a string representation with sensitive fields redacted.

__repr_args__

__repr_args__() -> Iterator[tuple[str | None, object]]

Provide arguments for string representation, redacting sensitive fields.

model_dump

model_dump(**kwargs: Any) -> dict[str, Any]

Dump the model to a dictionary, redacting sensitive fields.

PARAMETER DESCRIPTION
**kwargs

Arguments to pass to Pydantic's model_dump.

TYPE: Any DEFAULT: {}

RETURNS DESCRIPTION
dict[str, Any]

The redacting dictionary representation of the model.

model_dump_json

model_dump_json(**kwargs: Any) -> str

Dump the model to a JSON string, redacting sensitive fields.

PARAMETER DESCRIPTION
**kwargs

Arguments to pass to Pydantic's model_dump.

TYPE: Any DEFAULT: {}

RETURNS DESCRIPTION
str

The redacted JSON string representation of the model.


Password

Password hashing and verification utilities.

This module provides functions for secure password management using Argon2, with fallback verification support for PBKDF2-HMAC-SHA256.

hash_password

hash_password(password: str | SecretStr) -> str

Hash a password using Argon2id.

PARAMETER DESCRIPTION
password

The plaintext password to hash.

TYPE: str | SecretStr

RETURNS DESCRIPTION
str

The hashed password in Argon2 format.

verify_password

verify_password(
    password: str | SecretStr, password_hash: str
) -> bool

Verify a password against an Argon2 or legacy PBKDF2-HMAC-SHA256 hash.

PARAMETER DESCRIPTION
password

The plaintext password to verify.

TYPE: str | SecretStr

password_hash

The stored password hash.

TYPE: str

RETURNS DESCRIPTION
bool

True if the password matches the hash, False otherwise.