from app import create_app def test_dynamic_responses_have_security_headers(client): response = client.get("/") assert response.headers["Cache-Control"] == "no-store" assert response.headers["X-Content-Type-Options"] == "nosniff" assert response.headers["X-Frame-Options"] == "DENY" assert response.headers["Referrer-Policy"] == "strict-origin-when-cross-origin" policy = response.headers["Content-Security-Policy"] assert "default-src 'self'" in policy assert "frame-ancestors 'none'" in policy assert "'unsafe-inline'" not in policy def test_static_assets_have_bounded_public_cache(client): response = client.get("/static/css/style.css") assert response.status_code == 200 assert response.headers["Cache-Control"] == "public, max-age=3600" def test_production_hsts_is_https_only(): app = create_app( "production", { "SECRET_KEY": "production-test-only", "SQLALCHEMY_DATABASE_URI": "sqlite:///:memory:", }, ) client = app.test_client() secure = client.get("/", base_url="https://steady.example") insecure = client.get("/", base_url="http://steady.example") assert "Strict-Transport-Security" in secure.headers assert "Strict-Transport-Security" not in insecure.headers def test_trusted_hosts_reject_unknown_host(): app = create_app( "testing", {"TRUSTED_HOSTS": ["steady.example"]}, ) client = app.test_client() assert client.get("/", base_url="http://steady.example").status_code == 200 assert client.get("/", base_url="http://attacker.example").status_code == 400 def test_friendly_not_found_and_upload_limit(client, app): missing = client.get("/missing-page") assert missing.status_code == 404 assert b"That page is not here" in missing.data original_limit = app.config["MAX_CONTENT_LENGTH"] app.config["MAX_CONTENT_LENGTH"] = 32 try: too_large = client.post( "/auth/register", data={"username": "x" * 100}, ) finally: app.config["MAX_CONTENT_LENGTH"] = original_limit assert too_large.status_code == 413 assert b"That file is too large" in too_large.data