Reference
What the scanner checks
Browse the checks a scan can report and the advisory data used to assess a release. This catalogue describes the scanner’s coverage without scanning an instance.
Checks
Every check, by category
Grouped by what they are about rather than how badly they can fail - severity depends on the instance being scanned, so it is not shown here.
Cookies
-
cookieHttpOnlyAn observed cookie is readable by page scripts
A cookie sent by the public response lacks the HttpOnly attribute.
Fix: Set HttpOnly unless a browser script must deliberately read that cookie. Documentation
-
cookiePrefixAn observed cookie carries no name prefix, or breaks the one it claims
The '__Host-' and '__Secure-' name prefixes are the only cookie protection a browser enforces on the name itself, which is what makes them survive the things the attributes do not: a sibling subdomain, or plain HTTP on the same host, can overwrite an ordinary session cookie however carefully its Secure and HttpOnly flags were set, because neither attribute stops a cookie from being *written*. A '__Host-' cookie may only be set over HTTPS, with Path=/ and no Domain, so nothing but the exact origin can touch it. A cookie that names a prefix without honouring its rules is worse than one that never claimed it: every browser rejects it outright, so the session silently does not work.
Fix: Rename the session cookie to '__Host-<name>' and set it with Secure, Path=/ and no Domain attribute - or '__Secure-<name>' when it genuinely has to be shared across subdomains. Where the cookie comes from a reverse proxy or an identity provider rather than from OpenCloud, rename it there. Documentation
-
cookieSameSiteAn observed cookie has no cross-site policy
A cookie sent by the public response lacks a SameSite attribute.
Fix: Set SameSite=Lax or Strict unless a documented cross-site flow needs None. Documentation
-
cookieSecureAn observed cookie can travel over HTTP
A cookie sent by the public response lacks the Secure attribute.
Fix: Set Secure on every cookie the reverse proxy or application issues. Documentation
Authentication & accounts
-
authenticationA protected endpoint answered without demanding authentication
An endpoint that should require a session returned neither 401, 403 nor a redirect to the login page. Something in front of OpenCloud may be answering the request itself, or the endpoint really is open.
Fix: Request the reported path by hand and see what answers it. A cache or error page in front of OpenCloud is the usual explanation; an endpoint genuinely reachable without a session is an incident. Documentation
-
basicAuthDisabledHTTP Basic authentication is enabled
The instance answers with a 'WWW-Authenticate: Basic' challenge, so usernames and passwords can be replayed on every request without going through the identity provider, bypassing single sign-on and any second factor enforced there. It is often deliberate: CalDAV, CardDAV and WebDAV clients cannot speak OpenID Connect and have nothing else to authenticate with, which is why this counts as a medium finding rather than a serious one - and as a low one when an external identity provider handles the interactive login.
Fix: Set PROXY_ENABLE_BASIC_AUTH=false (the default) if nothing needs it. If calendar, contact or WebDAV clients do, keep it on and give them app tokens rather than account passwords, so that what can be replayed is revocable and never the single sign-on credential. Documentation
-
demoUsersDisabledThe documented demo accounts still sign in
IDM_CREATE_DEMO_USERS populates the built-in identity management with five accounts - dennis, margaret, alan, lynn and mary - whose passwords are published in the OpenCloud documentation, and dennis is an administrator. The scan asked the account endpoint with one of those documented pairs and was let in, so anybody who has read the manual can sign in as well. Nothing was guessed: only the published defaults were sent, and only to the instance's own identity provider.
Fix: Turn the demo users off (IDM_CREATE_DEMO_USERS=false) and delete the accounts that were already created - switching the setting off does not remove them. Treat the instance as compromised until the administrator account 'dennis' is gone or has a real password. Documentation
-
oidcEndpointsUseHttpsThe identity provider publishes an endpoint on plain HTTP
At least one URL in the discovery document - the issuer, or the authorization, token, userinfo or JWKS endpoint - is an http:// address. Every one of them carries either a credential, an authorization code or the keys tokens are verified against, so a plaintext hop is enough to read or rewrite a sign-in. OpenID Connect requires TLS for these endpoints.
Fix: Publish the provider over HTTPS and set its issuer to the https:// address. An http:// issuer usually means the provider is behind a terminating proxy but has not been told its public URL. Documentation
-
oidcImplicitFlowDisabledThe identity provider still offers the implicit flow
response_types_supported offers a response type that returns a token straight from the authorization endpoint ('token' or 'id_token'), which is the implicit flow. It puts access tokens in the URL fragment, where they reach the browser history, the Referer header and any script on the page; OAuth 2.1 removes it for that reason. Reported only for an external provider: OpenCloud's built-in provider offers these response types and cannot be reconfigured, so the finding would name something its operator cannot change.
Fix: Restrict the client to the authorization code flow. Keycloak's client has Implicit flow and Standard flow as separate switches - leave only Standard on; Authentik and Authelia list the allowed response types or grant types per client. Documentation
-
oidcPkceSupportedThe identity provider does not offer PKCE with S256
The discovery document publishes code_challenge_methods_supported without S256, so the authorization code flow runs without Proof Key for Code Exchange. OpenCloud's desktop, mobile and web clients are public clients that cannot keep a secret, and without PKCE an authorization code intercepted on the redirect - by another app registered for the same loopback port, or out of a proxy log - can be exchanged for tokens by whoever took it. Reported only when the provider publishes the field at all: OpenCloud's built-in provider omits it, and an absent answer is not a failing one.
Fix: Require PKCE with S256 on the provider. In Keycloak the client's Proof Key for Code Exchange setting is S256; in Authentik the client type is public with PKCE required; in Authelia the client carries require_pkce: true and pkce_challenge_method: S256. Documentation
-
oidcSigningAlgorithmStrongID tokens may be signed with a weak or absent algorithm
id_token_signing_alg_values_supported offers 'none' or a symmetric HMAC algorithm (HS256 and its siblings). 'none' means an unsigned ID token is acceptable, so anybody can write one. An HMAC algorithm signs with the client secret rather than a private key, so every party holding that secret - including a public client that cannot keep it - can forge a token for any user. OpenCloud's built-in provider signs with PS256 and passes this.
Fix: Offer only asymmetric signing algorithms (RS256, PS256, ES256 or EdDSA) for ID tokens and remove 'none' and the HS family from the provider's list. Documentation
-
passwordPolicyComplexityThe password policy no longer requires mixed characters
OpenCloud requires at least one lowercase letter, one uppercase letter, one digit and one special character in a public link password by default. The capabilities document reports at least one of those minimums as zero, so somebody lowered it - a twelve-character policy that accepts 'aaaaaaaaaaaa' is a length requirement rather than a password policy. Reported only when the instance publishes the minimums at all, which a disabled policy does not: that case is passwordPolicyEnforced's.
Fix: Set OC_PASSWORD_POLICY_MIN_LOWERCASE_CHARACTERS, OC_PASSWORD_POLICY_MIN_UPPERCASE_CHARACTERS, OC_PASSWORD_POLICY_MIN_DIGITS and OC_PASSWORD_POLICY_MIN_SPECIAL_CHARACTERS back to 1 or more. Each defaults to 1, so an instance that fails this had them lowered deliberately. Documentation
-
passwordPolicyEnforcedThe password policy is disabled or allows short passwords
The public capabilities show that the policy is disabled or its minimum length is below 8 characters. This governs public link passwords, not identity-provider account passwords.
Fix: Set OC_PASSWORD_POLICY_DISABLED=false and OC_PASSWORD_POLICY_MIN_CHARACTERS to 8 or more (8 is the default). OC_PASSWORD_POLICY_MIN_{LOWERCASE,UPPERCASE,DIGITS,SPECIAL}_CHARACTERS and a banned-password list tighten it further. Documentation
-
userEnumerationRestrictednot configurableAccount search is not restricted to shared groups
User search would let any account enumerate the whole directory. OpenCloud hardcodes this to the restricted state (search limited to group members), so in practice this check passes everywhere.
Fix: Nothing to change - OpenCloud offers no setting for this and already restricts the search. Documentation
Sharing & links
-
publicLinkExpirationEnforcednot configurablePublic links do not expire automatically (not configurable)
OpenCloud reports 'files_sharing.public.expire_date.enabled' as a hardcoded false in the frontend service: it is a constant, not a setting. Every instance reports it, so this says nothing about how this particular server is configured.
Fix: Nothing to change - OpenCloud offers no setting for this. If public links must expire, the expiry has to be set per share, or the link lifetime governed outside OpenCloud. Documentation
-
publicLinkPasswordEnforcedPublic links can be created without a password
At least one kind of public link - read-only, upload-only or editable - may be shared without a password, so anyone holding the URL has the data. OpenCloud enforces a password on read-only links by default but not on writable ones, which is the usual reason this check fails.
Fix: Set OC_SHARING_PUBLIC_SHARE_MUST_HAVE_PASSWORD=true and OC_SHARING_PUBLIC_WRITEABLE_SHARE_MUST_HAVE_PASSWORD=true. Prefer these global names over the deprecated FRONTEND_OCS_* forms. Documentation
Network exposure
-
backendPortClosedThe direct OpenCloud backend port is publicly reachable
Port 9200 serves the same OpenCloud instance as the public address. When a reverse proxy fronts OpenCloud, publishing that listener lets clients bypass the proxy's TLS and security policy.
Fix: Remove the public port mapping for 9200 and bind the backend to loopback or the private container network. Let only the reverse proxy reach it. Documentation
-
companionAdminConsoleThe collaboration backend's admin console is publicly reachable
A document collaboration backend is published on this instance's own origin, and its administration console answers from the internet. That console lists every open document session and the users in them, reports the server's own configuration, and can terminate sessions - and it is guarded by nothing but a single shared password that has no rate limiting in front of it.
Fix: Block the console's path at the reverse proxy that publishes the collaboration backend, so only the editor's own paths are served to the internet. Leaving it reachable and setting a password is the weaker of the two fixes, because the password is one credential protecting every document session on the server. Documentation
-
corsOriginRestrictedCross-origin requests are accepted from any site
The instance answered a request carrying an arbitrary Origin with an Access-Control-Allow-Origin that permits it. When Access-Control-Allow-Credentials is also true, any page on the internet can make a visitor's browser send its OpenCloud session cookie to this instance and then read the reply - the whole file listing, the user directory, the contents of a share - with no interaction beyond visiting that page. This is OpenCloud's shipped default rather than a mistake somebody made: OC_CORS_ALLOW_ORIGINS defaults to '*' and OC_CORS_ALLOW_CREDENTIALS to true, and a middleware asked for both commonly reflects the requesting origin back, which is exactly the combination browsers were meant to forbid.
Fix: Set OC_CORS_ALLOW_ORIGINS to the exact origins that must reach the API - the web interface's own origin, and any office or client application deliberately hosted elsewhere - rather than leaving it at '*'. Set OC_CORS_ALLOW_CREDENTIALS=false unless one of those origins genuinely needs to send the session. The per-service forms (GRAPH_CORS_ALLOW_ORIGINS, OCS_CORS_ALLOW_ORIGINS, and so on) override the shared name where one service needs a wider list. Documentation
-
debugEndpointA debug endpoint is publicly readable
A service debug path answered on the public address. Those endpoints expose Prometheus metrics, a configuration dump and, when pprof is on, the ability to make the process profile itself.
Fix: Do not proxy /debug paths to the public address, and leave the debug services bound to 127.0.0.1 as they are by default (OC_DEBUG_ADDR and the per-service *_DEBUG_ADDR variables). Documentation
-
debugPortA service debug port is reachable
One of OpenCloud's per-service debug listeners accepted a connection from outside. They are bound to 127.0.0.1 by default, so reaching one means it was published - by a container port mapping, as a rule.
Fix: Remove the port mapping that publishes it and leave the debug listeners on 127.0.0.1. If a metrics scraper needs them, reach them over the internal network rather than the public address. Documentation
-
directoryListingA web server is serving a directory index
An 'Index of /' page was returned. OpenCloud serves its own assets from the binary and never generates one, so this can only come from a web server pointed at the deployment directory - which then also serves opencloud.yaml, the boltdb files and anything else in it.
Fix: Stop serving the deployment directory as static files. Point the web server at OpenCloud's own address as a reverse proxy instead, and switch directory indexing off (Nginx 'autoindex off', Apache 'Options -Indexes'). Documentation
-
exposedA deployment file is publicly readable
A path that should never be served over HTTP answered with content. These are configuration files, databases and key material: reading them can hand over credentials, tokens or the whole data store.
Fix: Stop serving the deployment directory. Proxy to OpenCloud's own address rather than exposing the filesystem, and confirm each reported path answers 404 afterwards. Treat anything that was readable as disclosed and rotate it. Documentation
-
securityTxtPublishedNo security.txt says how to report a vulnerability
Nothing was served at /.well-known/security.txt, so somebody who finds a flaw in this instance has to guess at an address to send it to. What they guess is usually a public issue tracker, a support form read by nobody in a hurry, or nothing at all - and a report that never arrives is indistinguishable, from the outside, from a report nobody bothered to write.
Fix: Serve a plain-text file at /.well-known/security.txt from the reverse proxy in front of OpenCloud. RFC 9116 requires 'Contact:' and 'Expires:' - a date far enough out that it does not lapse unnoticed, and near enough that a stale file gets replaced - and 'Preferred-Languages:' and 'Policy:' are worth the two extra lines. OpenCloud itself serves no such file on any instance, so this is a deployment decision rather than a setting to switch on. Documentation
-
traceMethodDisabledThe server answers the HTTP TRACE method
TRACE makes the server echo the request back, headers included. Anything the browser attached on the way - the session cookie, an Authorization header, a header a reverse proxy added - comes back inside the response body, where a script that could never read those directly can read them as text. OpenCloud does not implement TRACE, so an instance answering it has a reverse proxy or an application server in front that does.
Fix: Refuse TRACE in whatever fronts the instance: Apache 'TraceEnable off', Nginx returns 405 for it already unless a location was written to pass every method through, and Traefik or Caddy need a rule limiting the methods forwarded upstream. Documentation
Embedding
-
webEmbedDelegatedAuthenticationRestrictedDelegated iframe authentication accepts an unvalidated origin
Delegated authentication is enabled without naming the parent origin allowed to send credentials to the embedded web client.
Fix: Set WEB_OPTION_EMBED_DELEGATE_AUTHENTICATION_ORIGIN to the exact trusted parent origin, or disable delegated authentication. Documentation
-
webEmbedMessageOriginRestrictedEmbedded web messages trust every parent origin
The public web configuration sets the embed message origin to '*'. Any site can then host the web client in a frame and exchange messages with it.
Fix: Set WEB_OPTION_EMBED_MESSAGES_ORIGIN to the exact trusted parent origin, or disable the embed integration. Documentation
Version & lifecycle
-
versionDetectionThe running version could not be determined
status.php returned only the legacy compatibility version, without 'productversion'. Without a real version no advisory can be matched and no release state worked out, so the checks that depend on it are not merely passing - they did not run.
Fix: Check whether something in front of the instance rewrites status.php, and whether the release is old enough not to publish 'productversion' yet. Until it reports one, treat the version part of this report as unknown rather than as good. Documentation
-
versionDisclosureA response header publishes a software version
The Server or X-Powered-By header carries a version number. It is not a vulnerability by itself; it tells whoever is looking which advisories to try first.
Fix: Strip or flatten the header in the reverse proxy - Nginx 'server_tokens off', Apache 'ServerTokens Prod', or unset it outright. Documentation
-
webfingerVersionDisclosureThe webfinger document publishes the exact version
The unauthenticated webfinger response contains the running version. It does not create a vulnerability, but it saves an attacker the work of finding out which advisories apply.
Fix: Strip the version from the webfinger response in the reverse proxy, or accept the disclosure: it only matters while a known advisory is unpatched, so keeping the instance current is the real fix. Documentation
Identity provider & proxy
-
addressParityThe name's addresses do not all serve the same instance
The hostname resolves to several addresses, and they answer with a different release, different security headers or hardening, or still accept the documented demo accounts. Whoever reaches the odd node gets the configuration nobody is watching - a scan that dials the name once sees only whichever address the resolver put first. Reported only when the scan was asked to dial every address; unlike tlsAddressParity, which compares the TLS identity of the two DNS families, this compares what each address serves.
Fix: Roll the same configuration out to every node behind the name, or take the node that lags out of DNS until it has caught up. A node serving an older release needs the upgrade the others already had. Documentation
-
forwardedHostIgnoredThe instance publishes a host name the caller chose
The scan asked for the OpenID Connect discovery document while claiming to have arrived at a host that does not exist, once through the request's own Host header and once through X-Forwarded-Host, and the answer named that host back - as the address it redirected to, or inside the issuer and the endpoints the document publishes. Those URLs are where a client sends the next sign-in, so whoever can choose the host has chosen where an authentication request goes. On its own it misleads only the caller who sent the header; behind a cache it becomes the answer everybody gets, and behind a proxy that forwards a client's own X-Forwarded-Host it is a stranger who chooses. Usually it means the instance was never told its public address and is deriving one from each request instead. When only the Host header comes back, and as the address it redirects to, the answer may not come from the instance at all: a reverse proxy with no default server hands a name it has no site for to whichever site it loaded first for that port - often another application on the same machine - and a redirect written there as 'return 301 https://$host...' names the caller's host back. OC_URL can be set correctly and the finding stays.
Fix: Set OC_URL to the public address of the instance so that every absolute URL is built from it rather than from the request. In whatever is in front, set the forwarded headers from the proxy's own configuration rather than passing the client's through - 'proxy_set_header X-Forwarded-Host $host;' in Nginx, 'RequestHeader set X-Forwarded-Host' in Apache. Then give the proxy an explicit default server that refuses a Host it does not recognise, so no other site answers for it: in Nginx a server block with 'listen 443 ssl default_server;', 'server_name _;', 'ssl_reject_handshake on;' and 'return 444;' (and the same for port 80), in Apache a first <VirtualHost> that answers 421 or 403. A redirect in any other site should name that site's own host rather than $host. To confirm which server answers, request the discovery document with a made-up Host header and compare the certificate and headers with the instance's own. Documentation
-
identityProviderDetectedNo identity provider could be found
The instance publishes no OpenID Connect discovery document at /.well-known/openid-configuration and does not redirect that request anywhere, so the scan cannot tell who issues its tokens. That is usually a proxy not forwarding the well-known path, and occasionally an instance whose sign-in is not configured at all. Nothing is submitted to find this out - only the document and the redirect are read.
Fix: Check how sign-in is set up: OpenCloud ships its own identity provider and can be pointed at an external one such as Keycloak, Authentik or Authelia. If an external provider is already in use, make sure the reverse proxy forwards /.well-known/ to it. Documentation
-
reverseProxyDetectedNo reverse proxy could be detected in front of the instance
Nothing in the response suggests a reverse proxy - no proxy-style Server or Via header. An instance exposed directly has no place to terminate TLS for other services, rate-limit an abusive client, or add a header OpenCloud does not send itself. The detection is deliberately best-effort: Traefik and HAProxy announce nothing by default, so a well-run deployment can land here, which is why this never changes the rating.
Fix: If there is a proxy, nothing needs doing. If there is not, putting Nginx, Traefik, Caddy or HAProxy in front is the usual way to run OpenCloud on a public address. Documentation
Security headers
-
Content-Security-PolicyThe Content-Security-Policy header is missing or too weak
Nothing restricts where scripts, styles and frames may be loaded from.
Fix: OpenCloud ships a policy by default; if it is missing, a proxy stripped it. Documentation
-
Cross-Origin-Embedder-PolicyThe Cross-Origin-Embedder-Policy header is missing or too weak
This origin loads cross-origin subresources without requiring them to opt in, which is the condition that keeps the browser from granting it a process of its own. It is the missing half of Cross-Origin-Opener-Policy: only both together isolate the instance from the Spectre-family side channels either one alone leaves open.
Fix: Send 'Cross-Origin-Embedder-Policy: require-corp', or 'credentialless' where third-party content cannot be changed. Test it before rolling it out: an office or media integration that embeds Collabora, a WOPI host or an avatar from another origin will stop loading unless that origin answers with a Cross-Origin-Resource-Policy of its own. Documentation
-
Cross-Origin-Opener-PolicyThe Cross-Origin-Opener-Policy header is missing or too weak
A window this instance opened, or one that opened it, keeps a handle on this document, which is what side-channel attacks in the Spectre family need to reach data in this origin's process.
Fix: Send 'Cross-Origin-Opener-Policy: same-origin'. Use 'same-origin-allow-popups' if an OpenID Connect or office integration signs in through a popup. Documentation
-
Cross-Origin-Resource-PolicyThe Cross-Origin-Resource-Policy header is missing or too weak
Nothing stops another site from loading this instance's responses as a subresource, so a file, a thumbnail or an avatar can be embedded elsewhere and read there.
Fix: Send 'Cross-Origin-Resource-Policy: same-origin', or 'same-site' when a sibling subdomain has to embed OpenCloud content. Documentation
-
Permissions-PolicyThe Permissions-Policy header is missing or too weak
Nothing restricts which browser features embedded content may use, so a framed document or an injected script can ask for the camera, the microphone or the visitor's location under this origin's name.
Fix: Send 'Permissions-Policy: camera=(), microphone=(), geolocation=()', adding back only what a media or collaboration integration needs. Documentation
-
Referrer-PolicyThe Referrer-Policy header is missing or too weak
Full URLs may leak to third-party sites through the Referer header.
Fix: Send 'Referrer-Policy: no-referrer' or 'strict-origin-when-cross-origin'. Documentation
-
Strict-Transport-SecurityThe Strict-Transport-Security header is missing or too weak
Browsers may fall back to plain HTTP for this host.
Fix: Send 'Strict-Transport-Security: max-age=63072000; includeSubDomains; preload'. Documentation
-
X-Content-Type-OptionsThe X-Content-Type-Options header is missing or too weak
Browsers may guess a response's content type and run it as script.
Fix: Send 'X-Content-Type-Options: nosniff'. Documentation
-
X-Frame-OptionsThe X-Frame-Options header is missing or too weak
The interface may be embedded in a foreign frame and clickjacked.
Fix: Send 'X-Frame-Options: SAMEORIGIN', or a CSP 'frame-ancestors' directive. Documentation
-
X-Permitted-Cross-Domain-PoliciesThe X-Permitted-Cross-Domain-Policies header is missing or too weak
Legacy plugins may request a cross-domain policy from this host.
Fix: Send 'X-Permitted-Cross-Domain-Policies: none'. Documentation
-
X-Robots-TagThe X-Robots-Tag header is missing or too weak
Search engines are not told to leave the instance out of their index.
Fix: Send 'X-Robots-Tag: noindex, nofollow'. Documentation
-
X-XSS-ProtectionThe X-XSS-Protection header is missing or too weak
The legacy XSS filter of older browsers is not switched on.
Fix: Send 'X-XSS-Protection: 1; mode=block'. Modern browsers ignore it. Documentation
-
cspWithoutUnsafeInlineThe Content-Security-Policy allows inline scripts or eval
The script-src directive (or default-src, when script-src is absent) contains 'unsafe-inline' or 'unsafe-eval', which removes most of the protection a CSP gives against cross-site scripting: 'unsafe-inline' lets injected markup or an event handler execute outright, and 'unsafe-eval' lets a gadget already in loaded code turn attacker-controlled input into code via eval() or the Function constructor. Note that 'unsafe-inline' is OpenCloud's shipped default, so an instance failing this check on that keyword alone is not misconfigured - it is unmodified. A policy that pairs 'unsafe-inline' with a nonce or a hash (the standard 'strict-dynamic' rollout pattern) does not fail this check: every browser that understands nonces ignores 'unsafe-inline' in that case, so the keyword is only a fallback for browsers old enough to ignore the nonce too.
Fix: Point PROXY_CSP_CONFIG_FILE_LOCATION at a csp.yaml without 'unsafe-inline' or 'unsafe-eval' (or PROXY_CSP_CONFIG_FILE_OVERRIDE_LOCATION to replace the default outright) - or, to keep supporting older browsers, move to a nonce- or hash-based policy with 'strict-dynamic' instead of dropping 'unsafe-inline' outright. Test it first: the web interface currently relies on inline scripts and styles, so a strict policy is likely to break the UI and any connected office or IDP service. Documentation
Transport & TLS
-
companionEditorHttpsThe collaboration backend loads its editor over plain HTTP
The WOPI discovery document published on this origin advertises editor addresses that are not HTTPS. Documents opened through them travel unencrypted, along with the access token that authorises the session - and a browser on an HTTPS page blocks the frame as mixed content, so the editor does not load at all.
Fix: Serve the collaboration backend over HTTPS and configure it with its public HTTPS address, so the addresses it advertises in /hosting/discovery match how a browser actually reaches it. Documentation
-
hstsLongMaxAgeStrict-Transport-Security has a short max-age
The HSTS max-age is under a year, so a browser stops enforcing HTTPS for this host sooner than it should. OpenCloud's own proxy sends ten years, so a short value means something in front of it - a reverse proxy or CDN - is rewriting the header.
Fix: OpenCloud has no setting for this; the header is fixed in the proxy service. Fix the reverse proxy in front of OpenCloud, or let OpenCloud's header through unmodified. Documentation
-
hstsPreloadStrict-Transport-Security has no preload directive
Without 'preload' the host cannot enter the browser preload list, so the very first request to it is still unprotected. OpenCloud's proxy sets the directive itself, so its absence points at a reverse proxy rewriting the header.
Fix: OpenCloud has no setting for this; fix the reverse proxy in front of it. Only add preload once every subdomain is HTTPS-only - the list is slow to leave. Documentation
-
hstsPreloadEligibleThe preload directive would be rejected by the preload list
'preload' is a request, not a state: it asks to be added to the list of hosts browsers force onto HTTPS before ever contacting them, and the list only accepts a header carrying a max-age of at least one year, 'includeSubDomains' and 'preload' together. OpenCloud's own proxy sends a ten-year max-age and 'preload' but no 'includeSubDomains', so the header on a stock instance asks for something the list refuses - which is a fact about OpenCloud rather than about this deployment, and why it is reported here and never counted. The instance is no less secure for it; it is simply not preloaded, however the header reads.
Fix: Add 'includeSubDomains' in the reverse proxy in front of OpenCloud, so the header reads 'max-age=63072000; includeSubDomains; preload', and then submit the domain at hstspreload.org - being accepted takes both. Confirm every subdomain is HTTPS-only first: 'includeSubDomains' commits all of them, and the list is slow to leave. Documentation
-
httpsAvailableThe instance is only reachable over plain HTTP
HTTPS could not be used at all, so the scan fell back to http://. Credentials, session cookies and every file travel unencrypted and can be read or altered by anything on the path.
Fix: Terminate TLS in front of OpenCloud and serve the instance over HTTPS only. Nothing else on this report matters as much. Documentation
-
httpsEnforcedPlain HTTP is not redirected to HTTPS
The instance answers on http:// without redirecting, so a client that omits the scheme can be served - and credentials or session cookies sent - over an unencrypted connection.
Fix: Redirect every http:// request to https:// in the reverse proxy, or stop serving plain HTTP entirely. Documentation
-
tlsAddressParityIPv4 and IPv6 do not present the same TLS service
The hostname publishes both address families, but their TLS endpoints differ or one cannot complete a handshake. Visitors may reach either address, so an old IPv6 listener can bypass the TLS configuration maintained on IPv4.
Fix: Deploy the same TLS terminator configuration and certificate on both address families, or remove the stale DNS record until it is ready. Documentation
-
tlsCaaRecordNo CAA record restricts who may issue a certificate
The domain has no CAA (Certification Authority Authorization) record naming an 'issue' or 'issuewild' property, so any publicly trusted certificate authority can be asked to issue a certificate for it - not just the one actually used. This checks only the exact name scanned, not the RFC 8659 parent-domain fallback chain, and it never judges which CA a record names, only whether one restricts issuance at all.
Fix: Add a CAA record at the DNS zone naming the certificate authority already in use, e.g. 'example.com. CAA 0 issue "letsencrypt.org"'. This is a DNS change at the domain's own zone, not an OpenCloud setting. Documentation
-
tlsCertificateThe certificate expires soon, or has expired
The remaining validity is below the configured threshold (--tls-min-days, 14 by default). An expired certificate stops clients dead, and unlike most findings this one has a date on it: it will fail whether or not anybody acts.
Fix: Renew the certificate, and fix the renewal rather than the certificate: an automated issuer that has stopped renewing is the usual cause. Check that the reload after renewal actually reaches the process serving TLS. Documentation
-
tlsCertificateLifetimeThe certificate was issued for an unusually long time
Its validity period is longer than the 398 days the CA/Browser Forum allows for publicly trusted certificates, which points at a private authority or a hand-made certificate. The risk is the key: a certificate valid for years stays valid for years after the key behind it leaks, and nothing forces the rotation that would otherwise happen on its own.
Fix: Move to short-lived, automatically renewed certificates. If a private authority has to stay, shorten its validity period and automate the renewal rather than lengthening the certificate to avoid the work. Documentation
-
tlsCertificatePolicyThe certificate uses a weak key or signature
The presented certificate has an RSA key below 2048 bits, an EC key below 256 bits, or an MD5/SHA-1 signature. Those parameters are no longer an adequate protection for an internet-facing certificate, even if the certificate has not expired.
Fix: Issue a replacement certificate with at least a 2048-bit RSA key or a 256-bit EC key and a SHA-256-or-stronger signature. Update the issuing CA template as well, so the next renewal does not restore the weak parameters. Documentation
-
tlsCertificateTransparencyThe certificate carries no Certificate Transparency proof
No signed certificate timestamps are embedded in the certificate, so it was never published to a Certificate Transparency log. Chrome and Safari refuse a publicly trusted certificate without them outright - this is an outage waiting for the next browser release, not only a transparency gap. The logs are also what lets a domain owner find out that somebody else was issued a certificate for their name; a certificate outside them cannot be noticed that way. Only checked for a certificate that chains to a public root: a private or self-signed CA cannot log anything and is not expected to.
Fix: Reissue through a certificate authority that embeds signed certificate timestamps - every public one has done so for years, Let's Encrypt included. A certificate that lacks them was almost certainly issued by a private CA that is nonetheless in the client trust store. Documentation
-
tlsChainThe server does not send a complete certificate chain
The certificates the server sent do not reach a root in the public trust store. An intermediate is missing, or the issuing authority is private. This is the classic finding that looks fine in a desktop browser - browsers cache intermediates they have seen elsewhere and fetch missing ones - and fails on mobile clients, command-line tools and anything doing machine-to-machine calls.
Fix: Serve the full chain: the leaf certificate followed by every intermediate, in order, and without the root. Most issuers publish a 'fullchain' file for exactly this. Documentation
-
tlsCipherSuiteThe negotiated TLS cipher suite is weak
The TLS connection completed with a cipher suite that uses a legacy primitive or does not provide forward secrecy. A modern protocol version alone does not protect a connection whose normal cipher selection is weak. This finding judges the suite this scan actually negotiated; it does not claim to enumerate every suite the server might offer.
Fix: Configure the TLS terminator to use TLS 1.2+ cipher suites with AEAD encryption and ephemeral ECDHE or DHE key exchange, then reload it. Remove NULL, RC4, DES/3DES, MD5, SHA-1 and static-RSA suites rather than merely preferring stronger ones. Documentation
-
tlsDeprecatedProtocolTLS 1.0 or TLS 1.1 is still accepted
The server negotiated a current protocol with this scan and then completed a second handshake pinned to a deprecated one, so both are on offer. The version a modern browser gets says nothing about the version an attacker can force: it is the oldest version accepted that decides what the transport is worth. RFC 8996 deprecated TLS 1.0 and 1.1 in 2021, and both carry cipher suites with no modern replacement.
Fix: Set the minimum protocol version to TLS 1.2 in whatever terminates TLS and reload it. Preferring newer versions is not enough - the old ones have to be removed from the offered set. Documentation
-
tlsDnssecThe zone answering for this name is not signed
Everything else measured about the transport starts from an address a resolver handed over. Without DNSSEC that answer carries no signature, so one forged on the way to the resolver cannot be told apart from the real one - and the CAA record restricting who may issue a certificate for this name can be forged along with the address it protects. Reported only when the resolver used demonstrably understands DNSSEC; when it does not, the finding is left out rather than guessed at.
Fix: Sign the zone at the DNS provider and publish the resulting DS record at the parent zone - an unsigned delegation leaves a signed zone unprotected. This is a change at the domain's own zone, not an OpenCloud setting. Documentation
-
tlsEarlyDataThe server accepts TLS 1.3 early data
The session tickets this server issues permit early data, so a resuming client may send its first request in the 0-RTT flight. That flight has no replay protection at the TLS layer by design: anyone who can record it can send it again, and the server cannot tell the copy from the original. For a file service that is a request to move, copy or delete replayed at a moment of somebody else's choosing. It is a low finding because exploiting it needs a network position, and because a correct server restricts 0-RTT to idempotent requests - but nothing on the wire proves it does.
Fix: Switch early data off in whatever terminates TLS (Nginx 'ssl_early_data off', the default; Caddy and Traefik do not enable it), unless a measured latency problem justifies it and the application is known to reject replayed non-idempotent requests. Documentation
-
tlsHandshakeThe TLS handshake failed
No TLS connection could be established at all, even with certificate verification switched off. Everything the scan says about the transport below rests on a connection that was never made, so the instance is either not serving TLS on this port or is serving something the client could not negotiate.
Fix: Check that the port really terminates TLS, that the certificate and key load, and that the server offers a protocol version and cipher suite a current client accepts. Documentation
-
tlsHostnameThe certificate does not cover the name it is served for
No subject alternative name in the certificate matches the host that was scanned - a certificate for a different domain, for 'localhost', or one with no alternative names at all, which every client has rejected for years. Clients cannot tell this apart from an interception, so they are right to refuse the connection.
Fix: Issue the certificate for the name users actually type, including every alias the instance answers to, and put each of them in the subject alternative name extension rather than only in the common name. Documentation
-
tlsOcspStaplingNo OCSP response is stapled to the handshake
The certificate names an OCSP responder, so revocation can be checked - but the server does not attach the answer to the handshake. Each client then has to ask the authority itself, which tells that authority who visits this instance and, when it is slow or unreachable, is usually skipped rather than treated as a failure. Stapling makes revocation actually work. It is a low finding because most current authorities, Let's Encrypt among them, no longer publish a responder at all - the check simply does not apply to those certificates.
Fix: Switch on OCSP stapling in whatever terminates TLS and give it a writable cache directory, so a slow responder degrades into a stale answer rather than into none. Documentation
-
tlsProtocolAn outdated TLS protocol version was negotiated
The connection came up on something older than TLS 1.2. TLS 1.0 and 1.1 have been deprecated since 2021 and are refused outright by current browsers, so this both weakens the transport and is on its way to breaking access entirely.
Fix: Set the minimum protocol version to TLS 1.2 - preferably 1.3 - in whatever terminates TLS, and remove the older versions from the offered set rather than merely preferring the newer ones. Documentation
-
tlsTrustedThe certificate chain is not trusted
The certificate does not validate against the public trust store: it is self-signed, issued by an unknown authority, or served without its intermediate certificates. 'opencloud init' generates a self-signed certificate unless real ones are configured, so this is the most common finding on a fresh deployment - and it means every client either sees a warning or has been taught to ignore one.
Fix: Issue a certificate from a public authority - Let's Encrypt through the reverse proxy is the usual route - and serve the full chain, intermediates included. An internal authority is fine as long as it is in the trust store of every client, but it will still fail this check, which is measured from outside. Documentation
Advisories
Known advisories
Every advisory in the database a scan is rated against, refreshed daily from the public feed.
-
GHSA-vf5j-r2hw-2hrwhighOpenCloud Affected by Public Link Exploit
### Impact A security issue was discovered in [Reva](https://github.com/opencloud-eu/reva) that enables a malicious user to bypass the scope validation of a public link. That allows it to access resources outside the scope of a public link. OpenCloud uses Reva as one of its core components and thus it is affected. ### Patches Update to OpenCloud version >= 4.0.3 (stable release) Update to OpenCloud version >= 5.0.2 (rolling release) ### Workarounds If projects are unable to update immediat
Fixed in 4.0.3; Fixed in 5.0.2
-
GHSA-gf4p-7p27-26w7mediumAccess to internal metadata
### Impact _What kind of vulnerability is it? Who is impacted?_ OpenCloud exposes internal metadata folders in the spaces of an authenticated user due to a vulnerability in a sub package (reva). This can lead to unwanted ways of interaction with the data. ### Patches _Has the problem been patched? What versions should users upgrade to?_ Patched versions are stable 4.0.8 and 7.2.0 releases. ### Workarounds _Is there a way for users to fix or remediate the vulnerability without upgr
Fixed in 4.0.8; Fixed in 7.2.0