This document outlines security considerations, best practices, and threat mitigation strategies for the PyBiorythm project.
PyBiorythm is a mathematical calculation library with minimal attack surface, but security best practices are implemented throughout:
Comprehensive input validation prevents malicious or malformed inputs:
class DateValidator:
@staticmethod
def validate_date_components(year: int, month: int, day: int) -> None:
# Range validation prevents integer overflow
if not isinstance(year, int) or not (MIN_YEAR <= year <= MAX_YEAR):
raise DateValidationError(f"Year must be between {MIN_YEAR} and {MAX_YEAR}")
# Month validation prevents array bounds issues
if not isinstance(month, int) or not (1 <= month <= 12):
raise DateValidationError(f"Month must be between 1 and 12")
# Day validation with calendar-aware checking
if not isinstance(day, int) or not (1 <= day <= 31):
raise DateValidationError(f"Day must be between 1 and 31")
@staticmethod
def create_validated_date(year: int, month: int, day: int) -> datetime:
DateValidator.validate_date_components(year, month, day)
try:
date_obj = datetime(year, month, day)
except ValueError as e:
raise DateValidationError(f"Invalid date: {e}")
# Prevent future dates that could cause calculation issues
if date_obj > datetime.now():
raise DateValidationError("Birth date cannot be in the future")
return date_obj
Chart parameters are validated to prevent resource exhaustion:
def _validate_chart_parameters(self, width: int, days: int) -> None:
# Prevent negative or zero values
if not isinstance(width, int) or width < 1:
raise ChartParameterError(f"Width must be positive integer")
if not isinstance(days, int) or days < 1:
raise ChartParameterError(f"Days must be positive integer")
# Prevent excessively large values that could consume memory
if width > 1000:
raise ChartParameterError("Chart width too large")
if days > 10000:
raise ChartParameterError("Too many days requested")
All inputs undergo strict type checking:
def calculate_biorhythm_values(self, birthdate: datetime, target_date: datetime) -> Tuple[float, float, float]:
if not isinstance(birthdate, datetime):
raise TypeError("Birthdate must be datetime object")
if not isinstance(target_date, datetime):
raise TypeError("Target date must be datetime object")
# Safe calculation with validated inputs
days_alive = (target_date - birthdate).days
# ... rest of calculation
Regular security scanning of dependencies:
# .github/workflows/security-scan.yml
- name: Security vulnerability scan
run: |
uv run safety check # Check for known vulnerabilities
uv run bandit -r biorythm/ # Static security analysis
PyBiorythm uses minimal dependencies to reduce attack surface:
Production Dependencies:
numpy>=1.20.0
- Mathematical operations onlyDevelopment Dependencies:
Development dependencies are pinned to specific versions:
[dependency-groups]
dev = [
"pytest>=8.3.5", # Specific versions for reproducibility
"pytest-cov>=5.0.0", # Known-good versions
"safety>=3.6.0", # Security scanning tool
"bandit[toml]>=1.7.10", # Static security analysis
]
Comprehensive SBOM generation for transparency:
- name: Generate SBOM
run: |
uv run cyclonedx-py requirements requirements-freeze.txt \
--output-format json \
--output-file sbom-python.json
SBOM includes:
Automated dependency review in CI/CD:
- name: Dependency Review
uses: actions/dependency-review-action@v3
with:
allow-licenses: MIT, Apache-2.0, BSD-2-Clause, BSD-3-Clause, ISC, GPL-2.0, GPL-3.0, LGPL-2.1, LGPL-3.0, MPL-2.0
GitHub Actions workflows follow security best practices:
name: CI/CD Pipeline
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read # Minimal permissions
security-events: write # For security scanning
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4 # Pinned to specific version
with:
persist-credentials: false # Don't persist GitHub token
Build artifacts are signed and verified:
- name: Build and verify package
run: |
uv run python -m build
uv run twine check dist/* # Verify package integrity
# Additional integrity checks would go here
No secrets are used in the PyBiorythm project:
Safe memory operations throughout the codebase:
def _create_chart_line(self, p_pos: int, e_pos: int, i_pos: int) -> str:
# Safe array operations with bounds checking
chart_line = list(" " * self.width)
# Ensure positions are within bounds
if 0 <= p_pos < self.width:
chart_line[p_pos] = "p"
if 0 <= e_pos < self.width:
chart_line[e_pos] = "e"
if 0 <= i_pos < self.width:
chart_line[i_pos] = "i"
return "".join(chart_line)
Protection against resource exhaustion:
def get_terminal_width(default=80, min_width=40, max_width=200):
try:
width = shutil.get_terminal_size().columns
# Clamp to reasonable bounds
return max(min_width, min(width, max_width))
except Exception:
return default
Safe error handling that doesn’t leak sensitive information:
def main():
try:
# Application logic
pass
except DateValidationError as e:
# User-friendly error without system details
logger.error(f"Date validation error: {str(e)}")
print(f"Error: {str(e)}")
sys.exit(1)
except Exception as e:
# Generic error message, detailed logging
logger.critical(f"Unexpected error: {str(e)}")
print("An unexpected error occurred. Please check your input and try again.")
sys.exit(1)
Automated static security analysis:
- name: Security linting with bandit
run: |
uv run bandit -r biorythm/ -f json -o bandit-report.json
uv run bandit -r biorythm/ --exit-zero # Don't fail build on warnings
Common security issues checked:
Security-focused code quality standards:
# Secure coding practices
def calculate_biorhythm_values(self, birthdate: datetime, target_date: datetime) -> Tuple[float, float, float]:
"""
Calculate biorhythm values with input validation
Security considerations:
- Input validation prevents injection attacks
- Mathematical operations are overflow-safe
- No external dependencies in calculation
"""
# Input validation
if not isinstance(birthdate, datetime):
raise TypeError("Invalid birthdate type")
if not isinstance(target_date, datetime):
raise TypeError("Invalid target_date type")
# Safe mathematical operations
days_alive = (target_date - birthdate).days
# Pure mathematical calculations - no security risk
physical = math.sin((2 * math.pi * days_alive) / PHYSICAL_CYCLE_DAYS)
emotional = math.sin((2 * math.pi * days_alive) / EMOTIONAL_CYCLE_DAYS)
intellectual = math.sin((2 * math.pi * days_alive) / INTELLECTUAL_CYCLE_DAYS)
return physical, emotional, intellectual
Safe logging practices that don’t expose sensitive data:
def setup_logging(level: int = logging.INFO) -> None:
# Safe logging configuration
logging.basicConfig(
level=level,
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
handlers=[logging.StreamHandler(sys.stdout)]
)
# No file logging to prevent information disclosure
# No sensitive data in log messages
def generate_chart(self, birthdate: datetime, plot_date: datetime = None) -> None:
# Safe logging - no sensitive data exposure
self.logger.info(f"Generating chart for {days_alive} days since birth")
# Never log actual birthdate or personal information
Secure package publishing process:
- name: Publish to PyPI
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: $
run: |
uv run twine upload dist/* --verbose
Security measures:
For Docker deployments (if applicable):
# Use official Python image with security updates
FROM python:3.12-slim
# Create non-root user
RUN groupadd -r biorhythm && useradd -r -g biorhythm biorhythm
# Install security updates
RUN apt-get update && apt-get upgrade -y && \
apt-get clean && rm -rf /var/lib/apt/lists/*
# Set working directory
WORKDIR /app
# Copy requirements and install dependencies
COPY pyproject.toml .
RUN pip install --no-cache-dir .
# Switch to non-root user
USER biorhythm
# Run application
CMD ["python", "-m", "biorythm"]
class TestSecurityValidation:
def test_input_sanitization(self):
"""Test that malicious inputs are properly handled"""
calc = BiorhythmCalculator()
# Test SQL injection patterns (not applicable but good practice)
with pytest.raises(DateValidationError):
DateValidator.create_validated_date("'; DROP TABLE users; --", 5, 15)
# Test buffer overflow attempts
with pytest.raises(ChartParameterError):
BiorhythmCalculator(width=999999999)
def test_resource_exhaustion_protection(self):
"""Test protection against resource exhaustion"""
# Large but reasonable inputs should work
calc = BiorhythmCalculator(width=100, days=100)
# Extremely large inputs should be rejected
with pytest.raises(ChartParameterError):
BiorhythmCalculator(width=100000, days=100000)
def test_error_information_disclosure(self):
"""Test that errors don't leak sensitive information"""
with pytest.raises(DateValidationError) as exc_info:
DateValidator.create_validated_date(2030, 5, 15)
error_message = str(exc_info.value)
# Error should be informative but not reveal system details
assert "Birth date cannot be in the future" in error_message
assert "/home/" not in error_message # No file paths
assert "password" not in error_message.lower() # No credentials
Manual security testing checklist:
If security vulnerabilities are discovered:
# Verify package integrity
pip install --only-binary=all biorythm
# Use virtual environments to isolate dependencies
python -m venv biorhythm-env
source biorhythm-env/bin/activate
pip install biorythm
# Keep dependencies updated
pip list --outdated
pip install --upgrade biorythm
# Safe programmatic usage
from biorythm import BiorhythmCalculator
from datetime import datetime
try:
calc = BiorhythmCalculator()
birthdate = datetime(1990, 5, 15) # Use known-good dates
calc.generate_chart(birthdate)
except Exception as e:
# Handle errors gracefully
print(f"Error: {e}")
PyBiorythm respects user privacy:
PyBiorythm follows industry security standards:
# Security monitoring workflow
name: Security Monitoring
on:
schedule:
- cron: '0 0 * * 1' # Weekly security checks
jobs:
security-scan:
runs-on: ubuntu-latest
steps:
- name: Security dependency scan
run: |
uv run safety check --json --output safety-report.json
- name: Vulnerability database update
run: |
uv run pip-audit --format=json --output=audit-report.json
Areas for ongoing security research:
For security-related questions or vulnerability reports:
Security Disclaimer: While PyBiorythm implements security best practices, no software is completely secure. Users should follow general security practices for their computing environment and keep all software updated.