Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
// applicationCacheの更新を妨害する
Object.defineProperty(this,'applicationCache',{get:function(){return{}}});
(function () {
// AppCache上でlocation.hrefを読み込むとAppCacheの内容を読み込むため、「ブラウザは別URLと認識するが、サーバは同じコンテンツを返すURL」を作る
contentLoad(location.href+'/');
// 本来であればsubmit等のイベントもキャッチする必要がある
window.addEventListener('click', function (evn) {
var elem = evn.target;
while (elem.tagName.toLocaleLowerCase() != 'a') elem = elem.parentNode;
if (elem.tagName.toLocaleLowerCase() != 'a') return;
evn.preventDefault();
history.pushState({}, null, elem.href);
// 本来であれば外部ドメインの場合は普通に遷移させる必要がある
contentLoad(elem.href);
});
function contentLoad (url) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
// キャッシュを無視して取得する(ユーザ操作での画面遷移時に使う)
xhr.setRequestHeader('Expires', 'Mon, 1 Jan 1990 00:00:00 GMT');
xhr.setRequestHeader('Cache-Control', 'no-cache');
xhr.setRequestHeader('Pragma', 'no-cache');
// Acceptを置き換えることでXHRと通常のブラウザの通信が見分けにくくなる
xhr.setRequestHeader('Accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8');
xhr.onreadystatechange = function () {
if (!xhr.responseText) return;
var range = document.createRange();
range.selectNodeContents(document.documentElement);
range.deleteContents();
// サーバ側のコンテンツをフィルタしたい場合、xhr.responseTextを置き換える
var fragment = range.createContextualFragment(xhr.responseText);
// Object.definePropertyでAppCacheが更新できなくなっているため、サーバ側のJSを呼んでも攻撃が妨害されない
document.documentElement.appendChild(fragment);
window.scrollTo(0, 0); // 本来はlocation.hashがない場合のみ等scrollさせる
};
xhr.send();
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment