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:
|
guard_name
|
Name of the guard that triggered.
TYPE:
|
value
|
The offending value (sanitized).
TYPE:
|
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:
|
base_dir
|
The base directory to constrain to. Defaults to cwd.
TYPE:
|
allow_symlinks
|
Whether to allow symlinks (default: False).
TYPE:
|
| 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:
|
allowed_commands
|
Optional whitelist of allowed base commands.
TYPE:
|
| 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:
|
allowed_extensions
|
Extensions to allow (with or without dot).
TYPE:
|
denied_extensions
|
Extensions to deny (with or without dot).
TYPE:
|
| 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:
|
allowed_names
|
Variable names to allow.
TYPE:
|
denied_names
|
Variable names to deny.
TYPE:
|
| 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:
|
allowed_algorithms
|
Optional whitelist of allowed algorithms. Defaults to a secure set (SHA-256, SHA-512, etc.).
TYPE:
|
| 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:
|
allowed_schemes
|
Set of URL schemes considered safe.
Defaults to
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Result[str, SecurityError]
|
|
Result[str, SecurityError]
|
|
| RAISES | DESCRIPTION |
|---|---|
TypeError
|
If url is not a :class: |
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:
|
max_length
|
Maximum length to truncate to.
TYPE:
|
allow_html
|
Whether to keep HTML tags (default: False).
TYPE:
|
allow_unicode
|
Whether to keep non-ASCII characters.
TYPE:
|
strip_whitespace
|
Whether to strip leading/trailing whitespace.
TYPE:
|
| 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:
|
max_length
|
Maximum length for the filename.
TYPE:
|
replacement
|
Character to replace invalid chars with.
TYPE:
|
preserve_extension
|
Keep original extension.
TYPE:
|
| 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:
|
base_dir
|
Optional base directory to constrain to.
TYPE:
|
max_depth
|
Maximum directory depth allowed.
TYPE:
|
resolve
|
Whether to resolve the path (requires it to exist).
TYPE:
|
| 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:
|
max_length
|
Maximum length allowed.
TYPE:
|
allow_multiline
|
Whether to allow newlines.
TYPE:
|
| 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:
|
| 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:
|
max_length
|
Maximum allowed length.
TYPE:
|
allow_hyphen
|
Allow hyphens in name.
TYPE:
|
allow_underscore
|
Allow underscores in name.
TYPE:
|
| 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:
|
| 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:
|
| 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:
|
allowed_schemes
|
Tuple of allowed URL schemes.
TYPE:
|
require_tld
|
Whether to require a TLD in the domain.
TYPE:
|
| 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.
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:
|
func_name
|
Name of the function that timed out.
TYPE:
|
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:
|
param_name
|
Name of the parameter that failed.
TYPE:
|
value
|
The invalid value (sanitized).
TYPE:
|
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:
|
| 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:
|
reraise_as
|
Exception type to re-raise as (None = don't reraise).
TYPE:
|
default
|
Default value to return if exception caught and not reraised.
TYPE:
|
log_errors
|
Whether to log caught exceptions.
TYPE:
|
| 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:
|
use_signal
|
Use signal-based timeout (Unix only, main thread only).
TYPE:
|
| 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:
|
removal_version
|
Version when function will be removed.
TYPE:
|
| 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:
|
| 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:
|
secret_key
|
The secret key for signing the token.
TYPE:
|
algorithm
|
The signing algorithm (default "HS256").
TYPE:
|
| 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:
|
secret_key
|
The secret key for verifying the signature.
TYPE:
|
algorithms
|
List of exactly accepted algorithms.
TYPE:
|
audience
|
The expected audience(s).
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
JWTPayload
|
The decoded payload dictionary. |
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If the "none" algorithm is present in the |
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.
__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:
|
| 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:
|
| 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:
|
| 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:
|
password_hash
|
The stored password hash.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
bool
|
True if the password matches the hash, False otherwise. |