{"record":{"id":"463c490cc880bc17","repo":"microsoft/semantic-kernel","slug":"missing-state-parameter","errorCode":null,"errorMessage":"Missing state parameter","messagePattern":"Missing state parameter","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"warning","filePath":"python/samples/demos/mcp_with_oauth/server/mcp_simple_auth/auth_server.py","lineNumber":88,"sourceCode":"        required_scopes=[auth_settings.mcp_scope],\n        resource_server_url=None,\n    )\n\n    # Create OAuth routes\n    routes = create_auth_routes(\n        provider=oauth_provider,\n        issuer_url=mcp_auth_settings.issuer_url,\n        service_documentation_url=mcp_auth_settings.service_documentation_url,\n        client_registration_options=mcp_auth_settings.client_registration_options,\n        revocation_options=mcp_auth_settings.revocation_options,\n    )\n\n    # Add login page route (GET)\n    async def login_page_handler(request: Request) -> Response:\n        \"\"\"Show login form.\"\"\"\n        state = request.query_params.get(\"state\")\n        if not state:\n            raise HTTPException(400, \"Missing state parameter\")\n        return await oauth_provider.get_login_page(state)\n\n    routes.append(Route(\"/login\", endpoint=login_page_handler, methods=[\"GET\"]))\n\n    # Add login callback route (POST)\n    async def login_callback_handler(request: Request) -> Response:\n        \"\"\"Handle simple authentication callback.\"\"\"\n        return await oauth_provider.handle_login_callback(request)\n\n    routes.append(Route(\"/login/callback\", endpoint=login_callback_handler, methods=[\"POST\"]))\n\n    # Add token introspection endpoint (RFC 7662) for Resource Servers\n    async def introspect_handler(request: Request) -> Response:\n        \"\"\"\n        Token introspection endpoint for Resource Servers.\n\n        Resource Servers call this endpoint to validate tokens without\n        needing direct access to token storage.","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/samples/demos/mcp_with_oauth/server/mcp_simple_auth/auth_server.py#L70-L106","documentation":"Raised as HTTPException(400) by the login_page_handler in mcp_simple_auth's auth_server.py when the /login GET request lacks a 'state' query parameter. The state parameter ties the login page to an in-flight authorization request; without it the server cannot render a valid login form and rejects the request.","triggerScenarios":"A GET /login request without ?state=...; the client/initiator omitted the state parameter when constructing the login URL; a user navigated directly to /login manually.","commonSituations":"Browser bookmarks hitting /login directly; a misconfigured client building the auth URL; the state was dropped by a redirect/proxy.","solutions":["Ensure the authorization flow always appends a valid state to the /login URL.","Start the OAuth flow from the proper authorize endpoint so the server generates and forwards state.","Do not deep-link /login without going through the authorize step.","Check reverse proxies / load balancers are not stripping query parameters."],"exampleFix":"// before\n# user opens http://host/login directly\n\n// after\n# start at the authorize endpoint; server redirects to /login?state=<generated>","handlingStrategy":"validation","validationCode":"state = request.query_params.get('state')\nif not state:\n    return PlainTextResponse('Missing state. Start the flow at /authorize.', status_code=400)\nawait oauth_provider.get_login_page(state)","typeGuard":"def has_state_param(request) -> bool:\n    return bool(request.query_params.get('state'))","tryCatchPattern":null,"preventionTips":["Always start OAuth at the authorize endpoint so state is generated.","Never deep-link /login without state.","Ensure proxies preserve query parameters."],"tags":["oauth","authentication","mcp","http","input-validation"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}