webforms - 自定义 Web 表单脚本生成
问题描述
好的,是的,现在是 2020 年,但不要笑。我正在尝试更新一些 ASP.NET Web 表单。我的目标是锁定它们,通过应用更严格的内容安全策略 (CSP) 使它们更安全。为此,我使用的是随机数,而不是允许unsafe-inline
编写脚本。
对于“简单”的网络表单,它运行良好。但是,每当有一个导致回发的 ASP 控件时,我都会遇到问题。当我查看页面源代码时,我看到如下内容:
<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 Web 表单代码生成的。问题是这些脚本元素都没有我想提供的随机数,所以它违反了我的 CSP(不包括unsafe-inline
)。有什么我可以重写来自定义这种行为吗?
解决方案
一些违规代码是在类RenderPostBackScript
内部的私有方法(例如 )中定义的,而该私有方法Page
又由内部方法调用。因此,除非我替换大量代码,否则不能以正常方式覆盖它。作为替代方案,我CreateHtmlTextWriter
在我的页面中覆盖:
protected override System.Web.UI.HtmlTextWriter CreateHtmlTextWriter(TextWriter tw)
{
return new HtmlTextWriter(tw, this);
}
然后在我的HtmlWriter
课堂上,我这样做:
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
的 for中使用了类似的方法AddAttribute
来避免 inline javascript:
inside href
,这将需要unsafe-inline
for script-src
(并排除使用 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);
}
}
推荐阅读
- react-native - 键盘打开时隐藏标签栏反应本机
- vue.js - 如何在应用程序内获取开发服务器代理目标?
- amazon-web-services - 允许 S3 访问同一账户中的特定 IAM 角色的 IAM 策略
- zio - 如何为理解片段运行一个简单的 ZIO
- java - 如何每 10 秒执行一次函数
- asp.net - 使用 MySQL 的 Visual Studio ASP.Net
- testing - 有没有办法使用运行器运行具有 TestCafe 的 test.meta 的测试?
- python - 自定义视图组件到基于视图
- c# - 通过 JSON 类进行迭代
- excel - Excel代码基于多个值和列复制行