admin管理员组文章数量:1287597
I am designing a JavaScript secure loader. The loader is inlined in the index.html
. The goal of the secure loader is to only load JavaScript resources are trusted. The contents of index.html
are mostly limited to the secure loader. For security purposes, I want index.html
(as stored in cache) to never change, even if my website is hacked.
How can I cache index.html
without the server being able to tamper with the cache? I am wondering if ServiceWorker
s can help. Effectively, the index.html
would register a service worker for fetching itself from an immutable cache (no network request is even made).
I am designing a JavaScript secure loader. The loader is inlined in the index.html
. The goal of the secure loader is to only load JavaScript resources are trusted. The contents of index.html
are mostly limited to the secure loader. For security purposes, I want index.html
(as stored in cache) to never change, even if my website is hacked.
How can I cache index.html
without the server being able to tamper with the cache? I am wondering if ServiceWorker
s can help. Effectively, the index.html
would register a service worker for fetching itself from an immutable cache (no network request is even made).
-
1
Not certain what you are trying to achieve? Once user visits
index.html
, thehtml
document
itself and resources linked fromindex.html
should not be changed? – guest271314 Commented Feb 3, 2017 at 21:16 - 4 What you seek to achieve -if possible- would ALSO prohibit you from ever updating said method for recurring visitors while it would offer no protection at all for new visitors. Seems far too many drawbacks for the limited advantage you might achieve. – user3277192 Commented Feb 6, 2017 at 4:37
- @swa66 The secure loader would have logic to be updatable in a controlled fashion. – Randomblue Commented Feb 7, 2017 at 15:17
- 1 @swa66 Cryptographic signatures for which only the legitimate website owner has. – Randomblue Commented Feb 8, 2017 at 12:06
- 1 With all due respect, </disclaimer> you do not design a website considering it is going to be hacked and you will lose control of it each and every day after your 4pm tea. You just don't. Reason of your question rather smells like you are going to hack some website and put a content there, and you do not want legitimate admin to be able to change it afterwards. Again, forgive me if it is not the case but this smells plain maleficent to me. – Umur Karagöz Commented Feb 10, 2017 at 9:27
3 Answers
Reset to default 4 +100in chrome you can use FileSystem API
http://www.noupe./design/html5-filesystem-api-create-files-store-locally-using-javascript-webkit.html this allows you to then save and read files from a sand-boxed file-system though the browser.
As for other support it's not been confirmed as an addition to the HTML5 specification set yet. so it's only available in chrome.
You could also use the IndexDB system this is supported in all modern browsers.
you can use both these services inside a Service Worker to manage the loading and manage of the content however i have to question why would you want to you prevent your self from ever updating your index.html
This design goal of "secure javascript loading"/TOFU is typically associated with javascript crypto and browser secrets (e.g. Cyph, Mega), so I'll include some relevant remendations along the way.
You're in dangerous territory. There are many dragons.
Option 1: Implement feross/infinite-app-cache to permanently cache the app in the browser
Here's the least amount of code required to achieve a TOFU web app in all browsers.
index.html:
<html manifest="manifest.appcache">
manifest.app cache:
CACHE MANIFEST
/manifest.appcache
/index.html
/script-loader.js
And make sure you serve the manifest with a content type of "text/cache-manifest".
Note: This standard is deprecated, however it will take some years before browsers disable this feature.
Problem: If an attacker (who has already hacked your server) can trick your users into visiting a URL not in the app cache, they can serve arbitrary code to extract/use browser secrets etc.
Solution: User input cannot be intercepted by a malicious page on the same domain (unless you do something really silly), so encrypt any browser secrets using a user-supplied password and dchest/scrypt-async-js.
Another thing to consider is the cached contents of a page CAN be extracted by the malicious page simply by using AJAX - so you HAVE to use user input, not just a random token rendered to the page.
Option 2: Extend the above solution with HPKP Suicide and a Service Worker
Implement HPKP Suicide to permanently "bake" the app into the browser by bricking the user's connection to the server.
If (and only if) you have implemented HPKP Suicide, service workers are now safe to use because the enforced max-age of 24 hours has no effect if the browser can't re-download the service worker.
index.html or script-loader.js:
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/service-worker.js').catch(function (error) {
console.error(error);
});
});
}
service-worker.js:
var files = [
'/',
'index.html',
'script-loader.js'
].map(file => new Request(file))
self.addEventListener('install', () => {
caches.open('cache')
.then(cache => {
files.map(file => {
fetch(file)
.then(response => cache.put(file, response))
.catch(err => console.error(err))
})
})
.catch(err => console.error(err))
})
self.addEventListener('fetch', (e) => {
var url = e.request.url.split('#')[0]
if (!files.filter(file => file.url === url).length) {
return e.respondWith(new Response('Not Found', { status: 404 }))
}
return e.respondWith(
caches.match(e.request).then(cachedResponse => {
if (cachedResponse) return cachedResponse
return Promise.all([
caches.open('cache'),
fetch(e.request.clone())
]).then((results) => {
var cache = results[0]
var response = results[1]
cache.put(e.request, response.clone())
return response
})
})
)
})
Important note: Without HPKP Suicide, using a service worker is LESS secure than infinite app cache because the service worker has a max-age of 24 hours, even if your server's cache directives set a higher age. Using service workers will also pletely disable app cache. It's a waste of time trying to achieve this with service workers if you haven't implemented HPKP Suicide.
Discussion
- HPKP suicide has lost the guarantee of permanence in Chrome as they have recently implemented a max-max-age of 60 days (see issue #523654 for discussion)
- I strongly remend you use TweetNaCl.js for all browser crypto: it takes effort to use incorrectly and unless you are encrypting large files the performance difference with WebCrypto is insignificant
You can also use Cache API, which can save the responses of your requests (all kinds of requests - html pages, api requests, images). But note, that it's currently supported only in Chrome and Firefox.
On that page is also example how to use it with fetch
本文标签: javascriptPermanent browser cache using ServiceWorkerStack Overflow
版权声明:本文标题:javascript - Permanent browser cache using ServiceWorker - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741308135a2371491.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论