Skip to content

sts: accept WebIdentityToken from POST body, not only the query string #70

@alukach

Description

@alukach

Summary

multistore-sts parses the AssumeRoleWithWebIdentity WebIdentityToken exclusively from the query string. The StsRouterExt handler calls try_handle_sts(req.query, …) (crates/sts/src/route_handler.rs), and try_parse_sts_request is documented as "Extracts AssumeRoleWithWebIdentity parameters from query strings" (crates/sts/src/request.rs). There is no path to supply the token in the request body.

This mirrors the AWS STS Query API convention, but it means the bearer-grade OIDC token always travels in the URL.

Why it matters

URLs leak into far more places than headers or bodies: CDN/edge access logs, reverse-proxy logs, browser history, and the Referer header. A WebIdentityToken captured from any of these within its validity window can be replayed to mint the user's temporary credentials.

A downstream consumer (the Source Cooperative data proxy, which mounts with_sts("/.sts", …)) carefully avoids logging query strings on the STS route, but it cannot prevent intermediaries from capturing the full URL, because the crate offers no body-based alternative.

Request

Allow the WebIdentityToken (and the other AssumeRoleWithWebIdentity params) to be read from an application/x-www-form-urlencoded POST body, matching how the real AWS STS endpoint accepts form-POST requests. Query-string parsing can remain for backwards compatibility, with the body taking precedence when present.

Concretely, try_handle_sts / try_parse_sts_request would need to also accept the request body, and RouteHandler for the STS route would parse POST bodies in addition to the query.

References

  • crates/sts/src/route_handler.rstry_handle_sts(req.query, …)
  • crates/sts/src/request.rstry_parse_sts_request(query: Option<&str>)

Filed from a security review of a downstream integration (Source Cooperative data proxy). Happy to help with a PR if the approach sounds right.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions