自定义 Web 表单脚本生成 [英] Customize web form script generation
问题描述
好的,是的,现在是 2020 年,但不要笑.我正在尝试更新一些 ASP.NET Web 表单.我的目标是锁定它们,通过应用更严格的内容安全策略 (CSP) 使它们更安全.为此,我使用的是随机数,而不是允许 unsafe-inline
用于脚本编写.
Ok, yes, it's 2020 but don't laugh. I'm trying update some ASP.NET web forms. My goal is to lock them down, making them more secure by applying a more restrictive Content Security Policy (CSP). To that end, I'm using a nonce, rather than allowing unsafe-inline
for scripting.
对于简单"网络表单,它工作正常.但是,每当有导致回发的 ASP 控件时,我都会遇到问题.当我查看页面源代码时,我看到如下内容:
For "simple" web forms, it's working fine. However, I hit a problem whenever there's an ASP control that results in a post back. When I look in the page source, I see stuff like this:
<script type="text/javascript">
//<![CDATA[
var theForm = document.forms['form1'];
if (!theForm) {
theForm = document.form1;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
和
<script type="text/javascript">
function previewFile() {
var preview = document.querySelector('#Body_Main_LogoImage');
var file = document.querySelector('#Body_Main_logoUpload').files[0];
var reader = new FileReader();
reader.onloadend = function () {
preview.src = reader.result;
}
if (file) {
reader.readAsDataURL(file);
} else {
preview.src = "";
}
}
</script>
我相信这段代码是由一些 MS 网页表单代码生成的.问题是这些脚本元素都没有我想提供的随机数,所以它违反了我的 CSP(不包括 unsafe-inline
).有什么我可以覆盖来自定义这种行为的吗?
This code is generated by some of the MS web form code, I believe. The problem is that neither of these script elements have a nonce, which I'd like to supply, so it is in violation of my CSP (which does not include unsafe-inline
). Is there anything I can override to customize this behaviour?
推荐答案
一些有问题的代码定义在 Page
类中的私有方法中(例如 RenderPostBackScript
),反过来又被内部方法调用.因此,除非我替换大量代码,否则无法以正常方式覆盖它.作为替代方案,我在我的页面中覆盖了 CreateHtmlTextWriter
:
Some of the offending code is defined in a private method (e.g. RenderPostBackScript
) inside the Page
class, which in turn is called by internal methods. So, overriding it the normal way isn't an option unless I replace a large bunch of code. As an alternative, I overrode CreateHtmlTextWriter
in my page:
protected override System.Web.UI.HtmlTextWriter CreateHtmlTextWriter(TextWriter tw)
{
return new HtmlTextWriter(tw, this);
}
然后在我的 HtmlWriter
类中,我这样做:
and then in my HtmlWriter
class, I do this:
public override void Write(string s)
{
if (s != null && s.IndexOf("<script") > -1 && s.IndexOf("nonce") == -1 && s.IndexOf("src") == -1)
{
s = s.Replace("<script", "<script nonce="" + this._page.GetNonce() + """);
}
base.Write(s);
}
我在我的 HtmlTextWriter
中为 AddAttribute
使用了类似的方法来避免在 href
中内联 javascript:
,它script-src
需要 unsafe-inline
(并排除使用 nonce).
I used a similar approach in my HtmlTextWriter
for AddAttribute
to avoid inline javascript:
inside href
, which would required unsafe-inline
for script-src
(and preclude the use of a nonce).
public override void AddAttribute(HtmlTextWriterAttribute key, string value)
{
if (key == HtmlTextWriterAttribute.Href && value != null && value.IndexOf("javascript:") > -1)
{
base.AddAttribute(key, "#");
var newScript = value.Replace("javascript:", "");
newScript += "; return false;";
base.AddAttribute(HtmlTextWriterAttribute.Onclick, newScript);
}
else
{
base.AddAttribute(key, value);
}
}
这篇关于自定义 Web 表单脚本生成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!