| title | API Security Testing Guide |
|---|---|
| category | developer |
| order | 2 |
| description | Comprehensive API security test suite covering OWASP Top 10 and core services |
| published | true |
Category: guides
Created: 2025-12-15
Updated: 2025-12-15
Status: active
Busibox includes a comprehensive API security test suite that covers all core services (AuthZ, Agent, Ingest, Search). The tests identify common vulnerabilities including those in the OWASP API Security Top 10.
# From busibox repo root
make test-security
# Or via interactive menu
make test
# → Select "Service Tests" (option 5)
# → Select "API Security Tests" (option 7)
# Run against specific environment
cd provision/ansible
make test-security INV=inventory/staging
make test-security INV=inventory/productioncd tests/security
# First time setup
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
# Run tests
SECURITY_TEST_ENV=test python -m pytest -v
# Run specific test categories
python -m pytest -v -m auth # Authentication tests
python -m pytest -v -m injection # Injection tests
python -m pytest -v -m fuzz # Fuzzing tests
python -m pytest -v -m rate_limit # Rate limiting testsTests in test_auth_security.py:
| Test | Description |
|---|---|
test_agent_api_no_auth |
Verify endpoints reject unauthenticated requests |
test_ingest_api_no_auth |
Verify ingest API requires authentication |
test_search_api_no_auth |
Verify search API requires authentication |
test_authz_admin_no_auth |
Verify admin endpoints require authentication |
test_malformed_jwt_agent |
Verify malformed JWTs are rejected |
test_alg_none_attack |
Verify JWT alg:none attack is blocked |
test_expired_token |
Verify expired tokens are rejected |
Tests for IDOR (Insecure Direct Object Reference) vulnerabilities:
| Test | Description |
|---|---|
test_access_other_user_file |
Cannot access another user's files |
test_access_other_user_conversation |
Cannot access another user's conversations |
test_delete_other_user_resource |
Cannot delete another user's resources |
test_uuid_manipulation |
Malicious UUIDs are handled safely |
Tests in test_injection.py:
| Test | Description |
|---|---|
test_search_query_sql_injection |
SQL injection in search queries blocked |
test_file_id_sql_injection |
SQL injection in file IDs blocked |
test_nosql_query_injection |
NoSQL injection blocked |
test_filename_command_injection |
Command injection in filenames blocked |
test_file_path_traversal |
Path traversal attacks blocked |
test_download_path_traversal |
Path traversal in downloads blocked |
test_search_query_reflection |
XSS payloads sanitized |
test_header_injection_in_parameters |
Header injection blocked |
test_ssrf_in_url_parameters |
SSRF attempts blocked |
test_ldap_injection_in_search |
LDAP injection blocked |
Tests in test_fuzzing.py:
| Test | Description |
|---|---|
test_fuzz_search_query |
Malformed search queries handled |
test_fuzz_search_limit |
Invalid pagination parameters handled |
test_hypothesis_search_parameters |
Property-based fuzzing of search |
test_fuzz_file_id_parameter |
Malicious file IDs handled |
test_fuzz_agent_definition |
Malformed agent definitions handled |
test_fuzz_oauth_token_request |
Malformed OAuth requests handled |
test_fuzz_authorization_header |
Malformed auth headers handled |
Tests in test_rate_limiting.py:
| Test | Description |
|---|---|
test_large_query_rejection |
Very large queries rejected |
test_deep_json_nesting_rejection |
Deeply nested JSON rejected |
test_many_parameters_rejection |
Too many parameters rejected |
test_regex_dos_protection |
ReDoS patterns handled safely |
test_upload_size_limit |
Large file uploads handled |
test_upload_content_type_validation |
Dangerous file types blocked |
Tests in test_endpoint_coverage.py verify ALL endpoints are tested:
- AuthZ API: 11 endpoints (OAuth, admin, health)
- Agent API: 26 endpoints (agents, tools, workflows, runs, conversations)
- Ingest API: 16 endpoints (upload, files, search, export)
- Search API: 7 endpoints (search modes, health)
tests/security/
├── conftest.py # Pytest fixtures and configuration
├── pytest.ini # Pytest settings
├── requirements.txt # Python dependencies
├── run_tests.sh # Test runner script
├── README.md # Test suite documentation
├── utils/
│ ├── __init__.py
│ ├── payloads.py # Malicious payload generators
│ ├── fuzzer.py # Fuzzing utilities
│ ├── auth.py # Authentication helpers
│ └── assertions.py # Security assertion helpers
├── test_auth_security.py # Authentication/authorization tests
├── test_injection.py # Injection attack tests
├── test_fuzzing.py # Fuzzing tests
├── test_rate_limiting.py # Rate limiting tests
└── test_endpoint_coverage.py # Comprehensive endpoint tests
| Variable | Description | Default |
|---|---|---|
SECURITY_TEST_ENV |
Target environment (local, test, production) |
test |
TEST_JWT_TOKEN |
Valid JWT for authenticated tests | None |
TEST_USER_EMAIL |
Test user email used for login + token exchange | test@busibox.local |
TEST_USER_ID |
User ID for X-User-Id header | test-security-user |
The test suite automatically configures endpoints based on environment:
Local Development:
agent = "http://localhost:8000"
data = "http://localhost:8002"
search = "http://localhost:8003"
authz = "http://localhost:8010"
files = "http://localhost:9000"Staging Environment (10.96.201.x):
agent = "http://10.96.201.202:8000"
data = "http://10.96.201.206:8002"
search = "http://10.96.201.204:8003"
authz = "http://10.96.201.210:8010"
files = "http://10.96.201.205:9000"Production Environment (10.96.200.x):
agent = "http://10.96.200.202:8000"
data = "http://10.96.200.206:8002"
search = "http://10.96.200.204:8003"
authz = "http://10.96.200.210:8010"
files = "http://10.96.200.205:9000"Create a new test_*.py file in tests/security/:
"""
Description of security tests.
"""
import pytest
from utils.payloads import PayloadGenerator
from utils.assertions import SecurityAssertions
class TestMySecurityTests:
"""Description of test class."""
@pytest.mark.auth # Use appropriate marker
def test_my_security_check(self, http_client, endpoints, auth_headers):
"""Test description."""
url = f"{endpoints.ingest}/my-endpoint"
response = http_client.get(url, headers=auth_headers)
# Assertions
assert response.status_code in [401, 403, 404]
SecurityAssertions.assert_no_sql_errors(response.text, "context")| Fixture | Scope | Description |
|---|---|---|
http_client |
session | Synchronous HTTP client |
async_http_client |
session | Async HTTP client |
endpoints |
session | Service endpoint URLs |
credentials |
session | Test credentials |
auth_headers |
function | Authentication headers |
admin_headers |
function | Admin authentication headers |
| Marker | Description |
|---|---|
@pytest.mark.auth |
Authentication/authorization tests |
@pytest.mark.injection |
Injection attack tests |
@pytest.mark.fuzz |
Fuzzing tests |
@pytest.mark.rate_limit |
Rate limiting tests |
@pytest.mark.idor |
IDOR vulnerability tests |
@pytest.mark.slow |
Slow tests (skipped by default) |
@pytest.mark.destructive |
Tests that modify data |
Use PayloadGenerator for malicious inputs:
from utils.payloads import PayloadGenerator
# SQL injection payloads
PayloadGenerator.SQL_INJECTION_BASIC
PayloadGenerator.SQL_INJECTION_UUID
# XSS payloads
PayloadGenerator.XSS_BASIC
# Command injection
PayloadGenerator.COMMAND_INJECTION
# Path traversal
PayloadGenerator.PATH_TRAVERSAL
# Invalid UUIDs
PayloadGenerator.MALICIOUS_UUIDS
# Auth bypass tokens
PayloadGenerator.AUTH_BYPASS_TOKENSUse SecurityAssertions for security-specific checks:
from utils.assertions import SecurityAssertions
# Check for SQL errors in response
SecurityAssertions.assert_no_sql_errors(response.text, "context")
# Check for sensitive data exposure
SecurityAssertions.assert_no_sensitive_data(response.text, "context")
# Check for proper error response
SecurityAssertions.assert_proper_error_response(
response.text, response.status_code, "context"
)| Risk | Coverage | Tests |
|---|---|---|
| API1: Broken Object Level Authorization | ✅ | IDOR tests |
| API2: Broken Authentication | ✅ | Auth bypass, token tests |
| API3: Broken Object Property Level Authorization | ✅ | Mass assignment tests |
| API4: Unrestricted Resource Consumption | ✅ | Rate limiting, DoS tests |
| API5: Broken Function Level Authorization | ✅ | Admin endpoint tests |
| API6: Unrestricted Access to Sensitive Business Flows | Partial (needs business logic) | |
| API7: Server Side Request Forgery | ✅ | SSRF tests |
| API8: Security Misconfiguration | ✅ | Health endpoint info leak tests |
| API9: Improper Inventory Management | ✅ | Endpoint coverage tests |
| API10: Unsafe Consumption of APIs | Partial (internal APIs) |
security-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: |
cd tests/security
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
- name: Run security tests
env:
SECURITY_TEST_ENV: test
run: |
cd tests/security
source venv/bin/activate
python -m pytest -v --tb=shortAdd to your deployment pipeline:
# Run before deploying to production
make test-security INV=inventory/staging
# Fail deployment if security tests fail
if [ $? -ne 0 ]; then
echo "Security tests failed - aborting deployment"
exit 1
fiCause: Target services not running or wrong environment.
Solution:
# Check service health
curl http://10.96.201.210:8010/health/live # AuthZ
curl http://10.96.201.206:8002/health # Data API
curl http://10.96.201.204:8003/health # Search
curl http://10.96.201.202:8000/health # Agent
# Deploy services if needed
cd provision/ansible
make all INV=inventory/stagingCause: Missing or invalid test credentials.
Solution:
# Bootstrap test credentials
cd provision/ansible
make bootstrap-test-creds INV=inventory/staging
# Export credentials
export TEST_JWT_TOKEN="..."
export TEST_USER_EMAIL="test@busibox.local"Cause: Slow tests are skipped by default.
Solution:
# Run with slow tests
python -m pytest -v --runslow- OAuth2 Token Exchange - Authentication architecture
- Bootstrap Test Credentials - Setting up test auth
- Agent Server Testing - Agent API testing
- Architecture Overview - System overview
If you discover a security vulnerability, please report it responsibly:
- Do not open a public issue
- Contact the security team directly
- Provide detailed reproduction steps
- Allow time for a fix before disclosure