Before any NoDevZone-generated plugin reaches a user's WordPress install, it passes through three automated security checks. This post explains what those checks look for — and why each one matters.

Why AI-generated code needs auditing

Large language models are surprisingly good at writing WordPress plugins. They know hook names, they understand WP coding standards, they produce readable PHP. But they also make predictable mistakes — and those mistakes are security vulnerabilities.

The most common ones we see:

  • Using $_GET or $_POST without sanitization
  • Missing nonce verification on form submissions
  • Direct database queries without $wpdb->prepare()
  • Using eval() or exec() for dynamic behavior
  • Outputting user data without esc_html() or esc_attr()

These aren't exotic edge cases. They show up regularly in LLM output — even from the best models.

Stage 1: Prompt validation

Before the AI writes a single line, we analyze the user's description. This step catches two categories of problems:

Manipulation attempts — prompts trying to make the AI produce deliberately malicious code. Things like "ignore previous instructions" or "create a backdoor for testing."

Vague or unworkable descriptions — prompts too short or too ambiguous to produce useful code. "Make a plugin" generates garbage; "Create a contact form that sends submissions to an email address with spam filtering" generates something real.

If a prompt fails this check, the user sees a specific error explaining why — not a generic rejection.

Stage 2: PHP lint in an isolated container

Once the AI produces PHP code, it's executed through php -l inside a Docker container that's completely isolated from everything else. This catches syntax errors before the plugin ever reaches a WordPress install.

But we go further: if the lint fails, the system doesn't just reject the output. It sends the error back to the AI with a correction prompt — what we call healing. The AI sees its own error and tries again, up to three times.

This means users almost never see a "generation failed" message. They see a slightly longer generation time — and working code.

Stage 3: Code security scan

This is the most important stage. We run a static analysis pass that checks for:

Dangerous functions: eval(), exec(), system(), shell_exec(), passthru() — any of these blocks the plugin from being released.

SQL injection vectors: raw $wpdb->query() calls with interpolated variables, missing $wpdb->prepare(), direct mysql_query() usage.

Missing permission checks: AJAX handlers that don't call current_user_can() before doing anything privileged.

Missing nonce verification: form processors that don't call wp_verify_nonce() or check_ajax_referer().

Unescaped output: echo $_GET[...], echo $user_input without escaping functions.

If any of these are found, the plugin is blocked. The user sees a report listing exactly which functions triggered the block and why — not just "failed security check."

What the audit report looks like

Every generated plugin comes with a security audit report in plain language. It lists:

  • Which checks passed (green)
  • Which checks triggered warnings (amber) — issues that aren't blockers but deserve attention
  • Any corrections that were auto-applied during healing

The report is generated automatically and attached to the plugin download. It's useful both for your own confidence and for showing clients that you took security seriously.

Stage 4: Save-time validation

This one isn't part of the initial generation — it applies when users edit plugin code manually in the NoDevZone editor.

Every time you save, the same lint + security scan runs again. If you introduce a critical vulnerability while editing, saving is blocked until you fix it. This prevents the common scenario where a developer makes a quick "temporary" change that stays in production for two years.

The limits of automated auditing

Automated scanning catches a specific class of problems well. It doesn't catch everything.

Logic errors, broken business logic, and subtle permission escalation issues that don't involve known dangerous patterns still require human review. We're transparent about this in the documentation — the audit isn't a replacement for a security review, it's a floor that guarantees a minimum standard.

For production plugins handling payments or sensitive data, we recommend a manual review in addition to the automated checks. The audit report gives a human reviewer a good starting point.