自定义网页表单脚本生成

问题描述 投票:0回答:3

好吧,是的,现在是 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
)。有什么我可以覆盖以自定义此行为吗?

webforms content-security-policy
3个回答
4
投票

一些有问题的代码是在

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
中为
AddAttribute
使用了类似的方法来避免内联
javascript:
href
内,这需要
unsafe-inline
用于
script-src
(并排除使用随机数)。

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);
    }
}

1
投票

您可以重写

__DoPostBack
并使用您自己的函数。

var __original= __doPostBack;
__doPostBack = myFunction();

这里有更多想法: 如何拦截页面中的任何回发? -ASP.NET


0
投票

如果你在 Chrome 中打开开发工具,你可能会看到这样的消息

拒绝执行内联脚本,因为它违反了以下内容安全策略指令:

"script-src 'self'
'unsafe-inline'
关键字、散列 (
'sha256-2NqnatcPqy5jjBXalTpZyJMO/0fUaYUb3ePlviUP4II='
) 或随机数 (
'nonce-...'
) 是启用内联执行所必需的。

如果您仔细查看该消息,它会告诉您哈希值是什么:

sha256-2NqnatcPqy5jjBXalTpZyJMO/0fUaYUb3ePlviUP4II=

所以如果你不想走 nonce 路线,你可以改走哈希路线并添加

Content-Security-Policy: script-src 'self' 'sha256-2NqnatcPqy5jjBXalTpZyJMO/0fUaYUb3ePlviUP4II=' 'unsafe-eval';

在某些情况下,您可能还必须添加

unsafe-eval
才能起作用。

© www.soinside.com 2019 - 2024. All rights reserved.