Inicio - Documentación - POM Cache - 09 Developers - Path, output, and authorization safety

Path, output, and authorization safety

Cache integrations operate on public responses and filesystem artifacts. A small mistake can expose private content, create path traversal, or remove a wider store than intended. Apply the safeguards in this guide before adding a hook or calling a helper.

Define the representation boundary

A shared cache key may represent only data that is identical for every visitor who can receive it. Do not cache output that varies by:

  • logged-in user or capability;
  • authorization, subscription, or account;
  • cart, checkout, session, or password;
  • nonce, CSRF token, or one-time URL;
  • private query parameter or request body;
  • cookie not included in an explicit bypass rule;
  • geography, currency, language, or device unless that variation has a safe independent key.

If a feature changes from public to private, preventing future writes is not enough. Disable direct server delivery, clear existing origin artifacts, invalidate the CDN, and verify all affected sessions before re-enabling caching.

Use JSON relative paths, not arbitrary filenames

pom_cache_json_normalize_relative_path() accepts a restricted relative .json path and returns an empty string when invalid. It rejects absolute paths, backslashes, null bytes, traversal segments, double slashes, missing .json suffixes, and unsupported characters.

Validate before any operation:

$relative_path = pom_cache_json_normalize_relative_path(
    'archive/book/page-2.json'
);

if ( '' === $relative_path ) {
    return;
}

$json = pom_cache_json_read(
    $relative_path,
    array( 'integration' => 'my_catalog' )
);

Do not concatenate request input into an absolute cache path. Let the public helper apply the current-site base directory and containment checks.

Validate before purging

pom_cache_json_purge() deletes one file only when relative_path normalizes successfully. A missing or invalid relative_path selects a full current-site JSON purge.

This makes pre-validation mandatory when the intended scope is exact:

$candidate = isset( $_POST['cache_path'] )
    ? sanitize_text_field( wp_unslash( $_POST['cache_path'] ) )
    : '';

$relative_path = pom_cache_json_normalize_relative_path( $candidate );
if ( '' === $relative_path ) {
    wp_die( esc_html__( 'Invalid cache path.', 'my-plugin' ) );
}

pom_cache_json_purge(
    array(
        'relative_path' => $relative_path,
        'context'       => 'my_plugin_manual_refresh',
    )
);

For fixed application-owned paths, prefer constants or deterministic builders over accepting a raw path from a request.

Protect state-changing endpoints

POM Cache helpers do not authorize your controller. Before clearing from an AJAX, REST, or administration action:

  1. authenticate the caller;
  2. check the exact required capability;
  3. verify a nonce or the REST route's authentication contract;
  4. sanitize and validate all input;
  5. select the narrowest helper;
  6. return an escaped, non-sensitive result.

Do not expose an unauthenticated “clear cache” URL.

Respect multisite scope

High-level helpers operate in the current blog context. To target another site:

$site_id = 12;

switch_to_blog( $site_id );
try {
    if ( function_exists( 'pom_cache_delete_site_cache' ) ) {
        pom_cache_delete_site_cache( 'my_plugin_network_sync' );
    }
    if ( function_exists( 'pom_cache_json_delete_site_cache' ) ) {
        pom_cache_json_delete_site_cache( 'my_plugin_network_sync' );
    }
} finally {
    restore_current_blog();
}

Authorize the network operation before switching. Never loop through arbitrary user-supplied blog IDs.

Keep filter callbacks conservative

Eligibility filters should normally convert true to false, never the reverse. A callback that re-enables a rejected read can bypass POM Cache's cookie or DONOTCACHEPAGE safeguards.

Output filters must return a string and remain deterministic. Never inject per-user data into pom_cache_buffer or pom_cache_ob_callback_filter.

Path filters are deployment contracts. Changing a directory for WordPress while Apache, the early drop-in, statistics, or deletion still uses the old path produces stale or unreachable artifacts. Prefer the Cache Location setting unless you control every layer.

Avoid low-level filesystem deletion

Use pom_cache_delete_site_cache(), pom_cache_json_delete_site_cache(), or an exact JSON helper. They apply current-site paths, public filters, and containment safeguards.

Do not recursively delete a computed cache root, follow symlinks, or use an unvalidated glob. Do not expose absolute filesystem paths in public errors or support reports.