[{"data":1,"prerenderedAt":120},["ShallowReactive",2],{"post-extension-ceiling-3-the-incognito-bypass":3,"post-next-extension-ceiling-3-the-incognito-bypass":113,"post-nav-extension-ceiling-3-the-incognito-bypass":114},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"heading":10,"date":11,"minutes":12,"series":13,"part":14,"parts":14,"summary":15,"short":16,"body":17,"_type":107,"_id":108,"_source":109,"_file":110,"_stem":111,"_extension":112},"\u002Fblog\u002Fextension-ceiling-3-the-incognito-bypass","blog",false,"","The extension ceiling, part 3: the incognito bypass","Part 1 needed a missing API. Part 2 needed a signed-in account. This one needs Ctrl+Shift+N. Open an incognito window and every extension the user has not individually allowed in is gone: no content scripts, no webRequest listeners, no DLP.","The incognito bypass","2026-05-28",5,"The extension ceiling",3,"Every extension-based DLP I tested loses sight of the user the moment an incognito window opens. The mechanism, and why policy can't fully close it.","Extensions are off in incognito unless the user opts each one in, and no enterprise policy flips that switch for them. Every extension-based control on the machine is one keyboard shortcut from blind.",{"type":18,"children":19,"toc":101},"root",[20,27,34,39,44,50,80,85,91,96],{"type":21,"tag":22,"props":23,"children":24},"element","p",{},[25],{"type":26,"value":9},"text",{"type":21,"tag":28,"props":29,"children":31},"h2",{"id":30},"the-mechanism",[32],{"type":26,"value":33},"The mechanism",{"type":21,"tag":22,"props":35,"children":36},{},[37],{"type":26,"value":38},"Extensions are disabled in incognito by default. The opt-in is a per-extension toggle, Allow in Incognito on the chrome:\u002F\u002Fextensions page, and it belongs to the user. Force-installing the extension by policy does not flip it. Pinning the version, blocking uninstall, hiding the toolbar icon, none of that flips it either. Chrome's position is the same one from part 1, applied consistently: incognito is a promise made to the user, and silently installing a watcher inside it would break the promise, even for an administrator.",{"type":21,"tag":22,"props":40,"children":41},{},[42],{"type":26,"value":43},"So the coverage of your security product is a user preference. That sentence is worth sitting with during a vendor evaluation, because every extension-based DLP I tested behaves exactly this way, and none of the datasheets mention it.",{"type":21,"tag":28,"props":45,"children":47},{"id":46},"the-obvious-fix-and-what-lines-up-behind-it",[48],{"type":26,"value":49},"The obvious fix, and what lines up behind it",{"type":21,"tag":22,"props":51,"children":52},{},[53,55,62,64,70,72,78],{"type":26,"value":54},"The standard answer is ",{"type":21,"tag":56,"props":57,"children":59},"code",{"className":58},[],[60],{"type":26,"value":61},"IncognitoModeAvailability",{"type":26,"value":63}," set to disabled, kill the feature entirely. It works, and then the gaps queue up behind it. Guest mode needs ",{"type":21,"tag":56,"props":65,"children":67},{"className":66},[],[68],{"type":26,"value":69},"BrowserGuestModeEnabled",{"type":26,"value":71}," set to false, it is a fresh profile with no extensions. Adding new profiles needs ",{"type":21,"tag":56,"props":73,"children":75},{"className":74},[],[76],{"type":26,"value":77},"BrowserAddPersonEnabled",{"type":26,"value":79}," set to false, same reason. And once this browser is fully sealed, the user opens Edge, or Firefox, or the Chrome they unzipped into their home directory, none of which carry your extension at all.",{"type":21,"tag":22,"props":81,"children":82},{},[83],{"type":26,"value":84},"Each closure is real and worth doing. The sum of them is also an admission: the enforcement boundary was never the extension. It was the inventory of browsers you can keep people inside, which is an endpoint problem, not a browser problem, and the extension was never going to solve it.",{"type":21,"tag":28,"props":86,"children":88},{"id":87},"what-it-looks-like-when-you-own-the-browser",[89],{"type":26,"value":90},"What it looks like when you own the browser",{"type":21,"tag":22,"props":92,"children":93},{},[94],{"type":26,"value":95},"A fork does not have an incognito problem, it has an incognito decision. The private window is your code. Policy can state plainly what a corporate session allows: incognito exists and DLP stays active in it, disclosed in the window itself. Or incognito is unavailable for managed profiles. Or it works untouched for personal browsing and corporate sites simply refuse to load in it. Any of those is a defensible design. The difference is that the choice is made by policy and disclosed to the user, instead of being made by a toggle the user controls and the admin cannot even see.",{"type":21,"tag":22,"props":97,"children":98},{},[99],{"type":26,"value":100},"That closes the series. The ceiling is not one missing API, it is a pattern. Pixels in part 1, the sync channel in part 2, the private window here. Extensions are guests, and Chrome is a good host that protects its users from its guests. When the requirement needs the host's keys, the requirement is a browser.",{"title":7,"searchDepth":102,"depth":102,"links":103},2,[104,105,106],{"id":30,"depth":102,"text":33},{"id":46,"depth":102,"text":49},{"id":87,"depth":102,"text":90},"markdown","content:blog:extension-ceiling-3-the-incognito-bypass.md","content","blog\u002Fextension-ceiling-3-the-incognito-bypass.md","blog\u002Fextension-ceiling-3-the-incognito-bypass","md",null,{"newer":113,"older":115},{"_path":116,"title":117,"heading":118,"date":119},"\u002Fblog\u002Fextension-ceiling-2-chrome-sync-and-mdm-scoping","The extension ceiling, part 2: Chrome sync and MDM scoping","Chrome sync and MDM scoping","2026-04-09",1781170135582]