브라우저가 비공개 브라우징 모드를 사용 중인지 감지
저는 보안에 대한 편집증적인 회사를 위해 엑스트라 넷을 구축하고 있습니다. 그들은 (무엇보다도) 사용자가 쿠키 나 기록이 유지되지 않도록 웹 브라우저에서 개인 정보 보호 브라우징 모드를 켜서 사이트를 탐색하고 있는지 확인하려고합니다.
이 http://jeremiahgrossman.blogspot.com/2009/03/detecting-private-browsing-mode.html 및 https://serverfault.com/questions/18966/force-safari-to-operate-in- 만 찾았습니다. 개인 모드 및 웹 서버에서 상태 감지
이상적인 솔루션은 자바 스크립트를 사용하지 않거나 최소한으로 사용하는 것입니다. 고유 한 쿠키를 설정하려고하면 모든 브라우저와 플랫폼에서 작동합니까? 전에이 일을 한 사람이 있습니까?
감사!
최신 정보
http://crypto.stanford.edu/~collinj/research/incognito/ 는 다른 포스터에서 언급 한 브라우저 핑거 프린터의 CSS 방문 기법을 사용합니다. 힌트를 주셔서 감사합니다.
작고 우아하기 때문에 좋아하지만 가능하면 자바 스크립트 없이도 할 수 있기를 원합니다.
2019 년 6 월 업데이트
Google은 Chrome 76 이상에서 개인 정보 보호 브라우징 모드를 영구적으로 감지 하는 기능 을 제거합니다 . 따라서 시크릿 브라우징을 감지하려는 경우 이제 불가능합니다 (Google에서 찾지 못한 방법을 찾지 않는 한). 비공개 브라우징 모드를 감지하는 기능은 버그로 인식되었으며 의도 된 적이 없습니다.
이 질문을 접하는 다른 사람에게는 2014 년 현재 누군가가 Javascript 또는 CSS를 통해 시크릿 / 비공개 / 안전 브라우징 모드에서 브라우징하고 있는지 감지 할 수있는 신뢰할 수 있고 정확한 방법이 없습니다. 한때 CSS 히스토리 해킹처럼 작동했던 이전 솔루션은 이후 모든 브라우저 공급 업체에서 사용할 수 없게되었습니다.
일상적인 웹 사이트에서 개인 브라우징 모드를 감지해야하는 상황이 있어서는 안됩니다. 사람들은 자신의 이유로 익명으로 브라우징을 선택하거나 익명으로 브라우징하지 않습니다.
Chrome 및 Firefox와 같은 브라우저는 더 이상 localStorage와 같은 기능을 비활성화하지 않습니다. 그들은 단순히 그것을 사용하는 웹 사이트에서 오류가 발생하지 않도록 임시 위치에 네임 스페이스를 지정합니다. 탐색을 마치면 네임 스페이스가 지워지고 아무것도 저장되지 않습니다. 모드에 관계없이 localStorage 지원을 테스트하는 경우 지원하는 브라우저에 대해 항상 true를 반환합니다.
특히 Chrome에서 비공개 모드를 감지하는 다른 방법은 완전히 패치되었으며 더 이상 작동하지 않습니다.
회사 내부적으로 필요한 경우 브라우저 플러그인을 개발해야합니다. 특히 Chrome과 Firefox는 플러그인이 사용자가 비공개 브라우징 / 시크릿 모드에 있는지 확인하고 그에 따라 작업을 수행 할 수있는 내부 API를 노출합니다. 플러그인 외부에서는 수행 할 수 없습니다.
다음은 프라이버시 모드를 감지하는 더 쉬운 방법입니다. 이것은 Safari에서만 작동합니다. 개발중인 웹 앱이 localStorage를 사용하기 때문에 만들었습니다. 개인 정보 보호 모드에서는 Safari에서 LocalStorage를 사용할 수 없으므로 내 앱이 작동하지 않습니다. 페이지로드시 아래 스크립트를 실행하십시오. localStorage를 사용할 수없는 경우 경고 상자가 표시됩니다.
try {
// try to use localStorage
localStorage.test = 2;
} catch (e) {
// there was an error so...
alert('You are in Privacy Mode\nPlease deactivate Privacy Mode and then reload the page.');
}
업데이트 됨 : Chrome이 더욱 발전했으며 시크릿 모드를 사용할 때 감지 할 공간이 더 이상 없습니다.
이 가능합니다 사용되는 대부분의 브라우저에 사용할 개인 정보 보호 브라우징 모드를 감지 할 수 있습니다. 여기에는 Safari, Firefox, IE10, Edge 및 Google Chrome이 포함됩니다.
Firefox
Firefox의 프라이빗 브라우징 모드가 활성화되면 IndexedDB는 프라이빗 브라우징 모드에서 사용할 수 없기 때문에 InvalidStateError를 발생시킵니다.
매우 경우 :
var db = indexedDB.open("test");
db.onerror = function(){/*Firefox PB enabled*/};
db.onsuccess =function(){/*Not enabled*/};
원정 여행
Safari의 경우 핵심은 로컬 저장소 서비스입니다. 프라이버시 모드에서는 비활성화됩니다. 따라서 그것에 액세스하고 try-catch 절을 사용하십시오. 다음 방법은 OSX 및 iOS 장치 모두에서 작동합니다. 이 방법에 대한 크레딧은이 질문과 답변에 있습니다.
var storage = window.sessionStorage;
try {
storage.setItem("someKeyHere", "test");
storage.removeItem("someKeyHere");
} catch (e) {
if (e.code === DOMException.QUOTA_EXCEEDED_ERR && storage.length === 0) {
//Private here
}
}
IE10 / 에지
Internet Explore는 개인 정보 보호 모드에서 IndexedDB를 비활성화 할 수도 있습니다. 그러니 존재를 확인하십시오. 하지만 이것만으로는 충분하지 않습니다. 오래된 브라우저에는 IDB가 없을 수도 있기 때문입니다. 따라서 IE10 및 후속 브라우저에만 해당 / 트리거가있는 이벤트에 대해 다른 검사를 수행하십시오. CodeReview에 대한 관련 질문은 여기 에서 찾을 수 있습니다.
if(!window.indexedDB && (window.PointerEvent || window.MSPointerEvent)){
//Privacy Mode
}
크롬
업데이트 : Chrome 76 이후로 작동하지 않습니다 (@jLynx 덕분에)
Chrome 시크릿 모드는 파일 시스템에서 확인할 수 있습니다. 여기에서 훌륭한 설명을 찾을 수 있습니다.
var fs = window.RequestFileSystem || window.webkitRequestFileSystem;
if (!fs) {
console.log("FS check failed..");
return;
}
fs(window.TEMPORARY, 100, function (fs) {}, function (err) {
//Incognito mode
});
개인 모드를 감지하는 방법은 다음과 같습니다.
function detectPrivateMode(cb) {
var db,
on = cb.bind(null, true),
off = cb.bind(null, false)
function tryls() {
try {
localStorage.length ? off() : (localStorage.x = 1, localStorage.removeItem("x"), off());
} catch (e) {
// Safari only enables cookie in private mode
// if cookie is disabled then all client side storage is disabled
// if all client side storage is disabled, then there is no point
// in using private mode
navigator.cookieEnabled ? on() : off();
}
}
// Blink (chrome & opera)
window.webkitRequestFileSystem ? webkitRequestFileSystem(0, 0, off, on)
// FF
: "MozAppearance" in document.documentElement.style ? (db = indexedDB.open("test"), db.onerror = on, db.onsuccess = off)
// Safari
: /constructor/i.test(window.HTMLElement) || window.safari ? tryls()
// IE10+ & edge
: !window.indexedDB && (window.PointerEvent || window.MSPointerEvent) ? on()
// Rest
: off()
}
detectPrivateMode(function (isPrivateMode) {
console.log('is private mode: ' + isPrivateMode)
})
edit 는 firefox에서 시도하는 현대적이고 빠른 synkronas 방법을 찾았습니다. 즉, indexedDB를 포함하지 않지만 테스트는 안전한 사이트에서만 작동합니다.
: "MozAppearance" in document.documentElement.style ? navigator.serviceWorker ? off() : on()
웹 페이지에서 사용자가 비공개 브라우징 모드에 있음을 확실히 알 수있는 방법은 없습니다. 다양한 브라우저 기능을 확인하려는 시도는 보안 구현이 업데이트됨에 따라 자주 변경되어야합니다. 일부 브라우저에서는 한동안 작동 할 수 있지만 전부는 아닙니다.
회사가 보안에 대해 우려하는 경우 개인 정보 설정이 잠겨있는 Firefox 또는 Chromium 배포를 롤링하고 해당 사용자 지정 클라이언트 만 엑스트라 넷에 연결하도록 허용하는 것이 좋습니다.
localStorage트릭은 수정 된 버그 , 그리고 사파리 11.0에서 더 이상 작동하지 않습니다.
Safari, Opera 및 Internet Explorer (Chrome 아님)에서 작동하는 흥미로운 대안이 있습니다. 이러한 브라우저는 DNT: 1헤더를 전송합니다 (Do Not Track).
이 헤더는 일반 브라우징에 대해 활성화 될 수 있기 때문에 100 % 신뢰할 수는 없지만 (기본적으로 비활성화되어 있음) 개인 정보 보호에 민감한 사용자를 식별하는 데 도움이 될 수 있습니다.
테스트 한 모든 주요 플랫폼과 브라우저에서 작동하는 작은 라이브러리를 만들었습니다 : https://github.com/jLynx/PrivateWindowCheck
당신은 단순히 전화를
isPrivateWindow(function(is_private) {
if(is_private)
alert('Private');
else
alert('Not Private');
});
시크릿 브라우징이 활성화되지 않은 경우 차단하지 않습니다.
왜 스마트 메시지 상자가 있습니까?
고유 한 쿠키를 설정하려고하면 모든 브라우저와 플랫폼에서 작동합니까? 전에이 일을 한 사람이 있습니까?
가장 우아한 해결책은 다음과 같습니다.
- 보안 누출 테스트 수행
- 보안 누출 테스트에서 문제가 발견되면
- 사용자에게 설정을 확인하도록 안내
- 프라이버시 모드 제안
말했듯이 모든 사람이 개인 정보 보호 모드를 활성화 할 수 있거나 활성화해야하는 것은 아닙니다.
웹 브라우저 는 프라이버시 모드가 활성화되면 다르게 작동합니다.
많은 브라우저에서 리소스 캐싱이 제한됩니다. CSS 캐시를 기반으로 브라우저가 어디에 있는지 감지 할 수 있습니다 . JavaScript없이이 공격을 수행 할 수 있습니다 .
EFF는 브라우저 지문 인식 프로젝트를 진행 중 입니다. 프라이버시 모드가 활성화되면 브라우저 지문의 일부가 다릅니다. 어서 시도해보세요 .
사용자가 "비공개 브라우징"모드에 있는지 일반적으로 감지하지 않아야한다는 DigitalSeas의 의견에 동의합니다. 그러나 저는 최근에 FireFox가 "disconnect.me"라는 서비스에 가입하고 있다는 사실을 발견했습니다.이 서비스는 "추적 보호"기능 에서 사용하는 URL 블랙리스트를 제공합니다 . disconnect.me는 특정 소셜 네트워크 (예 : Facebook의 facebook.net )를 블랙리스트에 추가하기 때문에 해당 SDK가 FireFox에로드되지 않는 것으로 나타났습니다. 따라서 사용자에게보다 유용하고 정확한 오류 메시지를 제공하기 위해 개인 브라우징 모드를 시도하고 감지 할 수있는 것이 합리적입니다.
그 정당성을 배제 하면서이 요지 는 해당 브라우저에 특정한 트릭을 사용하여 주요 브라우저에서 개인 브라우징에 대한 탐지를 제공한다고 주장합니다. 이 글을 쓰는 시점에서 (이 글을 읽을 때 요점이 업데이트되었을 수 있음) 감지 로직은 다음과 같습니다.
function retry(isDone, next) {
var current_trial = 0, max_retry = 50, interval = 10, is_timeout = false;
var id = window.setInterval(
function() {
if (isDone()) {
window.clearInterval(id);
next(is_timeout);
}
if (current_trial++ > max_retry) {
window.clearInterval(id);
is_timeout = true;
next(is_timeout);
}
},
10
);
}
function isIE10OrLater(user_agent) {
var ua = user_agent.toLowerCase();
if (ua.indexOf('msie') === 0 && ua.indexOf('trident') === 0) {
return false;
}
var match = /(?:msie|rv:)\s?([\d\.]+)/.exec(ua);
if (match && parseInt(match[1], 10) >= 10) {
return true;
}
return false;
}
function detectPrivateMode(callback) {
var is_private;
if (window.webkitRequestFileSystem) {
window.webkitRequestFileSystem(
window.TEMPORARY, 1,
function() {
is_private = false;
},
function(e) {
console.log(e);
is_private = true;
}
);
} else if (window.indexedDB && /Firefox/.test(window.navigator.userAgent)) {
var db;
try {
db = window.indexedDB.open('test');
} catch(e) {
is_private = true;
}
if (typeof is_private === 'undefined') {
retry(
function isDone() {
return db.readyState === 'done' ? true : false;
},
function next(is_timeout) {
if (!is_timeout) {
is_private = db.result ? false : true;
}
}
);
}
} else if (isIE10OrLater(window.navigator.userAgent)) {
is_private = false;
try {
if (!window.indexedDB) {
is_private = true;
}
} catch (e) {
is_private = true;
}
} else if (window.localStorage && /Safari/.test(window.navigator.userAgent)) {
try {
window.localStorage.setItem('test', 1);
} catch(e) {
is_private = true;
}
if (typeof is_private === 'undefined') {
is_private = false;
window.localStorage.removeItem('test');
}
}
retry(
function isDone() {
return typeof is_private !== 'undefined' ? true : false;
},
function next(is_timeout) {
callback(is_private);
}
);
}
글쎄, 당신은 그런 식으로 개인 모드와 "모든 쿠키 차단"을 실제로 구별하지는 않을 것이지만, 드문 상황을 제외하고는 작동해야한다고 생각합니다.
IMO의 큰 문제는 이것이 매우 나쁜 사이트 디자인이라는 것입니다. 90 년대에 흔했던 "이 웹 사이트를 보려면 브라우저 xxx가 필요합니다." 모든 브라우저에 개인 정보 보호 브라우징 모드가있는 것은 아니며 (예를 들어 IE를 경멸하는만큼) 해당 사용자는 귀하의 사이트에 전혀 액세스 할 수 없습니다.
또한 인터넷에있을 때 여러 웹 사이트가있는 여러 탭이 열리는 경우가 많습니다. 그 웹 사이트를보고 동시에 다른 사이트에 액세스 할 수 없기 위해 비공개 모드로 전환해야하는 것은 정말 짜증날 것입니다.
한 가지 할 수있는 일은 쿠키 대신 세션을 사용하여 사이트를 디자인하는 것이므로 저장되지 않습니다 (사용하지 않기 때문에 ...). 그리고 역사에 관해서는 ... 정말로, 그것의 문제는 무엇입니까?
function isPrivate(callback) {
callback || (callback = function(){});
var fs = window.RequestFileSystem || window.webkitRequestFileSystem;
if(fs){
return fs(window.TEMPORARY, 1, callback.bind(this, false), callback.bind(this, true));
}
if(window.indexedDB && /Firefox/.test(window.navigator.userAgent)){
try {
var db = window.indexedDB.open('test');
var tryes = 0;
var interval = limit = 10;
var wait = function(check){
if(tryes >= limit){ return callback(true); } // Give up
return window.setTimeout(check, ++tryes * interval);
}
var evaluate = function(){
return db.readyState === 'done' ? callback(!db.result) : wait(evaluate);
}
return wait(evaluate);
} catch (e) {
return callback(true);
}
}
if (!!window.navigator.userAgent.match(/(MSIE|Trident|Edge)/)){
try {
return callback(!window.indexedDB);
} catch (e) {
return callback(true);
}
}
try {
window.openDatabase(null, null, null, null);
return callback(false);
} catch (e) {
return callback(true);
}
}
isPrivate( function(isPrivate) {
console.log('Private mode ===>', isPrivate);
});
I've solved this issue by using two HTML pages. The main page define a status variable and set a cookie. The second page is opened in a new window (not tab), read the cookie and set status to the cookie value. Under MSIE, the cookie value is passed to the child page when the main page in normal mode. When in InPrivate Browsing mode, the cookie value is not passed to the child page (but is passed if you open a new tab).
The main.html page:
<script>
var myCookie="nocookie";
document.cookie="checkInPrivate=1";
var h=window.open("child.html", "_blank", "left=9999,height=200,width=200");
setTimeout(function() {
var status=null;
if (myCookie=="nocookie") {
status="unable to determine if we are InPrivate Browsing mode (child page did not set the cookie)";
} else if (myCookie.indexOf("checkInPrivate")>=0) {
status="not in InPrivate Browsing mode (child page did set the cookie)";
} else {
status="in InPrivate Browsing mode (child page set the cookie value but it was not provided)";
}
alert(status);
}, 200);
</script>
The child.html page:
Detecting MSIE's InPrivate Browsing mode...
<script>
window.opener.myCookie=document.cookie;
window.close();
</script>
I'm using InPrivate Browsing mode in order to prevent Browser Helper Objects (BHO) and browser extensions to be enabled, since BHO are most often malwares which can modify the web pages even if HTTPS and strong authentication are used. Internet Explorer 9 has a "Disable toolbars and extensions when InPrivate Browsing starts" in its "Privacy" settings.
However, this is not the ultimate way to prevent malicious browser extension: a malicious extension may change the main page behavior to make it think that the myCookie value has not been set and. We would wrongly assume that we are in InPrivate Browsing mode.
Note that I need cookies for my application so I do not use InPrivate Browsing for that purpose.
Write code to achieve following
1) In firefox test browser version. This method works with version >= 33.0 ( supports service workers ). Cannot use this method with old ( < 33.0 ) versions.
2) Try to set service worker. 3) If you can set,use or access a service worker you are 1000% not in private browsing mode as service workers cannot be interacted with on Firefox private browsing mode. I wish that they could be.
Quote:
"In Firefox, Service Worker APIs are hidden and cannot be used when the user is in private browsing mode"
https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers
Not sure if its cause this question is old but Firefox does provide documentation on how to detect private browsing mode. However it involves using an import of theirs DXR PrivateBrowsingUtils:
try {
// Firefox 20+
Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
if (!PrivateBrowsingUtils.isWindowPrivate(window)) {
...
}
} catch(e) {
// pre Firefox 20 (if you do not have access to a doc.
// might use doc.hasAttribute("privatebrowsingmode") then instead)
try {
var inPrivateBrowsing = Components.classes["@mozilla.org/privatebrowsing;1"].
getService(Components.interfaces.nsIPrivateBrowsingService).
privateBrowsingEnabled;
if (!inPrivateBrowsing) {
...
}
} catch(e) {
Components.utils.reportError(e);
return;
}
}
While creating my Safari extension, I found out that it was possible to query the boolean safari.self.browserWindow.activeTab.private. Below worked for me to check whether the browser was open in Private or not but only from the extension.
isPrivate = false;
try {
isPrivate = safari.self.browserWindow.activeTab.private;
} catch (_) {
isPrivate = true;
}
if (isPrivate === true){
console.log("Private window.");}
else {
console.log("Not private window.");}
Source: developer.apple.com | Instance Property private
참고URL : https://stackoverflow.com/questions/2860879/detecting-if-a-browser-is-using-private-browsing-mode
'Program Club' 카테고리의 다른 글
| Room Persistence Library로 생성 된 데이터베이스의 내용보기 (0) | 2020.11.29 |
|---|---|
| Python이 UCS-2 또는 UCS-4로 컴파일되었는지 확인하는 방법은 무엇입니까? (0) | 2020.11.29 |
| 특수 문자와 함께 일괄 에코 사용 (0) | 2020.11.29 |
| 최종 ArrayList의 의미는 무엇입니까? (0) | 2020.11.29 |
| rem은 CSS에서 em과 어떻게 다릅니 까? (0) | 2020.11.29 |