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

Multisite Security

skill-wpultimatesecurity-wordpress-security-skills-multisite-security · by wpultimatesecurity

>

— No reviews yet
0 installs
25 views
0.0% view→install

Install

$ agentstack add skill-wpultimatesecurity-wordpress-security-skills-multisite-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-wpultimatesecurity-wordpress-security-skills-multisite-security)

Reliability & compatibility

✓ Security review passed
0 installs to date
— no reviews yet
● 17d 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 Multisite Security? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Multisite security

When to use this skill

Use this skill whenever code runs on a WordPress multisite network:

  • Using switch_to_blog() to access another site's data.
  • Adding network admin pages (network_admin_menu).
  • Enumerating sites with get_sites().
  • Reading a blog_id from a request parameter or URL.
  • Performing actions that affect the whole network vs. a single site.

On multisite, site administrator and network administrator are different roles. Network-level actions require manage_network or manage_network_options, and switch_to_blog() must always be paired with restore_current_blog().

Related: see the capability-permission-checks skill for single-site capability patterns.

Core principles (and why they matter)

  1. Site admin != network admin. A site administrator can do almost anything on their

own site, but they must not manage network settings or access other sites' data. Network actions need manage_network / manage_network_options.

  1. Always pair switch_to_blog() with restore_current_blog(). Forgetting to restore

leaves the rest of the request running in the wrong site context, leaking or corrupting data.

  1. Re-check capabilities after switching. Capabilities are evaluated in the current

site context. After switch_to_blog(), the capability context changes; re-verify current_user_can() or user_can() if you act on the new site.

  1. Never trust a blog_id from input. Validate it against allowed sites (e.g., sites

the current user belongs to, or the network allowlist) before switching.

  1. Keep per-site data isolated. Do not store site A's data in site B's options or

tables unless the user explicitly authorized cross-site access.

  1. is_super_admin() is for network-level checks only. Prefer current_user_can( 'manage_network' )

for capabilities.

Step-by-step implementation

  1. Check is_multisite() before running multisite-specific code.
  2. For network admin pages, gate with current_user_can( 'manage_network_options' ).
  3. For site actions that read a blog_id from input:
  • Cast to integer.
  • Confirm the site exists (get_site()).
  • Confirm the current user may act on it (user_can( $user_id, 'manage_sites' ) or

membership checks).

  1. Wrap the operation in switch_to_blog() / restore_current_blog().
  2. After switching, re-check capabilities if the action is privileged.
  3. Return errors rather than silently failing or defaulting to the current site.

Common AI mistakes / anti-patterns

Mistake 1 — switch_to_blog() with an unvalidated blog id

// ❌ Insecure: any blog id can be requested, including sites the user does not own.
$blog_id = (int) $_GET['blog_id'];
switch_to_blog( $blog_id );
$posts = get_posts();
restore_current_blog();
// ✅ Secure: validate the blog id and the user's relationship to it.
$blog_id = isset( $_GET['blog_id'] ) ? absint( $_GET['blog_id'] ) : 0;
$site    = get_site( $blog_id );
if ( ! $site || ! is_user_member_of_blog( get_current_user_id(), $blog_id ) ) {
    wp_die( esc_html__( 'Invalid site.', 'my-plugin' ), 403 );
}

switch_to_blog( $blog_id );
$posts = get_posts();
restore_current_blog();

Mistake 2 — Forgetting restore_current_blog()

// ❌ Risky: subsequent code runs in the switched context.
foreach ( $blog_ids as $blog_id ) {
    switch_to_blog( $blog_id );
    do_something();
}
// ✅ Secure: restore after each switch.
foreach ( $blog_ids as $blog_id ) {
    switch_to_blog( $blog_id );
    do_something();
    restore_current_blog();
}

Mistake 3 — Using manage_options for a network action

// ❌ Insecure: site admins have manage_options but cannot manage the network.
if ( current_user_can( 'manage_options' ) ) {
    update_site_option( 'my_plugin_network_key', $value );
}
// ✅ Secure: network actions require manage_network / manage_network_options.
if ( ! current_user_can( 'manage_network_options' ) ) {
    wp_die( esc_html__( 'You do not have permission to manage network options.', 'my-plugin' ), 403 );
}
update_site_option( 'my_plugin_network_key', $value );

Mistake 4 — Leaking data after a switch

// ❌ Insecure: data fetched under site B is echoed on site A without re-checking.
switch_to_blog( $blog_id );
$title = get_bloginfo( 'name' );
restore_current_blog();
echo $title;
// ✅ Secure: validate the user may read the target site, then escape output.
if ( ! is_user_member_of_blog( get_current_user_id(), $blog_id ) ) {
    return;
}
switch_to_blog( $blog_id );
$title = get_bloginfo( 'name' );
restore_current_blog();
echo esc_html( $title );

Mistake 5 — Assuming is_super_admin() covers every case

// ❌ Less precise: is_super_admin checks the super-admin list, not a capability.
if ( is_super_admin() ) {
    // do network thing
}
// ✅ Secure: prefer the explicit network capability.
if ( current_user_can( 'manage_network' ) ) {
    // do network thing
}

Correct code examples

A complete network-safe routine that validates a blog id, switches context, and restores it is in [references/secure-multisite-operations.php](references/secure-multisite-operations.php).

Checklist

  • [ ] Multisite-specific code checks is_multisite() first.
  • [ ] Network admin actions use manage_network / manage_network_options.
  • [ ] blog_id values from input are cast to integers and validated.
  • [ ] The user is confirmed to be a member of / allowed on the target site before switching.
  • [ ] Every switch_to_blog() has a matching restore_current_blog().
  • [ ] Capabilities are re-checked after switching sites if the action is privileged.
  • [ ] Per-site data is not leaked into another site's context.
  • [ ] is_super_admin() is used only where the super-admin list is the correct gate.

Official references

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.