Abstract teknisk illustration mot en mörk marinblå bakgrund: ett genomskinligt chassi rymmer en stapel av små rundade paneler, och en enda omärkt mörk kanal löper från botten av stapeln rakt genom chassits golv ned i ett lägre, obelyst fack. Vid sidan av kanalen står tre små bleka portar stängda på en hylla, medan kanalen själv passerar mellan dem utan någon port i sin väg. En tunn bärnstensfärgad linje kommer in i chassit från vänster och försvinner in i stapeln. Ingen text, inga människor, inga organisationslogotyper, ingen bokstavlig avbildning av något verkligt system.
AI Safety Incidents

MaxKB kopplade ett Shell-verktyg till varje verktygsaktiverad assistent och begränsade det aldrig

Författare

Alistair Wren

Publiceringsdatum

Senaste modellerna · 20Visa alla modeller →
Benchmarks: Artificial Analysis · uppdateras dagligen
Tillbaka till alla inlägg

MaxKB, en öppen källkodsplattform för företagsassistenter som publiceras under GitHub-organisationen 1Panel-dev, byggde sina chattagenter på ett ramverk som tyst lägger till ett shell-verktyg närhelst en backend med shell-stöd skickas in – och MaxKB tog aldrig bort verktyget eller bad någon godkänna dess användning. Sårbarheten är CVE-2026-77521, publicerad som GitHub-säkerhetsrådgivning GHSA-f36j-f34j-h3rx den 2 september 2026 och fick 10,0 av 10 enligt CVSS 3.1 för fallet med en offentlig eller inbäddad assistent. Lasso Security, som hittade och rapporterade den, visade att ett chattmeddelande – eller text som assistenten enbart tar in via hämtning eller ett uppladdat dokument – kunde få modellen att köra kommandon: på en bare metal-driftsättning direkt på värden, och på den officiella containern genom en wrapper som forskarna säger kan kringgås med ett semikolon. Ingen citerad källa registrerar att sårbarheten har utnyttjats i det vilda. Postens egen allvarlighetsgrad, konfidensbedömning och källförteckning finns i AI-incidentarkivet, tillsammans med de närliggande MaxKB- och agentverktygsposterna från samma avslöjandebatch.

MaxKB är en självhostad produkt för att bygga retrieval-augmenterade assistenter: en operatör skapar en assistent, kopplar funktioner till den – verktyg, Model Context Protocol-servrar, färdigheter, delapplikationer – ansluter en kunskapsbas som byggts från uppladdade dokument eller crawlade webbplatser och exponerar sedan assistenten antingen via en autentiserad konsol eller som en offentlig, inbäddningsbar chattwidget. Den mångsidigheten är exponeringen. Utlösningsvillkoret i säkerhetsrådgivningen är inte en ovanlig konfiguration utan den vanliga: varje assistent med minst en kopplad funktion dirigerar sin chatt genom den påverkade agentvägen, medan en chatt utan kopplade funktioner inte gör det. I Lassos genomgång beskrivs projektet som ett av de mer spridda i sin kategori, och det noteras att MaxKB normalt driftsätts som en multi-tenant-tjänst – vilket placerar ett kommando som körs som applikationsanvändaren under multi-tenant-modellen i stället för inuti en enskild tenants del av den.

Skalverktyget kom med ramverket, inte produkten

MaxKB bygger dessa agenter med LangChains deepagents-bibliotek, låst till version 0.6.11 i projektets pyproject.toml både vid den sårbara taggen och den aktuella. I apps/application/flow/tools.py, på rad 467 i taggen v2.10.3-lts, anropar projektet create_deep_agent med backend inställt på SandboxShellBackend, en MaxKB-underklass som kör kommandon på värden. Enligt säkerhetsmeddelandet injicerar deepagents automatiskt en uppsättning verktyg när en shell-backend skickas på det sättet: execute, ls, read_file, write_file, edit_file, glob och grep. De ingår inte i argumentet tools=list, som endast innehåller operatörens egna verktyg, MCP-verktyg och skill-verktyg. De kan inte tas bort från gränssnittet eller via konfiguration.

MaxKB skickar inte heller excluded_tools, det biblioteksargument som skulle ta bort dem. Rådgivningen är noggrann med varför det spelar roll även som åtgärd: excluded_tools "tar bort verktyget från det modellen får veta, inte från exekveraren". Distinktionen mellan ett verktyg som modellen inte känner till och ett verktyg som inte kan köras är hela den här buggen i miniatyr.

En grind som listar tre verktyg och utelämnar det fjärde

Human-in-the-loop-kontrollen i samma anrop är en rad, och den räknar upp tre operationer: interrupt_on={"write_file": False, "read_file": False, "edit_file": False}. Att skriva en fil, läsa en fil och redigera en fil namnges. Kommandoexekvering är inte ens en nyckel i ordboken. Enligt rådgivningens tolkning innebär det att inget godkännande söks för execute – de tre filsystemoperationerna namnges och ställs uttryckligen in för att inte avbryta, och skalverktyget namnges inte alls.

Sammantaget är vägen: obetrodd text når modellen, modellen anropar execute och kommandot körs. Rådgivningen anger två sätt för obetrodd text att komma in. Den direkta är chatt – en offentlig eller inbäddad widget, eller en annan tenants konversation. Den indirekta är innehåll som assistenten tar in: ett RAG-dokument, en uppladdad fil eller en webbsida som plattformen crawlar in i en kunskapsbas. Lassos inlägg konkretiserar den andra vägen och konstaterar att "uppsättningen människor som kan placera text framför modellen är större än uppsättningen människor som kan chatta med den".

På en bare-metal-installation är kommandot bara ett kommando

Vad MaxKB än gör för inneslutning sker det i apps/application/flow/backend/sandbox_shell.py, och i v2.10.3-lts börjar det med ett standardvärde. Rad 9 lyder _enable_sandbox = bool(int(CONFIG.get("SANDBOX", 0))), och SANDBOX förekommer inte i Config.defaults i apps/maxkb/conf.py. Utan en explicit MAXKB_SANDBOX-inställning är värdet noll, wrapper-grenen på rad 65 hoppas över, och execute når subprocess.run med shell=True direkt på värden, som användaren som kör tjänsten – root, enligt rådgivningens formulering, om tjänsten körs som root.

Det är den konfiguration som forskarna använde för sitt proof of concept mot värden. De körde MaxKB:s riktiga kod från källan med MAXKB_SANDBOX osatt, skapade en assistent med ett verktyg kopplat och bad den i ett enda chattmeddelande att köra kommandon för systeminformation. Execute-verktyget utlöstes och skrev en fil vars innehåll var värdens egen utdata från uname, id och sw_vers – utdata som, enligt rådgivningen, bekräftades saknas i någon container. Lasso noterar också gränsen för vad som stoppade det: en uppenbart namngiven proof-fil avvisades av modellen, medan godartad operativ formulering inte avvisades. Modelljustering är, med deras ord, "ett partiellt fartgupp, inte en kontroll".

På den officiella avbildningen kördes sandlådan och läckte ändå.

Den officiella containern sätter MAXKB_SANDBOX=1 i basavbildningen, på rad 48 i installer/Dockerfile-base, så wrappern är aktiv där – och wrappern är den andra bristen. Den byggde en enda sträng: env -i LD_PRELOAD=/opt/maxkb-app/sandbox/lib/sandbox.so följt av gosu sandbox och sedan det modellgenererade kommandot, som lämnades till ett skal som kördes som root. Eftersom kommandot interpolerades som text låg bara dess första token under gosu. Varje semikolon, pipe, omdirigering eller kommandosubstitution i modellens utdata utvärderades av det yttre root-skalet innan sandlådan någonsin såg det.

Lassos rapport visar hur det fungerar i praktiken: en payload med env -i LD_PRELOAD=... PATH="$PATH" gosu sandbox ls; whoami; id, där ls är instängd, whoami inte är det, och allt efter det körs fritt. I tester skrev forskarna en rootägd fil med en omdirigering medan det inre kommando som kördes i sandlådan blockerades. Ovanpå det innehåller varken installer/Dockerfile eller installer/Dockerfile-base något USER-direktiv, så applikationsimagen körs som UID 0 — rådgivningen rapporterar att root bekräftats vid körning. Containern körde därför kommandon ändå, och sandlådan avgjorde bara vilka som kosmetiskt tillskrevs den lågprivilegierade användaren.

Det fullständiga attackflöde som Lasso beskriver kräver ingen åtkomst till målet alls. Angriparen lägger kommandon på en webbsida, väntar på att offrets agent ska crawla in sidan i en kunskapsbas, och offret ställer sedan en vanlig fråga. Svaret kommer tillbaka korrekt och legitimt; det injicerade curl-anropet har redan avfyrats mot angriparens server. Rådgivningsdokumentet noterar att forskarna endast testade sina egna distributioner, inte någon tredjeparts- eller hostad MaxKB-instans.

Vad källorna fastställer, och vad som helt enkelt inte mäts

Mekanismen, de två driftsättningslägena, tillskrivningen och den åtgärdade versionen stämmer överens i fyra dokument: GitHub-rådgivningen, NVD-posten som publicerades den 21 september 2026, Lassos egen tekniska redogörelse från den 10 september 2026 och GBHackers rapport från den 22 september 2026, som är den enda oberoende mediebevakningen som hittats för denna CVE. Ingen källa bestrider någon del av fyndet, och arkivet registrerar posten som obestridd med sin högsta konfidensgrad.

Det källorna inte innehåller är någon mätning av exponering. Det finns inget antal MaxKB-driftsättningar, inget antal internetexponerade eller inbäddade assistenter, inget skanningsresultat, ingen telemetri och inget namngivet offer. Inget i underlaget visar att sårbarheten används mot någon, och CISA:s egen exploateringsbedömning instämmer: SSVC-blocket som bifogats NVD-posten den 22 september 2026 bedömer exploatering som "poc", automatiserbar som "yes" och teknisk påverkan som "total". FIRST:s EPSS-modell satte sannolikheten för exploatering under de kommande 30 dagarna till 1,05 procent, den 64:e percentilen, den 27 oktober 2026, och CVE:n förekommer inte i CISA:s katalog Known Exploited Vulnerabilities daterad den 27 oktober 2026. Arkivets egen gradering återspeglar samma bevis: allvarlighetsgrad hög, verklig skada false.

10.0 förtjänar att dess omfattning anges, eftersom det är den siffra som mest sannolikt kommer att citeras utan sammanhang. Det är poängen för fallet med den publika eller inbäddade assistenten, där CVSS-vektorn lyder AV:N/AC:L/PR:N/UI:N/S:C — nåbar över nätverk, inga privilegier, ingen användarinteraktion, med en omfattningsändring eftersom ett kommando inuti assistenten går över till värdoperativsystemet. Poängen är CNA:ns, och CNA:n här är GitHubs rådgivningsprogram, vilket också är dit CVE-postens källidentifierare pekar. NVD har samma vektor som sekundärt mått och listar, per den 28 oktober 2026, posten med statusen "Deferred", vilket innebär att NVD har publicerat tilldelarens analys i stället för sin egen.

Rendered two-column card with the kicker 'MAXKB · CVE-2026-77521' and the title 'What the sources establish, and what they do not', subtitled with its sources: GHSA-f36j-f34j-h3rx of 2 September 2026, the NVD record of 21 September 2026, Lasso Security's write-up of 10 September 2026, GBHackers of 22 September 2026, FIRST EPSS, the CISA KEV catalogue and the repository tags. The left column, headed 'Established' in blue, lists eight items: CVSS 3.1 base score 10.0 with the vector AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H for a public or embedded assistant; CWE-78 OS command injection, CWE-250 unnecessary privileges and CWE-749 exposed dangerous method; deepagents 0.6.11 auto-adding execute to any shell backend, with no excluded_tools passed by MaxKB; the approval map covering write_file, read_file and edit_file with execute not a key in it; affected at or below 2.10.3-lts per the advisory and at or below 2.10.4-lts per Lasso Security's write-up; fixed in 2.10.5-lts, published 6 August 2026, 27 days before the advisory; the CISA SSVC assessment of 22 September 2026 with exploitation poc, automatable yes and technical impact total; and EPSS 1.05 percent at the 64th percentile on 27 October 2026 with no listing in the CISA KEV catalogue of that date. The right column, headed 'Not established, or not measured' in amber, lists seven items: no exploitation in the wild recorded by any cited source, with the archive recording real harm as false; no count of affected, exposed or internet-facing deployments; no named victim and no evidence of use in any intrusion; NVD status Deferred, so the 10.0 is the assigner's analysis rather than NVD's; disagreement between the two primary sources on the affected range boundary; the researchers' testing confined to their own deployments; and no detection or triage guidance for either deployment mode. A footer reads 'Card rendered by OrcaRouter. The 10.0 is scored for a public or embedded assistant; the archive grades the record high.' The OrcaRouter logo is composited in the bottom-right corner.

Patchen släpptes en månad innan rådgivningen gjorde det

Kronologin löper baklänges från publiceringen och är den minst intuitiva delen av redogörelsen. Lasso rapporterade sårbarheten privat via GitHubs rådgivningskanal den 8 juli 2026. MaxKB svarade dagen därpå, avgränsade rapporten till den officiella imagen och bad om ett proof of concept i en container; forskarna tillhandahöll detta och sandlådebypasset den 10 juli. En commit med rättelsen, 594f50f2, lades in den 9 juli – en dag efter rapporten – och skrev om sandbox_shell.py så att modellens kommandosträng tolkas först och gosu-prefixet tillämpas på varje enkelt kommando i stället för bara på det första, med varje argumentlista citerad på nytt så att substitution inte kan ta sig ut i föräldraskalet. Lassos redogörelse beskriver ändringen som att gosu-prefixet tillämpas ”på varje enkelt kommando, inte bara det första”.

Versionen som innehåller den, v2.10.5-lts, publicerades den 6 augusti 2026. GitHub-rådgivningen publicerades den 2 september, NVD publicerade CVE:n den 21 september, CISA:s SSVC-block lades till och GBHackers rapporterade den 22 september, och Lassos egen redogörelse dök upp den 10 september – mitt i den sekvensen, inte i början. En operatör som följde release-taggar i stället för rådgivningsflöden hade patchen ungefär fyra veckor innan varningen.

Versionsgränsen förtjänar mer uppmärksamhet än rådgivningen ger den, eftersom de två primära källorna inte stämmer överens och förvaret avgör frågan. Fältet i rådgivningsformuläret anger påverkade versioner som "<= 2.10.3-lts", med en anteckning om att detta verifierades på 2.10.3-lts och att den sårbara vägen "troligen" påverkar alla versioner som bygger agenter på detta sätt. Lassos egen beskrivning anger det påverkade intervallet som "<= 2.10.4-lts". Taggarna bekräftar det bredare intervallet: v2.10.4-lts, som släpptes 16 juli 2026, innehåller samma 75-radiga sandbox_shell.py som v2.10.3-lts, och den omskrivna 311-radiga filen dyker först upp i v2.10.5-lts. En operatör på 2.10.4-lts som bara läste rådgivningens intervall skulle ha dragit slutsatsen att de låg utanför det. Det gjorde de inte.

Rendered vertical timeline card with the kicker 'MAXKB · CVE-2026-77521' and the title 'Reported, fixed, released, disclosed', subtitled that the dates come from Lasso Security's disclosure timeline, the repository's release tags and commit metadata, the NVD record and GBHackers, and that every date is a single day. Ten dated entries run down a single spine: 8 July 2026, reported privately to 1Panel-dev through GitHub's advisory channel; 9 July 2026, fix commit 594f50f2 rewrites sandbox_shell.py and the vendor asks for a container proof of concept; 10 July 2026, the container proof of concept and the sandbox bypass supplied; 16 July 2026, v2.10.4-lts released, still carrying the 75-line unpatched sandbox_shell.py; 6 August 2026, v2.10.5-lts, the fixed release with a 311-line wrapper and gosu applied to every simple command; 2 September 2026, advisory GHSA-f36j-f34j-h3rx published with CVSS 10.0; 10 September 2026, Lasso Security publishes MaxKBypass; 21 September 2026, NVD publishes CVE-2026-77521, with the CISA SSVC added the next day and GBHackers reporting; 15 October 2026, v2.10.7-lts flips the code default SANDBOX from 0 to 1; 22 October 2026, v2.10.8-lts still builds the agent with SandboxShellBackend and still omits execute. A dark band at the foot headed 'The gap' reads that the fixed release preceded the advisory by 27 days, that v2.10.4-lts was released a week after the fix commit and does not contain the fix, and that the execute tool has never been gated because the approval map at v2.10.8-lts still names only write_file, read_file and edit_file. A footer reads 'Card rendered by OrcaRouter.' The OrcaRouter logo is composited in the bottom-right corner.

Vad åtgärden inte gjorde

Det som 2.10.5-lts åtgärdar är wrappern: den bygger inte längre en enda shellsträng som root. Det den inte gör är att åtgärda något hos själva verktyget. En direkt läsning av källkodsarkivet vid taggen v2.10.8-lts, publicerad 22 oktober 2026, visar att agenten fortfarande konstrueras med backend=SandboxShellBackend och att interrupt_on fortfarande har exakt tre nycklar – write_file, read_file och edit_file – utan execute. De två första åtgärdsförslagen i rådgivningen – att som standard bygga på en icke-exekverande backend och att lägga till "execute": True i godkännandekartan – finns inte i den utgåvan.

Rekommendationen om fail-closed kom senare, i v2.10.7-lts, och den har betydelse för det distributionsläge som var sämst ställt. Den offentliggjordes den 15 oktober 2026 och ändrar raden i sandbox_shell.py från CONFIG.get("SANDBOX", 0) till CONFIG.get("SANDBOX", 1). En installation från källkod eller på bare metal som aldrig har angett variabeln har nu wrappern aktiverad som standard i stället för avstängd, vilket är rekommendationen "fail closed vid distributioner utan containrar" i snäv bemärkelse. Rådgivningen efterfrågade mer än så under samma rubrik – att det exekveringsbara flödet vägrar att starta när sandbox-körtiden inte är tillgänglig – och efterfrågade separat att wrapper aldrig ska bygga en kommandosträng för ett root-skal. På containersidan, ett faktum snarare än en rekommendation: varken installer/Dockerfile eller installer/Dockerfile-base har något USER-direktiv vid taggen v2.10.8-lts, så applikationsavbildningen startar fortfarande som root.

Sammantaget är läget i underlaget per den 28 oktober 2026 följande. Den andra halvan av sårbarheten – sandlådan som ett semikolon tog sig ut ur – är stängd, och standardbeteendet med fail-open vid distributioner på värdar är stängt. Den första halvan – ett execute-verktyg som kommer med ett backend-objekt och inte är en nyckel i godkännandekartan – är fortfarande så MaxKB bygger en verktygsaktiverad assistent. Forskarnas eget åtgärdsråd var det snäva: uppgradera till 2.10.5-lts eller senare och kör Docker-versionen med sandlådan aktiverad. GBHackers förmedlade samma instruktion plus en bredare lista för administratörer – inaktivera agent-backends med shell-stöd om inte kodkörning uttryckligen krävs, kräv mänskligt godkännande före varje execute-åtgärd, kör containrar som icke-root och behandla crawlade sidor, RAG-dokument och uppladdningar som obetrodd indata.

Den andra MaxKB-posten från samma septemberbatch

Arkivets andra MaxKB-post från den här batchen är en annan bugg med ett värre slut. CVE-2026-77516, som också publicerades till NVD den 21 september 2026, är ett behörighetskringgående snarare än en kommandoinjektion: från version 2.0.0 till och med 2.9.2 kunde en arbetsrumsmedlem med den lägsta rollen, som uttryckligen nekats åtkomst till ett verktyg via WorkspaceUserResourcePermission, ändå binda det verktygets identifierare via tool_ids, skill_tool_ids eller mcp_tool_ids och köra det via agentens eller arbetsflödets dispatch-väg. Dispatch-vägen tillämpar inte på nytt det per-verktygsbeviljande som de dedikerade verktygsrutterna upprätthåller, och verktygskörning dekrypterar serversidiga init_params, så anroparen får de autentiseringsuppgifter som bärs av verktyget de nekades. Dess poäng är 5.4, och NVD:s beskrivning avslutas med en mening som CVE-2026-77521 inte behöver bära: "Ingen rättad version finns tillgänglig vid tiden för denna granskning."

Kontrasten är det användbara för alla som triagerar paret. Sårbarheten som fick 10,0 hade en rättelse incheckad inom en dag och utgiven en månad innan den publicerades. Sårbarheten som fick 5,4 hade ingen åtgärdad version publicerad vid tiden för dess CVE.

Abstract illustration on a dark navy field: a tall translucent shelf holds a row of small pale gate symbols, and a wide unbroken corridor runs beneath the shelf from left to right with nothing standing in it. At the corridor's midpoint a thin amber line drops down from the shelf above and joins the corridor floor, and a small cluster of glowing key-shaped tokens rests just past the join, out of reach of the gates. No text, no people, no organisation logos, no literal depiction of any real system.

Det som fortfarande är genuint öppet är mindre än poängen antyder och större än en patchnotering antyder. Fyndet ifrågasätts inte, och mekanismen verifierades från början till slut i båda distributionslägena av teamet som hittade den. Exponeringen är helt omätt — ingen har publicerat hur många MaxKB-assistenter som har ett verktyg, hur många av dem som kan nås av en obetrodd part, eller hur många som körs på en värd utan sandlådan — så felets verkliga konsekvens är en funktion av distributionsvanor som ingen citerad källa räknar. Och den del av designen som drev poängen till maxvärdet finns fortfarande kvar i den aktuella versionen: en funktion som kör kommandon, kopplad som standard, som saknas i kartan som först frågar en människa.