Skip to content

Commit 9ba43f8

Browse files
committed
Make Login.ashx page CSP-compliant
The page used `<body onload="document.forms[0].submit()">` which is not compliant with our stricter Content-Security Policy as that will block all in-line JavaScript. Instead use a <script> element to auto-submit the form. Note: In order to populate the nonce attribute in the new script element, we need the value of the nonce for that request. The simplest way to get this is to pull this out of the HTTP Context, which is what this change does, but this adds an additional level of coupling between the library and the application using it.
1 parent e164d11 commit 9ba43f8

3 files changed

Lines changed: 13 additions & 6 deletions

File tree

src/SAML2/Bindings/HttpPostBindingBuilder.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,9 @@ public string Response
9090
/// <summary>
9191
/// Gets the ASP.Net page that will serve html to user agent.
9292
/// </summary>
93+
/// <param name="cspNonce"></param>
9394
/// <returns>The Page.</returns>
94-
public Page GetPage()
95+
public Page GetPage(string cspNonce)
9596
{
9697
if (_request == null && _response == null)
9798
{
@@ -112,7 +113,7 @@ public Page GetPage()
112113
var head = new HtmlHead { Title = "SAML2.0 POST binding" };
113114
p.Controls.Add(head);
114115

115-
p.Controls.Add(new LiteralControl(Environment.NewLine + "<body onload=\"document.forms[0].submit()\">" + Environment.NewLine));
116+
p.Controls.Add(new LiteralControl(Environment.NewLine + "<body>" + Environment.NewLine));
116117
p.Controls.Add(new LiteralControl("<noscript><p><strong>Note:</strong> Since your browser does not support JavaScript, you must press the Continue button once to proceed.</p></noscript>"));
117118

118119
p.Controls.Add(new LiteralControl("<form action=\"" + _destinationEndpoint.Url + "\" method=\"post\"><div>"));
@@ -137,7 +138,10 @@ public Page GetPage()
137138
p.Controls.Add(action);
138139

139140
p.Controls.Add(new LiteralControl("<noscript><div><input type=\"submit\" value=\"Continue\"/></div></noscript>"));
140-
p.Controls.Add(new LiteralControl("</div></form>"));
141+
p.Controls.Add(new LiteralControl("</div></form>"));
142+
143+
var nonceString = string.IsNullOrEmpty(cspNonce) ? "" : $" nonce={cspNonce}";
144+
p.Controls.Add(new LiteralControl(Environment.NewLine + $"<script{nonceString}>document.forms[0].submit();</script>"));
141145
p.Controls.Add(new LiteralControl(Environment.NewLine + "</body>" + Environment.NewLine + "</html>"));
142146

143147
return p;

src/SAML2/Protocol/Saml20LogoutHandler.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,8 @@ private void HandleRequest(HttpContext context)
363363
XmlSignatureUtils.SignDocument(responseDocument, response.Id);
364364
builder.Response = responseDocument.OuterXml;
365365
builder.RelayState = context.Request.Params["RelayState"];
366-
builder.GetPage().ProcessRequest(context);
366+
var cspNonce = HttpContext.Current.Items["CSP-Script-Nonce"] as string;
367+
builder.GetPage(cspNonce).ProcessRequest(context);
367368
}
368369
}
369370

@@ -484,7 +485,8 @@ private void TransferClient(IdentityProviderElement idp, HttpContext context)
484485

485486
Logger.DebugFormat(TraceMessages.LogoutRequestSent, idp.Id, "POST", builder.Request);
486487

487-
builder.GetPage().ProcessRequest(context);
488+
var cspNonce = HttpContext.Current.Items["CSP-Script-Nonce"] as string;
489+
builder.GetPage(cspNonce).ProcessRequest(context);
488490
context.Response.End();
489491
return;
490492
}

src/SAML2/Protocol/Saml20SignonHandler.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -727,7 +727,8 @@ private void TransferClient(IdentityProviderElement identityProvider, Saml20Auth
727727

728728
Logger.DebugFormat(TraceMessages.AuthnRequestSent, postBuilder.Request);
729729

730-
postBuilder.GetPage().ProcessRequest(context);
730+
var cspNonce = HttpContext.Current.Items["CSP-Script-Nonce"] as string;
731+
postBuilder.GetPage(cspNonce).ProcessRequest(context);
731732
break;
732733
case BindingType.Artifact:
733734
Logger.DebugFormat(TraceMessages.AuthnRequestPrepared, identityProvider.Id, Saml20Constants.ProtocolBindings.HttpArtifact);

0 commit comments

Comments
 (0)