AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Nextcloud Core Security

skill-impertio-studio-nextcloud-claude-skill-package-nextcloud-core-security · by Impertio-Studio

>

No reviews yet
0 installs
10 views
0.0% view→install

Install

$ agentstack add skill-impertio-studio-nextcloud-claude-skill-package-nextcloud-core-security

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-impertio-studio-nextcloud-claude-skill-package-nextcloud-core-security)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
1mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Nextcloud Core Security? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

nextcloud-core-security

Quick Reference

Controller Security Defaults

Every controller method enforces ALL of the following unless explicitly overridden with attributes:

| Default | Effect | Override Attribute | |---------|--------|--------------------| | Admin-only | Non-admin users receive HTTP 403 | #[NoAdminRequired] | | Authenticated | Anonymous users redirected to login | #[PublicPage] | | 2FA required | Users without completed 2FA are blocked | #[NoTwoFactorRequired] | | CSRF validated | Request must include CSRF token or OCS-APIRequest: true header | #[NoCSRFRequired] |

ALWAYS start from the default secure posture and relax only what is needed. The default is the most restrictive configuration possible.

Security Attributes (NC 27+)

| Attribute | Effect | Use Case | |-----------|--------|----------| | #[NoAdminRequired] | Allow non-admin authenticated users | Regular user-facing endpoints | | #[PublicPage] | No login required | Public APIs, share pages | | #[NoCSRFRequired] | Skip CSRF token validation | API endpoints using bearer/basic auth | | #[NoTwoFactorRequired] | Bypass 2FA requirement | 2FA setup pages themselves | | #[UserRateLimit(limit: N, period: S)] | Rate limit for logged-in users | Sensitive operations | | #[AnonRateLimit(limit: N, period: S)] | Rate limit for anonymous users | Public endpoints | | #[BruteForceProtection(action: 'name')] | Throttle repeated failures | Login, token validation |

Legacy annotations (pre-NC 27): @NoAdminRequired, @NoCSRFRequired, @PublicPage. ALWAYS use PHP 8 attributes for NC 28+ apps.

Critical Warnings

NEVER assume a controller method without attributes is public -- the default is admin-only, authenticated, 2FA-required, CSRF-validated. Forgetting #[NoAdminRequired] means regular users get HTTP 403.

NEVER combine #[PublicPage] + #[NoCSRFRequired] on state-changing endpoints without additional authentication (bearer token, API key, or OCS-APIRequest: true header). This creates a CSRF vulnerability.

NEVER use #[NoCSRFRequired] on browser-facing form endpoints -- CSRF protection exists to prevent cross-site attacks on session-authenticated users.

NEVER call $response->throttle() on successful attempts -- only on failures. Throttling success slows legitimate users.

NEVER disable brute force protection on authentication endpoints.

NEVER forget to return the $response from afterController() middleware -- the response will be silently lost.


Middleware Chain Architecture

Middleware provides cross-cutting security concerns. The chain follows Django's pattern with four hooks executed in a specific order:

Hook Execution Order

Request arrives
    |
    v
[Middleware 1] beforeController()    (forward order: 1 -> 2 -> 3)
[Middleware 2] beforeController()
[Middleware 3] beforeController()
    |
    v
Controller method executes
    |
    v  (if exception thrown, skip to afterException)
[Middleware 3] afterController()     (reverse order: 3 -> 2 -> 1)
[Middleware 2] afterController()
[Middleware 1] afterController()
    |
    v
[Middleware 3] beforeOutput()        (reverse order: 3 -> 2 -> 1)
[Middleware 2] beforeOutput()
[Middleware 1] beforeOutput()
    |
    v
Response sent

Exception Handling Flow

Exception thrown during controller execution
    |
    v
[Middleware 3] afterException()      (reverse order: 3 -> 2 -> 1)
    |-- if handled (returns Response): continue to afterController chain
    |-- if not handled: propagate to next middleware
[Middleware 2] afterException()
[Middleware 1] afterException()

Hook Signatures

| Hook | Signature | Direction | Purpose | |------|-----------|-----------|---------| | beforeController | ($controller, $methodName) | Forward | Pre-execution checks, auth | | afterException | ($controller, $methodName, $exception): Response | Reverse | Exception recovery | | afterController | ($controller, $methodName, $response): Response | Reverse | Response modification | | beforeOutput | ($controller, $methodName, $output): string | Reverse | Output manipulation |

Middleware Registration

// App-level middleware (runs only for your app's controllers)
public function register(IRegistrationContext $context): void {
    $context->registerMiddleware(MySecurityMiddleware::class);
}

// Global middleware (NC 26+, runs across ALL apps)
$context->registerMiddleware(MonitoringMiddleware::class, true);

ALWAYS register middleware in Application::register(), not in boot(). Middleware must be available before any controller executes.


Content Security Policy

Per-Response CSP

use OCP\AppFramework\Http\ContentSecurityPolicy;

$response = new TemplateResponse('myapp', 'main');
$csp = new ContentSecurityPolicy();
$csp->addAllowedImageDomain('https://images.example.com');
$csp->addAllowedConnectDomain('https://api.example.com');
$response->setContentSecurityPolicy($csp);

Global CSP via Event Listener

Register a listener for AddContentSecurityPolicyEvent to modify CSP across all responses from your app.

CSP Method Overview

| Method | Directive | Default | |--------|-----------|---------| | allowInlineScript(bool) | script-src 'unsafe-inline' | false | | allowInlineStyle(bool) | style-src 'unsafe-inline' | false | | allowEvalScript(bool) | script-src 'unsafe-eval' | false | | useStrictDynamic(bool) | script-src 'strict-dynamic' | true | | addAllowedScriptDomain(string) | script-src | -- | | addAllowedStyleDomain(string) | style-src | -- | | addAllowedFontDomain(string) | font-src | -- | | addAllowedImageDomain(string) | img-src | -- | | addAllowedConnectDomain(string) | connect-src | -- | | addAllowedMediaDomain(string) | media-src | -- | | addAllowedObjectDomain(string) | object-src | -- | | addAllowedFrameDomain(string) | frame-src | -- | | addAllowedChildSrcDomain(string) | child-src | -- |

ALWAYS use the most restrictive CSP possible. Only add domains that your app actually needs.

NEVER use allowInlineScript(true) or allowEvalScript(true) unless absolutely required -- these weaken XSS protection significantly.


Security Events Catalog

| Event | Since | Purpose | |-------|-------|---------| | BeforeUserLoggedInEvent | NC 18 | Pre-login hook for custom validation | | PostLoginEvent | NC 18 | Post-login hook for auditing | | LoginFailedEvent | NC 19 | Failed login (known user) | | AnyLoginFailedEvent | NC 26 | Any login failure (broader scope) | | UserFirstTimeLoggedInEvent | NC 28 | First-ever login for onboarding | | TokenInvalidatedEvent | NC 32 | Auth token revoked | | TwoFactorProviderChallengeFailed | NC 28 | 2FA challenge failed | | TwoFactorProviderChallengePassed | NC 28 | 2FA challenge succeeded |

Register listeners via IRegistrationContext::registerEventListener() in Application::register().


Authentication Mechanisms

| Method | Use Case | Details | |--------|----------|---------| | Session + CSRF | Browser-based access | Default for web UI | | Basic Auth (app password) | Desktop/mobile clients | Via Login Flow v2 | | OIDC Bearer Token | SSO integration | Authorization: Bearer ID_TOKEN | | OCS-APIRequest: true header | API clients | Alternative to CSRF token |

ALWAYS use Login Flow v2 to obtain app passwords for external clients. NEVER store user passwords directly.


Decision Trees

Choosing Security Attributes

Is this endpoint admin-only?
  YES -> Use no attributes (default is admin-only)
  NO  -> Add #[NoAdminRequired]
         |
         Does it need to work without login?
           YES -> Add #[PublicPage]
           NO  -> Stop here
         |
         Is it called by an API client (not browser)?
           YES -> Add #[NoCSRFRequired]
           NO  -> Keep CSRF protection
         |
         Is it a 2FA setup page?
           YES -> Add #[NoTwoFactorRequired]
           NO  -> Keep 2FA requirement

Choosing Rate Limiting

Is the endpoint sensitive (auth, data modification)?
  NO  -> No rate limiting needed
  YES -> Is it accessible to anonymous users?
           YES -> Add #[AnonRateLimit(limit: N, period: S)]
           NO  -> (skip)
         Is it accessible to authenticated users?
           YES -> Add #[UserRateLimit(limit: N, period: S)]
           NO  -> (skip)
         Does it involve credentials/tokens?
           YES -> Add #[BruteForceProtection(action: 'name')]
                  Call $response->throttle() on FAILURE only
           NO  -> Rate limiting is sufficient

Reference Links

  • [references/methods.md](references/methods.md) -- Security attributes, middleware methods, CSP methods
  • [references/examples.md](references/examples.md) -- Security patterns, CSP configuration, middleware implementation
  • [references/anti-patterns.md](references/anti-patterns.md) -- Security mistakes and how to avoid them

Official Sources

  • https://docs.nextcloud.com/server/latest/developermanual/diggingdeeper/middleware.html
  • https://docs.nextcloud.com/server/latest/developer_manual/basics/controllers.html
  • https://docs.nextcloud.com/server/latest/developermanual/diggingdeeper/security.html

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.