| status | current |
|---|---|
| last_reviewed | 2026-08-22 |
Documenten uit een Nextcloud- of andere WebDAV-server, read-only. Dezelfde Source-adapter als
Drive, Jira en Planning: de pipeline weet niet dat het Nextcloud is.
| Env-var | Verplicht | Beschrijving |
|---|---|---|
NEXTCLOUD_BASE_URL |
ja | https://cloud.organisatie.nl — zonder /remote.php erachter |
NEXTCLOUD_USER |
ja | Gebruikersnaam; bij voorkeur een functioneel account |
NEXTCLOUD_APP_PASSWORD |
ja | App-specifiek wachtwoord, geen gebruikerswachtwoord |
NEXTCLOUD_PATHS |
nee | Eén of meer mappen onder de gebruikersmap. Leeg = de hele map |
In het portaal staan de mappen als losse rijen; de komma is het opslagformaat van de env-var, niet iets dat een auditor intypt.
App-wachtwoord en geen gebruikerswachtwoord. Nextcloud maakt ze aan onder Instellingen →
Beveiliging: per applicatie één credential, apart intrekbaar, zonder toegang tot de
webinterface. Zelfde argument als bij het Google-service-account — de auditcapability hoort
niet aan de sessie van een medewerker te hangen. Op de commandoregel:
php occ user:add-app-password <gebruiker>.
Dezelfde lezers als Drive, uit sources/tekst.py: PDF (pypdf, geen OCR), .docx inclusief
tabellen, .xlsx per blad, .pptx per dia, OpenDocument (.odt, .ods, .odp, .odg), en
text/plain, markdown, HTML en CSV.
Geen Google-native types — die bestaan hier niet.
Op de eerste echte run tegen de canary (2026-08-24) waren 32 van de 168 bestanden ODF, en
alle 32 werden gemeld als "onbekend type": elf .odt, elf .odp, zes .ods en vier .odg.
Op een schijf van een organisatie die LibreOffice gebruikt is dat de hoofdmoot en geen
uitzondering — een bron die een vijfde van zijn schijf niet leest, dekt die schijf niet.
Een ODF-bestand is een zip met content.xml. De lezer is zipfile plus
xml.etree.ElementTree uit de standaardbibliotheek; geen odfpy erbij, want de wandeling is
twintig regels en een dependency is een dependency om te volgen in een repo onder 27001-scope.
Alle vier formaten gaan door dezelfde lezer: het verschil tussen odt en odp zit in de omhulling
(office:text tegen draw:page), niet in waar de tekst staat. Een tabelrij blijft één regel
met tabs ertussen, net als bij .xlsx — cel-per-regel maakt van "A.5.1 | CISO" twee losse
feiten die niet meer bij elkaar horen.
Twee weigeringen, dezelfde als bij de PROPFIND-parser en om dezelfde reden — het bestand komt van een schijf waar iedereen kan uploaden:
| geval | wat er gebeurt |
|---|---|
content.xml bevat een DOCTYPE |
geweigerd; ElementTree blokkeert entity-expansie niet |
uitgepakte content.xml boven 32 MB |
geweigerd; de grens staat op de uitgepakte grootte, want juist een zip-bom is klein |
Een geweigerd of kapot bestand is nooit fataal: protocol_ingest vangt per document en meldt
het met de reden. Een .odg-tekening levert vaak niets op, en dat is een uitkomst en geen
fout — hij wordt gemeld als leeg, net als een gescande PDF.
Waarom gedeelde lezers: het zijn functies van bytes naar tekst en ze raken Drive niet. Een tweede set per bron maakt van "leest het tool xlsx-tabellen?" een vraag met twee antwoorden, die na één wijziging uit elkaar lopen.
Afbeeldingen, video en zip-archieven — met de reden in de melding en meegeteld in de dekking.
Plus drie Nextcloud-eigen mappen, die gemeld worden overgeslagen:
| map | waarom |
|---|---|
trashbin |
verwijderd is verwijderd |
versions |
alleen de huidige versie is bewijs; anders levert één document evenveel bevindingen als het versies heeft |
uploads |
onafgemaakte chunked uploads |
Verborgen bestanden (.-prefix) idem. Bij een nieuwe bron is de verleiding het grootst om "die
map hoort er niet bij" ongezegd te laten; dat is precies wat op 2026-08-18 in Drive is
rechtgezet.
WebDAV, niet de Nextcloud-eigen OCS-API. Dat is een standaard, dus dezelfde adapter werkt tegen
ownCloud, Seafile met WebDAV of een Apache met mod_dav.
Depth: infinity zou de hele boom in één antwoord geven, maar veel servers weigeren dat en waar
het mag is een fout halverwege niet te lokaliseren in een antwoord van megabytes. Recursie per
map dus, net als de Drive-adapter.
Nagemeten op 2026-08-22 met Python 3.12.13 en expat 2.7.3: xml.etree.ElementTree weigert een
klassieke entity-expansie ("billion laughs") niet — een kleine invoer leverde 3000 tekens op,
en dat schaalt door.
De weigering zit daarom in een DOCTYPE-check vóór het parsen, plus een lengtegrens van 32 MB.
Entiteiten vereisen een DTD, en een WebDAV-antwoord heeft er nooit legitiem een. Dat is twee
regels en geen extra afhankelijkheid; defusedxml zou hetzelfde doen met meer oppervlak, en een
pakket toevoegen aan een repo die zelf onder ISO 27001-scope valt is een beslissing.
Het gaat niet om wantrouwen tegen Nextcloud, maar erom dat een gecompromitteerde of verkeerd geconfigureerde server dit proces niet mag laten omvallen.
Zoals bij Drive: gezien, gelezen, en per reden overgeslagen — in het run-record.
gezien = gelezen + overgeslagen klopt altijd. Dat is de rekensom die een auditor maakt, en op
2026-08-22 klopte hij één keer niet: wat de WebDAV-client al oversloeg (verborgen bestanden) werd
in overgeslagen geteld maar niet in gezien.
scripts/preflight.py --component nextcloud, tegen canary-accept/nextcloud (Nextcloud
32.0.13) in het cluster. Die run vond twee fouten die de gestubde tests niet zagen:
- Paden waren relatief aan de opgevraagde map in plaats van aan de DAV-wortel, waardoor de recursie in de verkeerde map zocht en submappen leeg leken.
- Een lege
.txtkreeg de melding "mogelijk staat de inhoud in tekstvakken" — over een bestand van nul bytes. De reden hangt nu af van het formaat.
Let op bij testen tegen de canary: canary.accept.commonground.nu wijst in DNS naar de
nginx-ingress (81.24.6.82), terwijl de HTTPRoute aan de Envoy-gateway (81.24.11.239) hangt. Een
kubectl port-forward svc/nextcloud 18080:8080 omzeilt dat; het is een vraag aan de beheerder
van die namespace, niet iets om omheen te bouwen.