SRIによるlocalStorageコードセキュリティの強化
JS/CSSコードをローカルにキャッシュする用途は、このブログで繰り返していますが、ここではくどくどしません.このセキュリティ上の危険性の根源は、ほとんどのWebアプリケーションがlocalStorageからキャッシュコードを取得した後、検出メカニズムがなく、直接実行されることです.一方、localStorageはページをまたいでおり、同ドメインの下のどのページにもXSSの脆弱性があれば、攻撃者が往来localStorageで悪意のあるコードを書き込むことができる.
次のいくつかの概略コードは、問題の所在をより明確に見ることができます.
<!-- -->
<script id="code">/* */</script>
<script>html2ls('my_code', document.getElementById('code').innerHTML)</script>
<script>
function html2ls(ls_name, code) {
localStorage[ls_name] = code;
}
</script>
<!-- -->
<script>ls2html('my_code')</script>
<script>
function ls2html(ls_name) {
var script = document.createElement('script');
script.innerHTML = localStorage[ls_name]; // :/* */
document.head.appendChild(script);
}
</script>
<!-- XSS -->
<img src="" onerror="localStorage['my_code']+=';alert(0);'" />
<!-- N -->
<script>ls2html('my_code')</script>
<script>
function ls2html(ls_name) {
var script = document.createElement('script');
script.innerHTML = localStorage[ls_name]; // :/* */;alert(0)
document.head.appendChild(script);
}
</script>
Web loader , loader localStorage , , 。
, : , ls2html
でチェックします.ただし、ブラウザで を するには、 きなJSを する があります.ls2html
をできるだけ く できるように(localStorageからCSSを み るのもそれに するため)、このJSはページの に されなければならず、ページのパフォーマンスに きな を ぼす.また, で した アルゴリズムは, きなテキストを する にもあまり ではない.
の では、SRIポリシーを して、ブラウザが チェーンリソースの とコンテンツが するかどうかを に できることを りました. しいコードを する がなく、ブラウザに み まれたアルゴリズムもより になります.
SRIは チェーンリソースにのみ するため、localStorageから したコードを チェーン に する があります.この を するには、data URIsとBlob URLの2つのスキームがあります.
コードをdata URIs の チェーンに し、SRIを にします.
var code = 'alert("hello world!");';
var script = document.createElement('script');
script.crossOrigin = 'anonymous';
script.integrity = 'sha256-0URT8NZXh/hI7oaypQXNjC07bwnLB52GAjvNiCaN7Gc=';
script.src = 'data:application/x-javascript,' + encodeURIComponent(code);
document.head.appendChild(script);
Blob URL SRI:
var code = 'alert("hello world!");';
var blob = new Blob([code], {type: "application/x-javascript"});
var blobUrl = URL.createObjectURL(blob);
var script = document.createElement('script');
script.crossOrigin = 'anonymous';
script.integrity = 'sha256-0URT8NZXh/hI7oaypQXNjC07bwnLB52GAjvNiCaN7Gc=';
script.src = blobUrl;
document.head.appendChild(script);
SRI Chrome Firefox , :
Chrome 46.0.2490.33 beta
Firefox 44.0a1 (2015-09-23)
data URIs( SRI)
Blob URL( SRI)
data URIs(SRI + )
CORS
、
Blob URL(SRI + )
、
data URIs(SRI + )
CORS
、
Blob URL(SRI + )
Integrity
、
:
- SRI , ;
- Firefox , SRI ,data URIs Blob URL ;
- Chrome , SRI ,data URIs CORS ;
- Chrome , SRI ,Blob URL
integrity
;
の は が んでいることがわかります. のコードを し、2 のアクセス に を し、 メカニズムを します. <!-- -->
<script>ls2html('my_code', 'sha256-xxxx')</script>
<script>
function ls2html(ls_name, integrity) {
var script = document.createElement('script');
var code = localStorage[ls_name];
if (-1 == (navigator.userAgent || '').toLowerCase().indexOf('firefox') && window.URL && window.Blob) {
var blob = new Blob([code], {type: "application/x-javascript"});
var blobUrl = URL.createObjectURL(blob);
script.crossOrigin = 'anonymous';
script.integrity = integrity;
script.src = blogUrl;
script.onerror = function() { alert('localStorage !') };
} else {
script.innerHTML = code;
}
document.head.appendChild(script);
}
</script>
, 。 CSP , script-src blob:
. のブログでは、このlocalStorageコードのセキュリティ を しています.ブラウザ・コンソールを き、 のコードを してページをリフレッシュします.
localStorage.all_js += ';alert(0);'
Chrome 45+, alert(0) 。 localStorage , 。
Chrome Firefox , [email protected] 。 Chrome 。
NodeJS , SRI integrity , crypto
モジュールでいいです.
var crypto = require('crypto');
function getIntegrity(content, algorithm) {
algorithm = algorithm || 'sha256';
var result = algorithm + '-' + crypto
.createHash(algorithm)
.update(content)
.digest("base64");
return result;
}
, Content Security Policy Level 2(CSP2) , , , 。 。
: https://imququ.com/post/enhance-security-for-ls-code.html,
: