子资源完整性:如何只显示警告而不显示块资源?
Subresource Integrity: How to show only warning but not block resource?
我想为 Subresource Integrity 属性创建一个 soft integration,所以请确保我没有破坏应用程序,但只是为了显示一个警告,我需要修复一些地方。
是否有这样做的选项?
我不建议仅在 SRI-Hashes 不匹配时才显示警告。当以用户身份看到警告时,为时已晚,您的计算机上执行了潜在的恶意脚本。
但是,您可以使用 ServiceWorker
-API 和类似 <script data-integrity="xxxxxxxx">
的方式实现您想要的行为。为此,您需要:
- 注册一个新的
ServiceWorker
- 收听
fetch
事件
[Client.postMessage]
你父级的 targetURL
- 通过 targetURL 获取脚本完整性哈希
$('script[src=event.data.targetURL]').attr('data-integrity')
并使用 Worker.postMessage
将其推送到客户端
- 使用 e.G. 散列响应
cryptojs.sha256
- 匹配工人内部的哈希值
- 如果哈希匹配,return 响应。如果它们不匹配,return 响应并再次使用
Client.postMessage
触发警告。
安全方法
如果您需要某种灵活性,那么您也应该使用 - loading required resource from another URL. Probability that two different URL's will be hacked at the same time is a lot smaller compared to hacking just one resource. Fallback doesn't violate site security, because you must trust your known-good sources which you use in your code. If your resource is a Javascript - you can use a noncanonical-src 属性作为备用。
不安全的方法
现在,如果您真的非常希望用户通过强制损害资源加载来破坏服务器 and/or 客户端安全 - 至少询问用户 he/she 是否会为此承担责任。当然,这仍然是一件愚蠢的事情,就像在问“你想运行计算机中的病毒吗?”。我敢打赌没有人愿意说是。不管怎样,这是代码,它确实会问这些类型的问题:
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.min.js"></script>
<script>
function loadResource(path) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var cs = CryptoJS.SHA256(this.responseText);
if (btoa(cs) == 'NjBiMTllNWRhNmE5MjM0ZmY5MjIwNjY4YTVlYzExMjVjMTU3YTI2ODUxMzI1NjE4OGVlODBmMmQyYzhkOGQzNg==' ||
confirm('Bootstrap is NOT the latest version 4.3.1, load anyway ?')
) {
var link = document.createElement('link');
link.rel = "stylesheet";
link.href = path;
document.head.appendChild(link);
}
else {
var err = document.getElementById('error');
err.title = "Component version error !";
err.innerHTML = ' ⚠️';
}
}
};
xhttp.open("GET", path, true);
xhttp.send();
}
loadResource(
//'https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css' // newest boostrap
'https://stackpath.bootstrapcdn.com/twitter-bootstrap/2.0.4/css/bootstrap-combined.min.css' // old legacy
);
</script>
我想为 Subresource Integrity 属性创建一个 soft integration,所以请确保我没有破坏应用程序,但只是为了显示一个警告,我需要修复一些地方。
是否有这样做的选项?
我不建议仅在 SRI-Hashes 不匹配时才显示警告。当以用户身份看到警告时,为时已晚,您的计算机上执行了潜在的恶意脚本。
但是,您可以使用 ServiceWorker
-API 和类似 <script data-integrity="xxxxxxxx">
的方式实现您想要的行为。为此,您需要:
- 注册一个新的
ServiceWorker
- 收听
fetch
事件 [Client.postMessage]
你父级的 targetURL- 通过 targetURL 获取脚本完整性哈希
$('script[src=event.data.targetURL]').attr('data-integrity')
并使用Worker.postMessage
将其推送到客户端
- 使用 e.G. 散列响应
cryptojs.sha256
- 匹配工人内部的哈希值
- 如果哈希匹配,return 响应。如果它们不匹配,return 响应并再次使用
Client.postMessage
触发警告。
安全方法
如果您需要某种灵活性,那么您也应该使用
不安全的方法
现在,如果您真的非常希望用户通过强制损害资源加载来破坏服务器 and/or 客户端安全 - 至少询问用户 he/she 是否会为此承担责任。当然,这仍然是一件愚蠢的事情,就像在问“你想运行计算机中的病毒吗?”。我敢打赌没有人愿意说是。不管怎样,这是代码,它确实会问这些类型的问题:
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.min.js"></script>
<script>
function loadResource(path) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var cs = CryptoJS.SHA256(this.responseText);
if (btoa(cs) == 'NjBiMTllNWRhNmE5MjM0ZmY5MjIwNjY4YTVlYzExMjVjMTU3YTI2ODUxMzI1NjE4OGVlODBmMmQyYzhkOGQzNg==' ||
confirm('Bootstrap is NOT the latest version 4.3.1, load anyway ?')
) {
var link = document.createElement('link');
link.rel = "stylesheet";
link.href = path;
document.head.appendChild(link);
}
else {
var err = document.getElementById('error');
err.title = "Component version error !";
err.innerHTML = ' ⚠️';
}
}
};
xhttp.open("GET", path, true);
xhttp.send();
}
loadResource(
//'https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css' // newest boostrap
'https://stackpath.bootstrapcdn.com/twitter-bootstrap/2.0.4/css/bootstrap-combined.min.css' // old legacy
);
</script>