StackStorm / StackStorm/st2

CORS middleware reflects Origin with Allow-Credentials, enabling cross-origin attacks (CWE-346)

Open
#6,390 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
6.5k
Forks
787
PR merge metrics
No merged PRs in 30d

Description

Summary

The CORS middleware reflects the request's Origin header back as Access-Control-Allow-Origin when the configured allow_origin contains *, while simultaneously setting Access-Control-Allow-Credentials: true. This is a well-known CORS misconfiguration that allows any website to make authenticated cross-origin requests to the StackStorm API.

Affected File

st2common/st2common/middleware/cors.py (lines 65-69, 88, 91)

if origin:
    if "*" in origins:
        origin_allowed = origin  # reflects whatever the browser sends
    else:
        origin_allowed = origin if origin in origins else list(origins)[0]
# ...
headers["Access-Control-Allow-Origin"] = origin_allowed
# ...
headers["Access-Control-Allow-Credentials"] = "true"  # always set

Additionally, the middleware hardcodes localhost development origins that are always allowed:

# Default gulp development server WebUI URL
origins.add("http://127.0.0.1:3000")

# By default WebUI simple http server listens on 8080
origins.add("http://localhost:8080")
origins.add("http://127.0.0.1:8080")

Impact

When allow_origin contains *:
Any website can make authenticated, credential-bearing requests to the StackStorm API from a user's browser. If a StackStorm user visits a malicious page while logged in, the attacker can:

  • Read API responses (execution results, datastore values, pack configurations)
  • Trigger action executions
  • Modify rules and workflows
  • Exfiltrate API keys and tokens

This is because the combination of a reflected Access-Control-Allow-Origin and Access-Control-Allow-Credentials: true tells the browser to include cookies/auth headers and allow the response to be read by the requesting page.

Hardcoded localhost origins:
If an attacker can run a web server on localhost:3000 or localhost:8080 on a machine where a StackStorm user has an active session, they can exploit these hardcoded origins. These should not be present in production builds.

Recommended Fix

  1. Never reflect the Origin header when Access-Control-Allow-Credentials is true. If wildcard origin is configured, either:

    • Set Access-Control-Allow-Origin: * and remove Access-Control-Allow-Credentials (allows unauthenticated CORS only)
    • Or reject the configuration and log a warning
  2. Remove hardcoded localhost origins from the default allowed list. These should only be present in development configurations.

  3. Only set Access-Control-Allow-Credentials: true when the origin is explicitly whitelisted (not wildcarded).

if origin and origin in origins:
    headers["Access-Control-Allow-Origin"] = origin
    headers["Access-Control-Allow-Credentials"] = "true"
elif "*" in origins:
    headers["Access-Control-Allow-Origin"] = "*"
    # Do NOT set Allow-Credentials with wildcard origin

References

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading st2common/st2common/middleware/cors.py at the referenced lines 65-69, 88, and 91, and trace how configured origins become response headers. Verify that wildcard origins do not receive credentials, explicit allowlisted origins retain credentials, and hardcoded localhost origins are absent from production defaults.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
api, backend, security
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.