Security best practices for contributing to Monitoring Hub.
Always validate external input:
# Good: Strict schema validation
from core.engine.schema import ManifestSchema
schema = ManifestSchema()
validated_data = schema.load(user_input)
# Bad: Trusting user input
data = yaml.safe_load(untrusted_file) # No validationManifest validation prevents:
- Injection attacks through malformed YAML
- Unexpected data types causing runtime errors
- Missing required fields
Always use timeouts:
# Good: Timeout prevents hanging
response = requests.get(url, timeout=30)
# Bad: No timeout
response = requests.get(url) # Can hang indefinitelyImplement retry logic with exponential backoff:
from tenacity import retry, stop_after_attempt, wait_exponential
@retry(
stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1, min=2, max=10)
)
def download_file(url):
response = requests.get(url, timeout=30)
response.raise_for_status()
return response.contentEnable Jinja2 autoescape:
# Good: Autoescape prevents XSS
from jinja2 import Environment, FileSystemLoader, select_autoescape
env = Environment(
loader=FileSystemLoader(template_dir),
autoescape=select_autoescape(['html', 'xml', 'j2'])
)
# Bad: No autoescape
env = Environment(loader=FileSystemLoader(template_dir))Always chain exceptions for better debugging:
# Good: Exception chaining preserves context
try:
dangerous_operation()
except SpecificError as err:
logger.error(f"Operation failed: {err}")
raise click.Abort() from err
# Bad: Losing exception context
except:
raise click.Abort()Avoid bare except clauses:
# Good: Specific exception handling
try:
risky_operation()
except (ValueError, KeyError) as err:
handle_error(err)
# Bad: Catches everything including KeyboardInterrupt
try:
risky_operation()
except:
pass- Pin versions: Use exact versions in
requirements.txt - Regular updates: Review Dependabot PRs weekly
- Vulnerability scanning: Check
pip-auditreports - Minimal dependencies: Only add necessary packages
- Check package reputation (GitHub stars, downloads, maintainers)
- Review security advisories on PyPI Advisory Database
- Verify package signatures when available
- Check for known vulnerabilities with
pip-audit
# Use minimal base images
FROM registry.access.redhat.com/ubi9/ubi-minimal
# Run as non-root user
RUN useradd -r -u 1000 exporter
USER exporter
# Use read-only root filesystem
VOLUME ["/var/lib/exporter"]Before pushing images:
# Scan with Trivy
trivy image monitoring-hub/exporter:latest
# Check for high/critical vulnerabilities
trivy image --severity HIGH,CRITICAL monitoring-hub/exporter:latestNever commit secrets:
- API tokens
- Private keys
- Passwords
- Connection strings
Use environment variables:
# Good: From environment
token = os.environ.get('GITHUB_TOKEN')
# Bad: Hardcoded
token = "ghp_xxxxxxxxxxxx"Add sensitive files to .gitignore:
secrets/
.env
*.key
*.pem
credentials.json
The security.yml workflow runs on every pull request and push to main:
Bandit (Python Security Scanner)
- Scans Python code for common security issues
- Checks for SQL injection, hardcoded passwords, insecure functions
- Reports findings as GitHub annotations
pip-audit (Dependency Vulnerability Scanner)
- Scans Python dependencies for known CVEs
- Checks against the OSV vulnerability database
- Fails CI on high/critical vulnerabilities
Trivy (Container Security Scanner)
- Scans container images for vulnerabilities
- Uploads SARIF reports to GitHub Security tab
- Requires
security-events: writepermission - Integrates with GitHub Advanced Security
View security findings:
- Go to the Security tab in GitHub
- Click Code scanning alerts
- Review Trivy vulnerability reports
Install pre-commit hooks:
make installThis runs:
bandit: Security vulnerability scannerruff: Linting with security rulesmypy: Type checking
# Run security scanner
make security
# Check for vulnerable dependencies
pip-audit -r requirements/base.txt
# Scan code for secrets
gitleaks detect --no-git
# Scan container image with Trivy
trivy image --severity HIGH,CRITICAL monitoring-hub/exporter:latestDo not open public issues for security vulnerabilities.
Follow our Security Policy for responsible disclosure.
Before submitting a PR:
- All network calls have timeouts
- Input validation on external data
- No hardcoded secrets or credentials
- Jinja2 templates use autoescape
- Exceptions are properly chained
- No bare
except:clauses - Dependencies are pinned and reviewed
- Security tests pass (
make security) - No new Bandit warnings introduced
For security questions or concerns:
- Open a GitHub Discussion
- Contact maintainers privately for sensitive issues
- See SECURITY.md for vulnerability reporting