关于Acunetix扫描漏洞
- 没有 CSRF 保护的 HTML 表单
解决方案:
在登录页面添加 @Html.AntiForgeryToken(),同时对应的Controllers层添加[ValidateAntiForgeryToken]
如果上述方法不可行,可以尝试,在登录页面表单提交添加
代码语言:javascript复制<input type="hidden" name="txtx" autocomplete="off" class="layui-input" value="12345"/>
其中value的值是从后台传递过来的,提交表单时验证
在后台添加一个固定代码,生成value值时加上时间戳,在加密之后传回前台。
代码语言:javascript复制private string LogOntoken = "txtx" DateTime.Now.ToString("yyyyMMddHHmmss");
前台提交时传回后台,后台解密字符串看是否包含"txtx"
2、点击劫持:X-Frame-Options 标头丢失
解决方案:在web.config配置X-Frame-Options,添加在<system.webServer>下面
代码语言:html复制<system.webServer>
<httpProtocol>
<customHeaders>
<add name="X-Frame-Options" value="SAMEORIGIN" />
</customHeaders>
</httpProtocol>
</system.webServer>
3、未设置安全标志的 Cookie
解决方案:在web.config配置 <httpCookiesrequireSSL="true"/>,添加在<system.web>节点里面
代码语言:html复制<httpCookies requireSSL="true" />
<authentication mode="Forms">
<forms requireSSL="true" ..... />
</authentication>
如果节点下面有authentication 节点还需要在 表单forms里面配置requireSSL="true"。配置完成之后又可能会导致乱码(不是所有的项目都会,没找到解决方案!)
4、内容安全策略 (CSP) 未实施
解决方案:可以在 web.config 配置,在<system.webServer>节点里面
<add name="Content-Security-Policy" value="frame-ancestors 'self'" />
代码语言:html复制当前配置 :# 只允许被同源的页面嵌入
<httpProtocol>
<customHeaders>
<add name="Content-Security-Policy" value="frame-ancestors 'self'" />
</customHeaders>
</httpProtocol>
代码语言:javascript复制
# 不允许被嵌入,包括<frame>, <iframe>, <object>, <embed> 和 <applet>
Content-Security-Policy: frame-ancestors 'none'
# 只允许被同源的页面嵌入
Content-Security-Policy: frame-ancestors 'self'
# 只允许被白名单内的页面嵌入
Content-Security-Policy: frame-ancestors www.example.com
# 不允许被嵌入,包括<frame>, <iframe>, <embed> 和 <object>
X-Frame-Options: deny
# 只允许被同源的页面嵌入
X-Frame-Options: sameorigin
# (已废弃)只允许被白名单内的页面嵌入
X-Frame-Options: allow-from www.example.com
具体参考:https://blog.csdn.net/ynchyong/article/details/112005292
或者在页面 head 配置
代码语言:html复制<meta http-equiv="Content-Security-Policy" Content="frame-ancestors 'self'">
如果有外部引用,可以在后面添加对应的url就行,链接地址到端口号就行。如下例子:
代码语言:javascript复制<meta http-equiv="Content-Security-Policy" Content="default-src 'self' https://host1.com">
5、启用自动完成的密码类型输入
代码语言:javascript复制<INPUT TYPE="password" class = "form-control" AUTOCOMPLETE="off">
或者
<INPUT TYPE="password" class = "form-control" AUTOCOMPLETE="new-password">
--off有可能不支持了,需要使用new-password
关于PasswordFor密码框:密码自动填充
代码语言:javascript复制@Html.PasswordFor(x=> x.Authorize.Leader,new{ Value ="", @class="form-control", @autocomplete ="new-password", id ="txtLoginUserPwd", placeholder ="请输入密码"})
如果需要密码框不记住密码,在密码框添加oninput 事件,同时添加一个隐藏的文本框
代码语言:javascript复制@Html.PasswordFor(x => x.Authorize.Leader, new { Value = "", oninput = "OnChangeEvent()", @class = "form-control", @autocomplete = "new-password", id = "txtLoginUserPwd", placeholder = "请输入密码" })
<input type="hidden" id="HiddenPwd" autocomplete="off" name="HiddenPwd" />
js代码
代码语言:javascript复制<script>
var typing = true;
function OnChangeEvent() {
$('#txtLoginUserPwd')
.on('compositionstart', event => {
// 中文输入法开始输入
typing = false;
})
.on('compositionend', event => {
// 中文输入法结束输入
typing = true;
})
if (typing) {
var pwd = $("#txtLoginUserPwd").val();
var hiddenPwd = $("#HiddenPwd").val();
let value = pwd;
if (value != '') {
for (let i = 0; i < value.length; i ) {
if (value.charAt(i) != "u25CF") {
//如果不是圆点,表示该字符为用户输入的值,放到真实值的对应位置
let char = value.charAt(i);
hiddenPwd = hiddenPwd.slice(0, i) char hiddenPwd.slice(i);
//将该字符替换为圆点
value = value.slice(0, i) "u25CF" value.slice(i 1);
console.log(i);
console.log(value);
}
}
//防止真实值和圆点的数量不对应。
hiddenPwd = hiddenPwd.slice(0, value.length);
$("#HiddenPwd").val(hiddenPwd);
//将转换过的字符串显示给用户
value = value.slice(0, value.length);
$("#txtLoginUserPwd").val(value);
} else {
//保持一致性
$("#HiddenPwd").val("");;
}
}
else {
var pwd = $("#txtLoginUserPwd").val();
pwd = pwd.replace(/[u4E00-u9FA5]/g, '');
$("#txtLoginUserPwd").val(pwd);
}
}
</script>