[{"data":1,"prerenderedAt":1210},["ShallowReactive",2],{"blog-articles-pl":3},[4],{"id":5,"title":6,"author":7,"body":11,"date":1194,"description":1195,"extension":1196,"image":1197,"locale":1198,"meta":1199,"navigation":1200,"path":1201,"seo":1202,"slug":1203,"stem":1204,"tags":1205,"__hash__":1209},"blog\u002Fblog\u002Fclaude-code-sandboxing.md","Claude Code w piaskownicy: jak skonfigurować sandboxing i dlaczego to naprawdę ma znaczenie",{"name":8,"role":9,"avatar":10},"Przemek Kowalczyk","Senior Full Stack Developer","\u002Fandroid-chrome-512x512.png",{"type":12,"value":13,"toc":1169},"minimark",[14,18,23,26,34,42,45,55,58,85,88,138,152,166,170,199,205,208,212,226,236,352,355,457,476,480,487,742,760,764,770,858,871,875,881,948,965,980,984,1016,1019,1023,1026,1031,1034,1038,1041,1045,1052,1060,1069,1073,1076,1080,1083,1087,1090,1094,1097,1101,1104,1108,1111,1113,1117,1120,1123,1165],[15,16,17],"p",{},"Claude Code potrafi czytać Twój kod, wykonywać polecenia w powłoce, łączyć się z serwerami MCP i pushować zmiany do repozytorium. To właśnie czyni go użytecznym agentem — i to samo czyni go atrakcyjnym celem ataku. Poniżej: jak realnie skonfigurować sandbox w Claude Code oraz seria udokumentowanych, prawdziwych przypadków prompt injection, które pokazują, dlaczego warto to zrobić zanim, a nie po incydencie.",[19,20,22],"h2",{"id":21},"dlaczego-sandbox-a-nie-tylko-zaufanie-do-modelu","Dlaczego sandbox, a nie tylko \"zaufanie do modelu\"",[15,24,25],{},"Domyślnie agent kodujący prosi o zgodę na każdą komendę powłoki. To męczące — i prowadzi do tzw. approval fatigue: użytkownik po którejś z kolei prośbie klika \"zatwierdź\" bez czytania. Sandbox odwraca ten model: zamiast pytać za każdym razem, z góry definiujesz granice (które pliki, które domeny), a system operacyjny egzekwuje je na poziomie procesu — niezależnie od tego, co model \"chciał\" zrobić i czy dana komenda robi więcej, niż sugeruje jej nazwa.",[15,27,28,29,33],{},"To rozróżnienie jest kluczowe: reguły uprawnień (permissions) są oceniane ",[30,31,32],"em",{},"przed"," uruchomieniem komendy na podstawie jej treści; sandbox egzekwuje granicę na uruchomionym już procesie, na poziomie jądra systemu. Innymi słowy — nawet jeśli prompt injection nakłoni Claude Code do wykonania złośliwej komendy, sandbox może i tak zablokować faktyczny dostęp do plików czy sieci.",[19,35,37,38],{"id":36},"szybki-start-sandbox","Szybki start: ",[39,40,41],"code",{},"\u002Fsandbox",[15,43,44],{},"Sandbox działa natywnie na macOS (przez wbudowany framework Seatbelt), Linuksie i WSL2 (przez bubblewrap). Natywny Windows nie jest wspierany — tam trzeba uruchomić Claude Code wewnątrz dystrybucji WSL2.",[46,47,52],"pre",{"className":48,"code":50,"language":51},[49],"language-text","\u002Fsandbox\n","text",[39,53,50],{"__ignoreMap":54},"",[15,56,57],{},"Otwiera to panel z trzema zakładkami:",[59,60,61,69,79],"ul",{},[62,63,64,68],"li",{},[65,66,67],"strong",{},"Mode"," — czy sandboksowane komendy mają być auto-zatwierdzane, czy nadal przechodzić przez zwykłe pytania o zgodę",[62,70,71,74,75,78],{},[65,72,73],{},"Overrides"," — czy komendy, które nie dają się uruchomić w sandboksie, mogą \"spaść\" do trybu bez izolacji (",[39,76,77],{},"allowUnsandboxedCommands",")",[62,80,81,84],{},[65,82,83],{},"Config"," — podgląd wynikowej konfiguracji",[15,86,87],{},"Na Linuksie\u002FWSL2 potrzebne są dwa pakiety:",[46,89,93],{"className":90,"code":91,"language":92,"meta":54,"style":54},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","sudo apt-get install bubblewrap socat   # Ubuntu\u002FDebian\nsudo dnf install bubblewrap socat        # Fedora\n","bash",[39,94,95,121],{"__ignoreMap":54},[96,97,100,104,108,111,114,117],"span",{"class":98,"line":99},"line",1,[96,101,103],{"class":102},"sBMFI","sudo",[96,105,107],{"class":106},"sfazB"," apt-get",[96,109,110],{"class":106}," install",[96,112,113],{"class":106}," bubblewrap",[96,115,116],{"class":106}," socat",[96,118,120],{"class":119},"sHwdD","   # Ubuntu\u002FDebian\n",[96,122,124,126,129,131,133,135],{"class":98,"line":123},2,[96,125,103],{"class":102},[96,127,128],{"class":106}," dnf",[96,130,110],{"class":106},[96,132,113],{"class":106},[96,134,116],{"class":106},[96,136,137],{"class":119},"        # Fedora\n",[15,139,140,143,144,147,148,151],{},[39,141,142],{},"bubblewrap"," egzekwuje izolację systemu plików, ",[39,145,146],{},"socat"," przekierowuje ruch sieciowy przez proxy sandboksa. Opcjonalny filtr seccomp (blokujący gniazda Unix) instaluje się przez ",[39,149,150],{},"npm install -g @anthropic-ai\u002Fsandbox-runtime",".",[15,153,154,155,158,159,162,163,151],{},"Wybór trybu w panelu zapisuje się lokalnie, w ",[39,156,157],{},".claude\u002Fsettings.local.json"," (nie trafia do gita). Żeby włączyć sandbox globalnie dla wszystkich projektów, ustaw ",[39,160,161],{},"sandbox.enabled: true"," w ",[39,164,165],{},"~\u002F.claude\u002Fsettings.json",[19,167,169],{"id":168},"dwa-tryby-pracy","Dwa tryby pracy",[15,171,172,175,176,179,180,183,184,187,188,190,191,194,195,198],{},[65,173,174],{},"Auto-allow"," — komendy próbują uruchomić się w sandboksie i są automatycznie dopuszczane, bez pytania. Jeśli komenda potrzebuje dostępu do domeny spoza listy dozwolonych, wraca do zwykłego procesu zatwierdzania. Nawet w tym trybie zawsze obowiązują: jawne reguły odmowy (",[39,177,178],{},"deny","), potwierdzenie dla ",[39,181,182],{},"rm","\u002F",[39,185,186],{},"rmdir"," celujących w ",[39,189,183],{}," lub katalog domowy, oraz reguły ",[39,192,193],{},"ask"," dotyczące konkretnej treści (np. ",[39,196,197],{},"Bash(git push *)",").",[15,200,201,204],{},[65,202,203],{},"Regular permissions"," — wszystkie komendy Bash przechodzą przez zwykły proces zatwierdzania, nawet jeśli działają w sandboksie. Więcej kontroli, więcej klikania.",[15,206,207],{},"W obu trybach granice systemu plików i sieci są identyczne — różnica dotyczy wyłącznie tego, czy trzeba je ręcznie zatwierdzać.",[19,209,211],{"id":210},"konfiguracja-systemu-plików","Konfiguracja systemu plików",[15,213,214,215,218,219,222,223,198],{},"Domyślnie sandboksowane komendy mogą zapisywać wyłącznie do bieżącego katalogu roboczego i katalogu tymczasowego sesji. Odczyt jest szerszy — obejmuje praktycznie cały dysk, poza wyraźnie zablokowanymi ścieżkami (i uwaga: to domyślnie ",[30,216,217],{},"nie"," blokuje odczytu plików takich jak ",[39,220,221],{},"~\u002F.aws\u002Fcredentials"," czy ",[39,224,225],{},"~\u002F.ssh\u002F",[15,227,228,229,222,232,235],{},"Przykład rozszerzenia dostępu zapisu dla narzędzi typu ",[39,230,231],{},"kubectl",[39,233,234],{},"terraform",":",[46,237,241],{"className":238,"code":239,"language":240,"meta":54,"style":54},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"sandbox\": {\n    \"enabled\": true,\n    \"filesystem\": {\n      \"allowWrite\": [\"~\u002F.kube\", \"\u002Ftmp\u002Fbuild\"]\n    }\n  }\n}\n","json",[39,242,243,249,266,282,296,334,340,346],{"__ignoreMap":54},[96,244,245],{"class":98,"line":99},[96,246,248],{"class":247},"sMK4o","{\n",[96,250,251,254,258,261,263],{"class":98,"line":123},[96,252,253],{"class":247},"  \"",[96,255,257],{"class":256},"spNyl","sandbox",[96,259,260],{"class":247},"\"",[96,262,235],{"class":247},[96,264,265],{"class":247}," {\n",[96,267,269,272,275,277,279],{"class":98,"line":268},3,[96,270,271],{"class":247},"    \"",[96,273,274],{"class":102},"enabled",[96,276,260],{"class":247},[96,278,235],{"class":247},[96,280,281],{"class":247}," true,\n",[96,283,285,287,290,292,294],{"class":98,"line":284},4,[96,286,271],{"class":247},[96,288,289],{"class":102},"filesystem",[96,291,260],{"class":247},[96,293,235],{"class":247},[96,295,265],{"class":247},[96,297,299,302,306,308,310,313,315,318,320,323,326,329,331],{"class":98,"line":298},5,[96,300,301],{"class":247},"      \"",[96,303,305],{"class":304},"sbssI","allowWrite",[96,307,260],{"class":247},[96,309,235],{"class":247},[96,311,312],{"class":247}," [",[96,314,260],{"class":247},[96,316,317],{"class":106},"~\u002F.kube",[96,319,260],{"class":247},[96,321,322],{"class":247},",",[96,324,325],{"class":247}," \"",[96,327,328],{"class":106},"\u002Ftmp\u002Fbuild",[96,330,260],{"class":247},[96,332,333],{"class":247},"]\n",[96,335,337],{"class":98,"line":336},6,[96,338,339],{"class":247},"    }\n",[96,341,343],{"class":98,"line":342},7,[96,344,345],{"class":247},"  }\n",[96,347,349],{"class":98,"line":348},8,[96,350,351],{"class":247},"}\n",[15,353,354],{},"Blokowanie odczytu całego katalogu domowego z wyjątkiem projektu:",[46,356,358],{"className":238,"code":357,"language":240,"meta":54,"style":54},"{\n  \"sandbox\": {\n    \"enabled\": true,\n    \"filesystem\": {\n      \"denyRead\": [\"~\u002F\"],\n      \"allowRead\": [\".\"]\n    }\n  }\n}\n",[39,359,360,364,376,388,400,423,444,448,452],{"__ignoreMap":54},[96,361,362],{"class":98,"line":99},[96,363,248],{"class":247},[96,365,366,368,370,372,374],{"class":98,"line":123},[96,367,253],{"class":247},[96,369,257],{"class":256},[96,371,260],{"class":247},[96,373,235],{"class":247},[96,375,265],{"class":247},[96,377,378,380,382,384,386],{"class":98,"line":268},[96,379,271],{"class":247},[96,381,274],{"class":102},[96,383,260],{"class":247},[96,385,235],{"class":247},[96,387,281],{"class":247},[96,389,390,392,394,396,398],{"class":98,"line":284},[96,391,271],{"class":247},[96,393,289],{"class":102},[96,395,260],{"class":247},[96,397,235],{"class":247},[96,399,265],{"class":247},[96,401,402,404,407,409,411,413,415,418,420],{"class":98,"line":298},[96,403,301],{"class":247},[96,405,406],{"class":304},"denyRead",[96,408,260],{"class":247},[96,410,235],{"class":247},[96,412,312],{"class":247},[96,414,260],{"class":247},[96,416,417],{"class":106},"~\u002F",[96,419,260],{"class":247},[96,421,422],{"class":247},"],\n",[96,424,425,427,430,432,434,436,438,440,442],{"class":98,"line":336},[96,426,301],{"class":247},[96,428,429],{"class":304},"allowRead",[96,431,260],{"class":247},[96,433,235],{"class":247},[96,435,312],{"class":247},[96,437,260],{"class":247},[96,439,151],{"class":106},[96,441,260],{"class":247},[96,443,333],{"class":247},[96,445,446],{"class":98,"line":342},[96,447,339],{"class":247},[96,449,450],{"class":98,"line":348},[96,451,345],{"class":247},[96,453,455],{"class":98,"line":454},9,[96,456,351],{"class":247},[15,458,459,460,462,463,465,466,468,469,472,473,475],{},"Zasada rozstrzygania konfliktów: bardziej szczegółowa ścieżka wygrywa. Wąski ",[39,461,429],{}," potrafi \"odsłonić\" fragment szerszego ",[39,464,406],{},", ale dokładny ",[39,467,406],{}," (np. ",[39,470,471],{},"~\u002F.env",") zawsze wygrywa nad szerokim ",[39,474,429],{}," — czyli szeroki allow nie może po cichu odsłonić sekretu.",[19,477,479],{"id":478},"ochrona-danych-uwierzytelniających","Ochrona danych uwierzytelniających",[15,481,482,483,486],{},"Osobny blok ",[39,484,485],{},"sandbox.credentials"," (Claude Code ≥ 2.1.187) pozwala jawnie wskazać pliki i zmienne środowiskowe do ochrony:",[46,488,490],{"className":238,"code":489,"language":240,"meta":54,"style":54},"{\n  \"sandbox\": {\n    \"enabled\": true,\n    \"credentials\": {\n      \"files\": [\n        { \"path\": \"~\u002F.aws\u002Fcredentials\", \"mode\": \"deny\" },\n        { \"path\": \"~\u002F.ssh\", \"mode\": \"deny\" }\n      ],\n      \"envVars\": [\n        { \"name\": \"GITHUB_TOKEN\", \"mode\": \"deny\" },\n        { \"name\": \"NPM_TOKEN\", \"mode\": \"deny\" }\n      ]\n    }\n  }\n}\n",[39,491,492,496,508,520,533,547,588,626,631,644,683,721,727,732,737],{"__ignoreMap":54},[96,493,494],{"class":98,"line":99},[96,495,248],{"class":247},[96,497,498,500,502,504,506],{"class":98,"line":123},[96,499,253],{"class":247},[96,501,257],{"class":256},[96,503,260],{"class":247},[96,505,235],{"class":247},[96,507,265],{"class":247},[96,509,510,512,514,516,518],{"class":98,"line":268},[96,511,271],{"class":247},[96,513,274],{"class":102},[96,515,260],{"class":247},[96,517,235],{"class":247},[96,519,281],{"class":247},[96,521,522,524,527,529,531],{"class":98,"line":284},[96,523,271],{"class":247},[96,525,526],{"class":102},"credentials",[96,528,260],{"class":247},[96,530,235],{"class":247},[96,532,265],{"class":247},[96,534,535,537,540,542,544],{"class":98,"line":298},[96,536,301],{"class":247},[96,538,539],{"class":304},"files",[96,541,260],{"class":247},[96,543,235],{"class":247},[96,545,546],{"class":247}," [\n",[96,548,549,552,554,558,560,562,564,566,568,570,572,575,577,579,581,583,585],{"class":98,"line":336},[96,550,551],{"class":247},"        {",[96,553,325],{"class":247},[96,555,557],{"class":556},"swJcz","path",[96,559,260],{"class":247},[96,561,235],{"class":247},[96,563,325],{"class":247},[96,565,221],{"class":106},[96,567,260],{"class":247},[96,569,322],{"class":247},[96,571,325],{"class":247},[96,573,574],{"class":556},"mode",[96,576,260],{"class":247},[96,578,235],{"class":247},[96,580,325],{"class":247},[96,582,178],{"class":106},[96,584,260],{"class":247},[96,586,587],{"class":247}," },\n",[96,589,590,592,594,596,598,600,602,605,607,609,611,613,615,617,619,621,623],{"class":98,"line":342},[96,591,551],{"class":247},[96,593,325],{"class":247},[96,595,557],{"class":556},[96,597,260],{"class":247},[96,599,235],{"class":247},[96,601,325],{"class":247},[96,603,604],{"class":106},"~\u002F.ssh",[96,606,260],{"class":247},[96,608,322],{"class":247},[96,610,325],{"class":247},[96,612,574],{"class":556},[96,614,260],{"class":247},[96,616,235],{"class":247},[96,618,325],{"class":247},[96,620,178],{"class":106},[96,622,260],{"class":247},[96,624,625],{"class":247}," }\n",[96,627,628],{"class":98,"line":348},[96,629,630],{"class":247},"      ],\n",[96,632,633,635,638,640,642],{"class":98,"line":454},[96,634,301],{"class":247},[96,636,637],{"class":304},"envVars",[96,639,260],{"class":247},[96,641,235],{"class":247},[96,643,546],{"class":247},[96,645,647,649,651,654,656,658,660,663,665,667,669,671,673,675,677,679,681],{"class":98,"line":646},10,[96,648,551],{"class":247},[96,650,325],{"class":247},[96,652,653],{"class":556},"name",[96,655,260],{"class":247},[96,657,235],{"class":247},[96,659,325],{"class":247},[96,661,662],{"class":106},"GITHUB_TOKEN",[96,664,260],{"class":247},[96,666,322],{"class":247},[96,668,325],{"class":247},[96,670,574],{"class":556},[96,672,260],{"class":247},[96,674,235],{"class":247},[96,676,325],{"class":247},[96,678,178],{"class":106},[96,680,260],{"class":247},[96,682,587],{"class":247},[96,684,686,688,690,692,694,696,698,701,703,705,707,709,711,713,715,717,719],{"class":98,"line":685},11,[96,687,551],{"class":247},[96,689,325],{"class":247},[96,691,653],{"class":556},[96,693,260],{"class":247},[96,695,235],{"class":247},[96,697,325],{"class":247},[96,699,700],{"class":106},"NPM_TOKEN",[96,702,260],{"class":247},[96,704,322],{"class":247},[96,706,325],{"class":247},[96,708,574],{"class":556},[96,710,260],{"class":247},[96,712,235],{"class":247},[96,714,325],{"class":247},[96,716,178],{"class":106},[96,718,260],{"class":247},[96,720,625],{"class":247},[96,722,724],{"class":98,"line":723},12,[96,725,726],{"class":247},"      ]\n",[96,728,730],{"class":98,"line":729},13,[96,731,339],{"class":247},[96,733,735],{"class":98,"line":734},14,[96,736,345],{"class":247},[96,738,740],{"class":98,"line":739},15,[96,741,351],{"class":247},[15,743,744,745,748,749,222,752,755,756,759],{},"Ważne: nie ma wbudowanej domyślnej listy sekretów do ochrony — chronione jest tylko to, co jawnie wymienisz. Tryb ",[39,746,747],{},"mask"," (Claude Code ≥ 2.1.199) pozwala zachować działanie narzędzi typu ",[39,750,751],{},"gh",[39,753,754],{},"npm",", podstawiając prawdziwy token dopiero na poziomie proxy sieciowego, tylko dla wskazanych hostów (",[39,757,758],{},"injectHosts",") — sama komenda nigdy nie widzi prawdziwego sekretu.",[19,761,763],{"id":762},"sieć-model-domyślnie-zero-zaufania","Sieć — model \"domyślnie zero zaufania\"",[15,765,766,767,235],{},"Żadna domena nie jest dozwolona domyślnie. Pierwsze użycie nowej domeny wywołuje pytanie o zgodę; można to obejść z góry, wypełniając ",[39,768,769],{},"allowedDomains",[46,771,773],{"className":238,"code":772,"language":240,"meta":54,"style":54},"{\n  \"sandbox\": {\n    \"enabled\": true,\n    \"network\": {\n      \"allowedDomains\": [\"*.github.com\", \"registry.npmjs.org\"]\n    }\n  }\n}\n",[39,774,775,779,791,803,816,846,850,854],{"__ignoreMap":54},[96,776,777],{"class":98,"line":99},[96,778,248],{"class":247},[96,780,781,783,785,787,789],{"class":98,"line":123},[96,782,253],{"class":247},[96,784,257],{"class":256},[96,786,260],{"class":247},[96,788,235],{"class":247},[96,790,265],{"class":247},[96,792,793,795,797,799,801],{"class":98,"line":268},[96,794,271],{"class":247},[96,796,274],{"class":102},[96,798,260],{"class":247},[96,800,235],{"class":247},[96,802,281],{"class":247},[96,804,805,807,810,812,814],{"class":98,"line":284},[96,806,271],{"class":247},[96,808,809],{"class":102},"network",[96,811,260],{"class":247},[96,813,235],{"class":247},[96,815,265],{"class":247},[96,817,818,820,822,824,826,828,830,833,835,837,839,842,844],{"class":98,"line":298},[96,819,301],{"class":247},[96,821,769],{"class":304},[96,823,260],{"class":247},[96,825,235],{"class":247},[96,827,312],{"class":247},[96,829,260],{"class":247},[96,831,832],{"class":106},"*.github.com",[96,834,260],{"class":247},[96,836,322],{"class":247},[96,838,325],{"class":247},[96,840,841],{"class":106},"registry.npmjs.org",[96,843,260],{"class":247},[96,845,333],{"class":247},[96,847,848],{"class":98,"line":336},[96,849,339],{"class":247},[96,851,852],{"class":98,"line":342},[96,853,345],{"class":247},[96,855,856],{"class":98,"line":348},[96,857,351],{"class":247},[15,859,860,863,864,866,867,870],{},[65,861,862],{},"Istotne ograniczenie bezpieczeństwa",": wbudowane proxy domyślnie ",[30,865,217],{}," terminuje ani nie inspekcjonuje ruchu TLS — decyzję o dopuszczeniu podejmuje wyłącznie na podstawie nazwy hosta podanej przez klienta. Oznacza to, że szeroka reguła w stylu ",[39,868,869],{},"github.com"," teoretycznie otwiera drogę do technik takich jak domain fronting. Jeśli model zagrożenia tego wymaga, trzeba skonfigurować własne proxy terminujące TLS.",[19,872,874],{"id":873},"wymuszanie-sandboksa-w-organizacji","Wymuszanie sandboksa w organizacji",[15,876,877,878,880],{},"Dla administratorów — konfiguracja przez managed settings, której deweloperzy nie mogą lokalnie poluzować (dla kluczy logicznych typu ",[39,879,274],{},"):",[46,882,884],{"className":238,"code":883,"language":240,"meta":54,"style":54},"{\n  \"sandbox\": {\n    \"enabled\": true,\n    \"failIfUnavailable\": true,\n    \"allowUnsandboxedCommands\": false\n  }\n}\n",[39,885,886,890,902,914,927,940,944],{"__ignoreMap":54},[96,887,888],{"class":98,"line":99},[96,889,248],{"class":247},[96,891,892,894,896,898,900],{"class":98,"line":123},[96,893,253],{"class":247},[96,895,257],{"class":256},[96,897,260],{"class":247},[96,899,235],{"class":247},[96,901,265],{"class":247},[96,903,904,906,908,910,912],{"class":98,"line":268},[96,905,271],{"class":247},[96,907,274],{"class":102},[96,909,260],{"class":247},[96,911,235],{"class":247},[96,913,281],{"class":247},[96,915,916,918,921,923,925],{"class":98,"line":284},[96,917,271],{"class":247},[96,919,920],{"class":102},"failIfUnavailable",[96,922,260],{"class":247},[96,924,235],{"class":247},[96,926,281],{"class":247},[96,928,929,931,933,935,937],{"class":98,"line":298},[96,930,271],{"class":247},[96,932,77],{"class":102},[96,934,260],{"class":247},[96,936,235],{"class":247},[96,938,939],{"class":247}," false\n",[96,941,942],{"class":98,"line":336},[96,943,345],{"class":247},[96,945,946],{"class":98,"line":342},[96,947,351],{"class":247},[59,949,950,955],{},[62,951,952,954],{},[39,953,920],{}," — brak wymaganej zależności (np. bubblewrap) blokuje start Claude Code zamiast ciche uruchomienie bez izolacji",[62,956,957,960,961,964],{},[39,958,959],{},"allowUnsandboxedCommands: false"," — wyłącza furtkę ",[39,962,963],{},"dangerouslyDisableSandbox",", więc żadna komenda nie może \"uciec\" z sandboksa",[15,966,967,968,971,972,975,976,979],{},"Warto dodać ",[39,969,970],{},"allowManagedDomainsOnly"," i ",[39,973,974],{},"allowManagedReadPathsOnly",", żeby zablokować deweloperom możliwość rozszerzania listy dozwolonych domen\u002Fścieżek lokalnie — pola tablicowe (np. ",[39,977,978],{},"excludedCommands",") domyślnie łączą się ze wszystkich zakresów ustawień, więc deweloper i tak może coś dopisać.",[19,981,983],{"id":982},"czego-sandbox-nie-robi","Czego sandbox NIE robi",[59,985,986,989,996,1002,1013],{},[62,987,988],{},"Obejmuje wyłącznie proces Bash i jego procesy potomne — narzędzia Read\u002FEdit\u002FWrite działają przez osobny system uprawnień",[62,990,991,992,995],{},"Nie jest pełną izolacją: przy ",[39,993,994],{},"enableWeakerNestedSandbox"," (np. w kontenerze bez uprzywilejowanych namespace'ów) izolacja jest wyraźnie słabsza",[62,997,998,1001],{},[39,999,1000],{},"allowAppleEvents"," na macOS usuwa izolację uruchamiania innych aplikacji",[62,1003,1004,1005,1008,1009,1012],{},"Zmienna ",[39,1006,1007],{},"docker.sock"," udostępniona przez ",[39,1010,1011],{},"allowUnixSockets"," praktycznie daje pełny dostęp do hosta",[62,1014,1015],{},"To redukcja ryzyka, nie twierdza nie do zdobycia — dokumentacja Anthropic wprost to podkreśla",[1017,1018],"hr",{},[19,1020,1022],{"id":1021},"realne-przypadki-prompt-injection-z-życia","Realne przypadki prompt injection z życia",[15,1024,1025],{},"Poniżej udokumentowane, publicznie ujawnione incydenty — nie hipotezy z artykułów akademickich, tylko konkretne CVE i raporty badaczy bezpieczeństwa.",[1027,1028,1030],"h3",{"id":1029},"_1-echoleak-microsoft-365-copilot-cve-2025-32711-cvss-93","1. EchoLeak — Microsoft 365 Copilot (CVE-2025-32711, CVSS 9.3)",[15,1032,1033],{},"W czerwcu 2025 badacze Aim Security ujawnili pierwszy udokumentowany atak typu zero-click prompt injection na produkcyjny system AI. Wystarczył jeden spreparowany e-mail, bez żadnej interakcji użytkownika, by Copilot uzyskał dostęp do plików wewnętrznych i przesłał ich zawartość na serwer kontrolowany przez atakującego. Ukryte instrukcje trafiały do modelu podczas rutynowego podsumowywania wiadomości — antywirusy, firewalle i skanowanie statyczne nie miały tu nic do powiedzenia, bo atak działał w naturalnym języku, nie w kodzie.",[1027,1035,1037],{"id":1036},"_2-slack-ai-wyciek-z-prywatnych-kanałów-sierpień-2024","2. Slack AI — wyciek z prywatnych kanałów (sierpień 2024)",[15,1039,1040],{},"Badacze PromptArmor ujawnili lukę w Slack AI, która pozwalała atakującemu wykraść dane z prywatnych kanałów Slacka, do których nie miał dostępu — w tym klucze API udostępnione w prywatnych kanałach deweloperskich — poprzez umieszczenie złośliwej instrukcji na kanale publicznym lub w załączonym dokumencie.",[1027,1042,1044],{"id":1043},"_3-poisoning-claude-code-łańcuch-dostaw-przez-github-action","3. Poisoning Claude Code — łańcuch dostaw przez GitHub Action",[15,1046,1047,1048,1051],{},"W styczniu 2026 badacz RyotaK (GMO Flatt Security) ujawnił krytyczną lukę w ",[39,1049,1050],{},"claude-code-action"," Anthropica. Osiem dni po ujawnieniu, nieznany podmiot wykorzystał niezałataną lukę, by opublikować nieautoryzowane wydanie instalujące agenta OpenClaw na każdym systemie deweloperskim i CI\u002FCD, który zaktualizował Cline CLI. Pakiet pozostawał aktywny przez około osiem godzin, zanim token npm został unieważniony. To jeden z pierwszych w pełni udokumentowanych przypadków kompromitacji własnej infrastruktury dystrybucji narzędzia AI, przeprowadzonej przez agenta, który to narzędzie samo obsługiwało.",[1027,1053,1055,1056,1059],{"id":1054},"_4-wyciek-klucza-api-przez-procselfenviron-w-claude-code-github-action","4. Wyciek klucza API przez ",[39,1057,1058],{},"\u002Fproc\u002Fself\u002Fenviron"," w Claude Code GitHub Action",[15,1061,1062,1063,1065,1066,151],{},"Microsoft Security Blog opisał (czerwiec 2026) atak, w którym prompt injection z publicznego repozytorium (treść issue\u002FPR) skłoniła Claude Code do bezpośredniego odczytu ",[39,1064,1058],{}," narzędziem Read. Zwrócony blob environ zawierał nieoczyszczony klucz ANTHROPIC_API_KEY. Atakujący mógł następnie wykorzystać dowolny kanał eksfiltracji dostępny w danym workflow — kontrolowaną domenę przez WebFetch lub Bash, komentarz w issue przez GitHub MCP, albo log akcji. Anthropic załatało to w Claude Code 2.1.128, blokując dostęp do wrażliwych plików ",[39,1067,1068],{},"\u002Fproc",[1027,1070,1072],{"id":1071},"_5-agentjacking-przez-sentry-atak-na-claude-code-cursor-i-codex-jednocześnie","5. Agentjacking przez Sentry — atak na Claude Code, Cursor i Codex jednocześnie",[15,1074,1075],{},"Ujawniony w czerwcu 2026 przez Tenet Security atak nie wymagał żadnego naruszenia zabezpieczeń. Pojedyncze, spreparowane zdarzenie błędu wysłane przez publiczny klucz uwierzytelniający Sentry — nie wymagający żadnego złamania zabezpieczeń ani autoryzacji — wstrzykiwało instrukcje atakującego do danych o błędzie, które Claude Code, Cursor i Codex następnie wykonywały jako zaufane dane diagnostyczne. Tenet przetestował ponad 100 celów w kontrolowanych warunkach, osiągając 85% skuteczności, a firma zidentyfikowała blisko 2400 organizacji z publicznie wystawionymi danymi uwierzytelniającymi Sentry podatnymi na tę technikę. Sentry określiło tę lukę jako \"technicznie nie do obrony\".",[1027,1077,1079],{"id":1078},"_6-check-point-zdalne-wykonanie-kodu-przez-hooki-w-ustawieniach-repo","6. Check Point — zdalne wykonanie kodu przez hooki w ustawieniach repo",[15,1081,1082],{},"CVE-2025-59536 pozwalało na zdalne wykonanie kodu poprzez złośliwe hooki umieszczone w pliku ustawień repozytorium — kod uruchamiał się jeszcze zanim użytkownik zdążył przeczytać okno dialogowe zaufania. Drugie, CVE-2026-21852, umożliwiało wykradzenie klucza API poprzez nadpisanie jednej zmiennej środowiskowej, przekierowując uwierzytelniony ruch do infrastruktury atakującego jeszcze przed jakimkolwiek promptem zgody. W obu przypadkach samo sklonowanie i otwarcie niezaufanego repozytorium wystarczało, by wyzwolić atak.",[1027,1084,1086],{"id":1085},"_7-claudy-day-inwazyjny-prompt-injection-przez-parametr-url-na-claudeai","7. \"Claudy Day\" — inwazyjny prompt injection przez parametr URL na claude.ai",[15,1088,1089],{},"Badacze Oasis Security opisali w marcu 2026 pełny łańcuch ataku na domyślnej, standardowej sesji claude.ai. Claude.ai pozwala otworzyć nowy czat z wcześniej wypełnionym promptem poprzez parametr URL. Odkryto, że pewne znaczniki HTML dało się osadzić w tym parametrze — niewidoczne w polu tekstowym, ale w pełni przetwarzane przez Claude po naciśnięciu Enter. Atakujący mógł ukryć dowolne instrukcje, łącznie z poleceniami ekstrakcji danych, w tym co wyglądało jak normalny prompt — bez żadnych integracji, narzędzi czy serwerów MCP. Podatność została naprawiona.",[1027,1091,1093],{"id":1092},"_8-perplexity-comet-przeglądarka-agentowa-przejęta-przez-zaproszenie-kalendarzowe","8. Perplexity Comet — przeglądarka agentowa przejęta przez zaproszenie kalendarzowe",[15,1095,1096],{},"Zenity Labs ujawniło, że agentowa przeglądarka Perplexity Comet może zostać przejęta poprzez złośliwe zaproszenie kalendarzowe zawierające ładunek prompt injection, co powodowało dostęp do lokalnego systemu plików, przeglądanie katalogów, otwieranie i odczyt plików oraz eksfiltrację danych. Atak nie wymaga żadnej interakcji użytkownika poza zaakceptowaniem tego, co wygląda na zwyczajne zaproszenie na spotkanie.",[1027,1098,1100],{"id":1099},"_9-microsoft-semantic-kernel-rce-z-dowolnego-wektora-prompt-injection","9. Microsoft Semantic Kernel — RCE z dowolnego wektora prompt injection",[15,1102,1103],{},"Zespół Microsoft Defender Security Research zidentyfikował dwie krytyczne podatności w Semantic Kernel — CVE-2026-26030 (SDK Python) i CVE-2026-25592 (SDK .NET) — gdzie atakujący dysponujący jakimkolwiek wektorem prompt injection mógł osiągnąć zdalne wykonanie kodu na maszynie hostującej agenta.",[1027,1105,1107],{"id":1106},"_10-skala-zjawiska-w-liczbach","10. Skala zjawiska w liczbach",[15,1109,1110],{},"Według raportu CrowdStrike 2026 Global Threat Report, przeciwnicy wstrzykiwali złośliwe prompty do legalnych narzędzi generatywnej AI w ponad 90 organizacjach w 2025 roku, wykorzystując te wstrzyknięcia do generowania poleceń kradnących dane uwierzytelniające i kryptowaluty. Raport podsumowuje to wprost: prompty to nowe malware, a wolumen ataków wspieranych przez AI wzrósł w tym okresie o 89% rok do roku.",[1017,1112],{},[19,1114,1116],{"id":1115},"wnioski-praktyczne","Wnioski praktyczne",[15,1118,1119],{},"Wspólny mianownik tych incydentów: atakujący prawie nigdy nie rozmawia bezpośrednio z modelem. Ładunek trafia przez treść, którą agent i tak musi przetworzyć jako część legalnego zadania — komentarz w kodzie, zgłoszenie błędu, e-mail, zaproszenie kalendarzowe, plik ustawień repozytorium. To właśnie dlatego warstwa OS-level sandboxingu ma sens niezależnie od tego, jak dobrze wytrenowany jest model: sandbox nie próbuje rozpoznać złośliwej instrukcji w treści, tylko ogranicza, co jakakolwiek komenda — złośliwa czy nie — może faktycznie zrobić.",[15,1121,1122],{},"Praktyczny minimalny zestaw działań przy pracy z niezaufaną treścią (obce repozytoria, zewnętrzne issue, dane z MCP):",[1124,1125,1126,1132,1144,1153,1162],"ol",{},[62,1127,1128,1129,1131],{},"Włącz sandbox (",[39,1130,161],{},") i traktuj auto-allow jako domyślny tryb pracy",[62,1133,1134,1135,1137,1138,1141,1142],{},"Jawnie zablokuj odczyt katalogów z sekretami (",[39,1136,604],{},", ",[39,1139,1140],{},"~\u002F.aws",") przez ",[39,1143,485],{},[62,1145,1146,1147,1149,1150,1152],{},"Ogranicz ",[39,1148,769],{}," do konkretnych, zaufanych hostów — unikaj szerokich wildcardów typu ",[39,1151,832],{},", jeśli to możliwe",[62,1154,1155,1156,1158,1159],{},"W CI\u002FCD wyłącz ",[39,1157,77],{}," i ustaw ",[39,1160,1161],{},"failIfUnavailable: true",[62,1163,1164],{},"Audytuj serwery MCP przed instalacją tak samo, jak dowolną zależność npm — pod kątem dostępu do plików, wywołań sieciowych i wstrzykniętych promptów systemowych",[1166,1167,1168],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}",{"title":54,"searchDepth":123,"depth":123,"links":1170},[1171,1172,1174,1175,1176,1177,1178,1179,1180,1193],{"id":21,"depth":123,"text":22},{"id":36,"depth":123,"text":1173},"Szybki start: \u002Fsandbox",{"id":168,"depth":123,"text":169},{"id":210,"depth":123,"text":211},{"id":478,"depth":123,"text":479},{"id":762,"depth":123,"text":763},{"id":873,"depth":123,"text":874},{"id":982,"depth":123,"text":983},{"id":1021,"depth":123,"text":1022,"children":1181},[1182,1183,1184,1185,1187,1188,1189,1190,1191,1192],{"id":1029,"depth":268,"text":1030},{"id":1036,"depth":268,"text":1037},{"id":1043,"depth":268,"text":1044},{"id":1054,"depth":268,"text":1186},"4. Wyciek klucza API przez \u002Fproc\u002Fself\u002Fenviron w Claude Code GitHub Action",{"id":1071,"depth":268,"text":1072},{"id":1078,"depth":268,"text":1079},{"id":1085,"depth":268,"text":1086},{"id":1092,"depth":268,"text":1093},{"id":1099,"depth":268,"text":1100},{"id":1106,"depth":268,"text":1107},{"id":1115,"depth":123,"text":1116},"2026-07-18","Praktyczny przewodnik po sandboxingu w Claude Code oraz rzeczywistych incydentach prompt injection, które pokazują, dlaczego izolacja agentów AI jest niezbędna.","md","\u002Fimages\u002Fblog\u002Fclaude-code-sandboxing.svg","pl",{},true,"\u002Fblog\u002Fclaude-code-sandboxing",{"title":6,"description":1195},"claude-code-sandboxing","blog\u002Fclaude-code-sandboxing",[1206,1207,1208],"Claude Code","Bezpieczeństwo AI","Sandboxing","0ALS959xMyR5v5sTO_3oOCggob4YuoEDmdQ1Ka5rvFs",1784390856262]