Skip to content

TaipanStack v0.3.4 โ€” Quality, Security Hardening & Code Health

Overview

v0.3.4 is a quality patch release that significantly deepens test coverage, hardens security validators, modularises the codebase, and introduces a new password security module โ€” all while maintaining 100% backwards compatibility.

This release merges 23 Pull Requests covering test improvements, security fixes, refactoring/code-health, and performance optimisations.


1. ๐Ÿ”’ Security Fix โ€” Plaintext Password Handling

File: src/app/secure_system.py | PR #93

UserService.create_user previously stored user passwords as plaintext strings. This has been corrected: passwords are now properly hashed before being passed to the internal user store.

# Before (insecure)
user = User(username=username, password=password)

# After (secure)
user = User(username=username, password=hash_password(password))

[!WARNING] This is a security fix. All deployments on v0.3.3 or earlier are encouraged to upgrade immediately and re-hash any stored passwords.


2. ๐Ÿ” New password Security Module

File: src/taipanstack/security/password.py + tests/test_security_password.py

A dedicated password security module has been introduced, providing:

  • hash_password(password: str) -> str โ€” bcrypt-based secure hashing
  • verify_password(plain: str, hashed: str) -> bool โ€” constant-time comparison
  • generate_secure_token(length: int = 32) -> str โ€” cryptographically secure random token generator
from taipanstack.security.password import hash_password, verify_password

hashed = hash_password("my_secret_password")
assert verify_password("my_secret_password", hashed)  # True
assert not verify_password("wrong_password", hashed)   # False

3. ๐Ÿš€ Async Resilience (@retry & @circuit_breaker)

Files: src/taipanstack/utils/retry.py & src/taipanstack/utils/circuit_breaker.py

Native asynchronous support was added to both resilience primitives. Coroutines are wrapped transparently, allowing the event loop to yield correctly via asyncio.sleep(). Both decorators export precise @overload signatures, matching strict-mode mypy requirements.

from taipanstack.utils.retry import retry
from taipanstack.utils.circuit_breaker import circuit_breaker

@retry(max_attempts=3)
@circuit_breaker(failure_threshold=5)
async def fetch_user_data(user_id: int) -> dict:
    return await async_http_client.get(f"/users/{user_id}")

4. ๐Ÿ›ก๏ธ Pydantic Security Types

File: src/taipanstack/security/types.py

Introduced native Pydantic v2 compatibility for TaipanStack's security validators. You can now declaratively shield your API models against SSRF, Path Traversal, and Command Injection directly inside the type annotations using SafeUrl, SafePath, SafeCommand, and SafeProjectName.

from pydantic import BaseModel
from taipanstack.security.types import SafeUrl, SafeCommand

class WebhookPayload(BaseModel):
    # Validates URL format AND rejects SSRF (loopback/private IPs)
    target_url: SafeUrl

    # Validates against shell metacharacters (; | $ > &)
    script_step: SafeCommand

5. ๐Ÿ•ต๏ธ Structlog Data Masking

File: src/taipanstack/utils/logging.py

Added the mask_sensitive_data_processor to the structlog pipeline. This processor automatically intercepts structured log event dictionaries and redacts sensitive parameters based on case-insensitive key patterns (password, secret, token, authorization, api_key).

from taipanstack.utils.logging import get_logger

log = get_logger()
# The value "super_secret_value" will be logged as "***REDACTED***"
log.info("user_authenticated", username="alice", password="super_secret_value")

3. ๐Ÿงช Test Coverage Improvements

Extensive test coverage has been added across all validators and core modules. Every new test asserts both positive and negative code paths:

Test File New Tests Coverage Target
test_security_validators.py 6 new validate_ip_address, validate_port, validate_url, validate_python_version
test_security_validators_extended.py 4 new validate_ip_address (IPv4 + IPv6 edge cases)
test_result_module.py 3 new @safe / @safe_from base Exception and explicit raise
test_utils_logging.py 4 new log_operation expected/unexpected exception branches
test_utils_filesystem.py 4 new Path traversal without base_dir
test_compat.py 2 new get_optimization_level CVE-2020-10735 integer string limits
test_secure_system.py 3 new UserService โ€” UserAlreadyExistsError path
test_security_password.py 7 new New password module โ€” hashing, verification, token generation
test_security_ssrf.py 2 updated DNS error message platform-independence + hostname truncation

Notable: CVE-2020-10735 Test Coverage (PR #129)

Python 3.11+ enforces a limit on integer-string conversion to prevent DoS via extremely large integers. v0.3.4 ensures get_optimization_level correctly handles the ValueError raised when an environment variable contains a string exceeding 4300 digits:

huge_int_str = "9" * 4500
with patch.dict(os.environ, {"STACK_OPTIMIZATION_LEVEL": huge_int_str}):
    assert get_optimization_level() == 1  # falls back gracefully

URL Port Lazy Evaluation Fix (PR #130 / #126)

urlparse is lazily evaluated โ€” accessing .port triggers full parsing. validate_url now explicitly evaluates the port attribute during the parse step:

parsed = urlparse(url)
_ = parsed.port  # triggers lazy evaluation โ†’ catches out-of-range ports

This ensures that http://example.com:99999999999 raises ValueError("Invalid URL format: Port out of range") as expected.


4. ๐Ÿงน Code Health & Refactoring

Change File(s) PR
Remove unused compat imports from taipanstack.core public API core/__init__.py #99
Remove unused imports from root __init__.py taipanstack/__init__.py #100
Define proper __all__ in utils/__init__.py utils/__init__.py #98
Remove redundant from __future__ import annotations Multiple #112
Preserve valid config package public API config/__init__.py #102

5. โšก Performance

Change File PR Gain
Optimise string concatenation in generate_pre_commit_config using list + join instead of += config/generators.py #130 ~10โ€“15% on large configs

6. ๐Ÿ”ง CI / DevOps

Fix Detail
openSUSE Leap repo Added zypper removerepo repo-openh264 \|\| true before package install to suppress failures on CI runners without the codec repo (PR #116)
Actions Group Bump Bumped actions/checkout, actions/setup-python, and related actions to latest versions (PR #95)

Q&A Summary

Metric v0.3.3 v0.3.4
Test Coverage 100% 100%
Total Tests ~650 ~685
Security Fixes 0 1 (critical)
New Security Modules โ€” password.py & types.py
New Async Support โ€” retry & circuit_breaker
CVE Test Coverage โŒ โœ… CVE-2020-10735
Breaking Changes 0 0

Upgrade

pip install --upgrade taipanstack==0.3.4

No breaking changes โ€” upgrade is safe for all v0.3.x installations.