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

Shortcode Block Security

skill-wpultimatesecurity-wordpress-security-skills-shortcode-block-security · by wpultimatesecurity

>

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

Install

$ agentstack add skill-wpultimatesecurity-wordpress-security-skills-shortcode-block-security

Open-source listing, not yet scanned by AgentStack. Follow the source repository for install instructions.

Security review

⚠ Flagged

1 finding(s); flagged for manual review. · v0.1.0 How review works →

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

What it can access

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

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 →

Reliability & compatibility

— Not yet reviewed
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 Shortcode Block Security? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Shortcode & dynamic block security

When to use this skill

Use this skill whenever code renders content from shortcodes or dynamic blocks:

  • Registering a shortcode with add_shortcode().
  • Reading or outputting shortcode attributes ($atts) or enclosed content ($content).
  • Registering a dynamic block with a render_callback.
  • Reading block attributes in a server-side render.
  • Building HTML, URLs, or classes from shortcode/block input.

Shortcodes and dynamic blocks are stored XSS sinks: a contributor enters [my_card title="..."] and the render callback echoes it unescaped. Every attribute must be sanitized and every output escaped.

Related: see the output-escaping skill for context-correct escaping and the gutenberg-block-editor-security skill for broader block-editor surfaces.

Core principles (and why they matter)

  1. shortcode_atts() sets defaults; it does NOT sanitize. The returned array still holds

raw user input. Sanitize each value before use.

  1. Block attributes are user input too. Declaring type: 'string' in block.json does not

escape HTML or JavaScript for you; sanitize on render.

  1. Escape at render for the exact context. HTML body → esc_html(). HTML attribute →

esc_attr(). URL → esc_url(). Rich HTML → wp_kses_post() with an allowlist.

  1. Do not store unescaped attribute values. If you persist them, sanitize on save and escape

on read.

  1. Never pass shortcode/block input to do_shortcode() or eval() uncontrolled. Both can

execute arbitrary shortcodes or code.

  1. Return, don't echo. Shortcode and block render callbacks must return strings; echoing

produces unexpected output placement.

Step-by-step implementation

  1. In the shortcode callback, call shortcode_atts() with a complete default map.
  2. Sanitize each attribute to its expected type (absint, sanitize_text_field, esc_url_raw,

sanitize_key).

  1. In a block render_callback, read attributes from the $attributes array and sanitize them

the same way.

  1. Build the markup by concatenating escaped values.
  2. Return the complete markup string.
  3. For rich content, use wp_kses_post() or a tightly scoped wp_kses() allowlist.

Common AI mistakes / anti-patterns

Mistake 1 — Echoing $atts directly

// ❌ Insecure: stored XSS through the title attribute.
function my_plugin_card_shortcode( $atts ) {
    return '' . $atts['title'] . '';
}
// ✅ Secure: default, then sanitize, then escape.
function my_plugin_card_shortcode( $atts ) {
    $atts = shortcode_atts(
        array(
            'title' => '',
            'link'  => '',
        ),
        $atts,
        'my_plugin_card'
    );

    $title = sanitize_text_field( $atts['title'] );
    $link  = esc_url_raw( $atts['link'] );

    $output = '';
    if ( $link ) {
        $output .= '' . esc_html( $title ) . '';
    } else {
        $output .= '' . esc_html( $title ) . '';
    }
    $output .= '';

    return $output;
}

Mistake 2 — Trusting shortcode_atts() to sanitize

// ❌ Insecure: shortcode_atts only supplies defaults and filters unknown keys.
$atts = shortcode_atts( array( 'class' => '' ), $atts );
echo '...';
// ✅ Secure: sanitize the value after normalizing it.
$atts  = shortcode_atts( array( 'class' => '' ), $atts, 'my_plugin_box' );
$class = sanitize_html_class( $atts['class'] );
echo '...';

Mistake 3 — Dynamic block render callback echoing attributes

// ❌ Insecure: block attributes echoed raw.
function my_plugin_render_banner( $attributes ) {
    ?>
    ">
        
    
    %s',
        esc_attr( $bg_color ),
        esc_html( $heading )
    );
}

Mistake 4 — Allowing arbitrary HTML through attributes

// ❌ Insecure: an attacker can inject script/event handlers.
function my_plugin_render_note( $attributes ) {
    return '' . $attributes['content'] . '';
}
// ✅ Secure: constrain rich markup with wp_kses_post.
function my_plugin_render_note( $attributes ) {
    $content = isset( $attributes['content'] ) ? $attributes['content'] : '';
    return '' . wp_kses_post( $content ) . '';
}

Mistake 5 — Running do_shortcode() on untrusted input

// ❌ Insecure: executes arbitrary shortcodes supplied by a visitor.
echo do_shortcode( $_POST['content'] );
// ✅ Secure: do not run do_shortcode on user input; if required, sanitize first.
$content = wp_kses_post( wp_unslash( $_POST['content'] ?? '' ) );

Correct code examples

A complete secure shortcode and dynamic-block render callback is in [references/secure-shortcode-block.php](references/secure-shortcode-block.php).

Checklist

  • [ ] shortcode_atts() provides defaults for every supported attribute.
  • [ ] Each shortcode attribute is sanitized to its expected type after normalization.
  • [ ] Block attributes are sanitized inside render_callback, not trusted from block.json types.
  • [ ] All rendered output is escaped for its context (esc_html, esc_attr, esc_url, wp_kses_post).
  • [ ] CSS classes use sanitize_html_class() (or esc_attr() with an allowlist).
  • [ ] Colors use sanitize_hex_color() where appropriate.
  • [ ] The callback returns a string; it does not echo directly.
  • [ ] do_shortcode() is never run on untrusted input.

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.