<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>sql injection Archives - Developry Plugins</title>
	<atom:link href="https://developryplugins.com/tag/sql-injection/feed/" rel="self" type="application/rss+xml" />
	<link>https://developryplugins.com/tag/sql-injection/</link>
	<description></description>
	<lastBuildDate>Mon, 24 Nov 2025 11:18:16 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://developryplugins.com/wp-content/uploads/2025/11/cropped-favicon-32x32.png</url>
	<title>sql injection Archives - Developry Plugins</title>
	<link>https://developryplugins.com/tag/sql-injection/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>WordPress Plugin Security Best Practices: Prevent Common Vulnerabilities</title>
		<link>https://developryplugins.com/wordpress-plugin-security-best-practices-prevent-common-vulnerabilities/</link>
		
		<dc:creator><![CDATA[Krasen Slavov]]></dc:creator>
		<pubDate>Tue, 20 Jan 2026 09:00:00 +0000</pubDate>
				<category><![CDATA[WordPress Plugin Development Guide]]></category>
		<category><![CDATA[plugin security]]></category>
		<category><![CDATA[security best practices]]></category>
		<category><![CDATA[sql injection]]></category>
		<category><![CDATA[wordpress security]]></category>
		<category><![CDATA[xss prevention]]></category>
		<guid isPermaLink="false">https://developryplugins.com/?p=173</guid>

					<description><![CDATA[<p>Plugin security vulnerabilities endanger millions of WordPress sites. As a plugin developer, you’re responsible for protecting user data, preventing attacks, and maintaining WordPress ecosystem trust. This guide covers essential security...</p>
<p>The post <a href="https://developryplugins.com/wordpress-plugin-security-best-practices-prevent-common-vulnerabilities/">WordPress Plugin Security Best Practices: Prevent Common Vulnerabilities</a> appeared first on <a href="https://developryplugins.com">Developry Plugins</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><!-- @format --></p>
<p>Plugin security vulnerabilities endanger millions of WordPress sites. As a plugin developer, you’re responsible for protecting user data, preventing attacks, and maintaining WordPress ecosystem trust. This guide covers essential security practices every plugin developer must follow.</p>
<h2 id="why-plugin-security-matters">Why Plugin Security Matters</h2>
<p>WordPress powers 43% of websites globally. Attackers target plugins because:</p>
<ul>
<li>Plugins often handle sensitive data</li>
<li>Security vulnerabilities affect thousands of sites using the same plugin</li>
<li>Poorly coded plugins provide entry points to otherwise secure sites</li>
<li>Plugin vulnerabilities appear in major security databases</li>
</ul>
<p>A single SQL injection vulnerability in your plugin could compromise thousands of WordPress installations. Security isn’t optional—it’s your primary responsibility as a developer.</p>
<h2 id="cross-site-scripting-xss-prevention">Cross-Site Scripting (XSS) Prevention</h2>
<p>XSS attacks inject malicious JavaScript into pages, stealing cookies, redirecting users, or modifying content.</p>
<p><strong>Always escape output:</strong></p>
<div class="sourceCode" id="cb1">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true"></a><span class="co">// HTML context</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true"></a><span class="kw">echo</span> <span class="st">&#39;&lt;p&gt;&#39;</span> . esc_html<span class="ot">(</span> <span class="kw">$user_input</span> <span class="ot">)</span> . <span class="st">&#39;&lt;/p&gt;&#39;</span><span class="ot">;</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true"></a></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true"></a><span class="co">// Attribute context</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true"></a><span class="kw">echo</span> <span class="st">&#39;&lt;div class=&quot;&#39;</span> . esc_attr<span class="ot">(</span> <span class="kw">$class_name</span> <span class="ot">)</span> . <span class="st">&#39;&quot;&gt;&#39;</span><span class="ot">;</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true"></a></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true"></a><span class="co">// URL context</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true"></a><span class="kw">echo</span> <span class="st">&#39;&lt;a href=&quot;&#39;</span> . esc_url<span class="ot">(</span> <span class="kw">$link</span> <span class="ot">)</span> . <span class="st">&#39;&quot;&gt;Link&lt;/a&gt;&#39;</span><span class="ot">;</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true"></a></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true"></a><span class="co">// JavaScript context</span></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true"></a><span class="kw">echo</span> <span class="st">&#39;&lt;script&gt;var data = &#39;</span> . esc_js<span class="ot">(</span> <span class="kw">$data</span> <span class="ot">)</span> . <span class="st">&#39;;&lt;/script&gt;&#39;</span><span class="ot">;</span></span></code></pre>
</div>
<p><strong>Allow specific HTML with wp_kses():</strong></p>
<div class="sourceCode" id="cb2">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true"></a><span class="kw">$allowed_html</span> = <span class="kw">array</span><span class="ot">(</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true"></a>    <span class="st">&#39;a&#39;</span> =&gt; <span class="kw">array</span><span class="ot">(</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true"></a>        <span class="st">&#39;href&#39;</span> =&gt; <span class="kw">array</span><span class="ot">(),</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true"></a>        <span class="st">&#39;title&#39;</span> =&gt; <span class="kw">array</span><span class="ot">()</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true"></a>    <span class="ot">),</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true"></a>    <span class="st">&#39;strong&#39;</span> =&gt; <span class="kw">array</span><span class="ot">(),</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true"></a>    <span class="st">&#39;em&#39;</span> =&gt; <span class="kw">array</span><span class="ot">()</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true"></a><span class="ot">);</span></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true"></a><span class="kw">echo</span> wp_kses<span class="ot">(</span> <span class="kw">$user_content</span><span class="ot">,</span> <span class="kw">$allowed_html</span> <span class="ot">);</span></span></code></pre>
</div>
<p>Never output unescaped user data. Ever.</p>
<h2 id="sql-injection-prevention">SQL Injection Prevention</h2>
<p>SQL injection allows attackers to execute arbitrary database queries.</p>
<p><strong>Always use prepared statements:</strong></p>
<div class="sourceCode" id="cb3">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true"></a><span class="kw">global</span> <span class="kw">$wpdb</span><span class="ot">;</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true"></a></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true"></a><span class="co">// WRONG - vulnerable to SQL injection</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true"></a><span class="kw">$user_id</span> = <span class="kw">$_GET</span><span class="ot">[</span><span class="st">&#39;user_id&#39;</span><span class="ot">];</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true"></a><span class="kw">$results</span> = <span class="kw">$wpdb</span>-&gt;get_results<span class="ot">(</span> <span class="st">&quot;SELECT * FROM </span><span class="kw">{$wpdb-&gt;users}</span><span class="st"> WHERE ID = </span><span class="kw">$user_id</span><span class="st">&quot;</span> <span class="ot">);</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true"></a></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true"></a><span class="co">// CORRECT - using prepare()</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true"></a><span class="kw">$user_id</span> = <span class="fu">intval</span><span class="ot">(</span> <span class="kw">$_GET</span><span class="ot">[</span><span class="st">&#39;user_id&#39;</span><span class="ot">]</span> <span class="ot">);</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true"></a><span class="kw">$results</span> = <span class="kw">$wpdb</span>-&gt;get_results<span class="ot">(</span></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true"></a>    <span class="kw">$wpdb</span>-&gt;prepare<span class="ot">(</span></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true"></a>        <span class="st">&quot;SELECT * FROM </span><span class="kw">{$wpdb-&gt;users}</span><span class="st"> WHERE ID = %d&quot;</span><span class="ot">,</span></span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true"></a>        <span class="kw">$user_id</span></span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true"></a>    <span class="ot">)</span></span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true"></a><span class="ot">);</span></span></code></pre>
</div>
<p><strong>Placeholders for different data types:</strong></p>
<div class="sourceCode" id="cb4">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true"></a><span class="co">// %d for integers</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true"></a><span class="kw">$wpdb</span>-&gt;prepare<span class="ot">(</span> <span class="st">&quot;SELECT * FROM table WHERE id = %d&quot;</span><span class="ot">,</span> <span class="kw">$id</span> <span class="ot">);</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true"></a></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true"></a><span class="co">// %s for strings</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true"></a><span class="kw">$wpdb</span>-&gt;prepare<span class="ot">(</span> <span class="st">&quot;SELECT * FROM table WHERE name = %s&quot;</span><span class="ot">,</span> <span class="kw">$name</span> <span class="ot">);</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true"></a></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true"></a><span class="co">// %f for floats</span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true"></a><span class="kw">$wpdb</span>-&gt;prepare<span class="ot">(</span> <span class="st">&quot;SELECT * FROM table WHERE price = %f&quot;</span><span class="ot">,</span> <span class="kw">$price</span> <span class="ot">);</span></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true"></a></span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true"></a><span class="co">// Multiple values</span></span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true"></a><span class="kw">$wpdb</span>-&gt;prepare<span class="ot">(</span></span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true"></a>    <span class="st">&quot;SELECT * FROM table WHERE id = %d AND name = %s&quot;</span><span class="ot">,</span></span>
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true"></a>    <span class="kw">$id</span><span class="ot">,</span></span>
<span id="cb4-14"><a href="#cb4-14" aria-hidden="true"></a>    <span class="kw">$name</span></span>
<span id="cb4-15"><a href="#cb4-15" aria-hidden="true"></a><span class="ot">);</span></span></code></pre>
</div>
<p>Never concatenate variables into SQL queries.</p>
<h2 id="csrf-protection-with-nonces">CSRF Protection with Nonces</h2>
<p>CSRF attacks trick users into executing unwanted actions.</p>
<p><strong>Create nonces in forms:</strong></p>
<div class="sourceCode" id="cb5">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true"></a>&lt;form method=<span class="st">&quot;post&quot;</span>&gt;</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true"></a>    &lt;<span class="ot">?</span>php wp_nonce_field<span class="ot">(</span> <span class="st">&#39;dprt_save_settings&#39;</span><span class="ot">,</span> <span class="st">&#39;dprt_nonce&#39;</span> <span class="ot">);</span> <span class="kw">?&gt;</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true"></a>    &lt;input type=<span class="st">&quot;text&quot;</span> name=<span class="st">&quot;setting_value&quot;</span>&gt;</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true"></a>    &lt;input type=<span class="st">&quot;submit&quot;</span> value=<span class="st">&quot;Save&quot;</span>&gt;</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true"></a>&lt;/form&gt;</span></code></pre>
</div>
<p><strong>Verify nonces before processing:</strong></p>
<div class="sourceCode" id="cb6">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true"></a><span class="kw">if</span> <span class="ot">(</span> <span class="kw">isset</span><span class="ot">(</span> <span class="kw">$_POST</span><span class="ot">[</span><span class="st">&#39;submit&#39;</span><span class="ot">]</span> <span class="ot">)</span> <span class="ot">)</span> {</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true"></a>    <span class="kw">if</span> <span class="ot">(</span> ! <span class="kw">isset</span><span class="ot">(</span> <span class="kw">$_POST</span><span class="ot">[</span><span class="st">&#39;dprt_nonce&#39;</span><span class="ot">]</span> <span class="ot">)</span> || ! wp_verify_nonce<span class="ot">(</span> <span class="kw">$_POST</span><span class="ot">[</span><span class="st">&#39;dprt_nonce&#39;</span><span class="ot">],</span> <span class="st">&#39;dprt_save_settings&#39;</span> <span class="ot">)</span> <span class="ot">)</span> {</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true"></a>        wp_die<span class="ot">(</span> <span class="st">&#39;Security check failed&#39;</span> <span class="ot">);</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true"></a>    }</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true"></a></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true"></a>    <span class="co">// Process form data</span></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true"></a>}</span></code></pre>
</div>
<p><strong>For admin pages, use check_admin_referer():</strong></p>
<div class="sourceCode" id="cb7">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true"></a>check_admin_referer<span class="ot">(</span> <span class="st">&#39;dprt_save_settings&#39;</span><span class="ot">,</span> <span class="st">&#39;dprt_nonce&#39;</span> <span class="ot">);</span></span></code></pre>
</div>
<p><strong>For AJAX:</strong></p>
<div class="sourceCode" id="cb8">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true"></a><span class="co">// JavaScript</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true"></a>$.post<span class="ot">(</span> ajaxurl<span class="ot">,</span> {</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true"></a>    action: <span class="st">&#39;dprt_save&#39;</span><span class="ot">,</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true"></a>    nonce: dprt_ajax.nonce<span class="ot">,</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true"></a>    data: formData</span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true"></a>}<span class="ot">);</span></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true"></a></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true"></a><span class="co">// PHP</span></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true"></a><span class="kw">function</span> dprt_ajax_save<span class="ot">()</span> {</span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true"></a>    check_ajax_referer<span class="ot">(</span> <span class="st">&#39;dprt_ajax_nonce&#39;</span><span class="ot">,</span> <span class="st">&#39;nonce&#39;</span> <span class="ot">);</span></span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true"></a>    <span class="co">// Process request</span></span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true"></a>}</span></code></pre>
</div>
<p>Every form submission, AJAX request, and state-changing action requires nonce verification.</p>
<h2 id="user-capability-checks">User Capability Checks</h2>
<p>Verify users have permission before allowing actions:</p>
<div class="sourceCode" id="cb9">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true"></a><span class="co">// Check specific capability</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true"></a><span class="kw">if</span> <span class="ot">(</span> ! current_user_can<span class="ot">(</span> <span class="st">&#39;manage_options&#39;</span> <span class="ot">)</span> <span class="ot">)</span> {</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true"></a>    wp_die<span class="ot">(</span> <span class="st">&#39;Unauthorized access&#39;</span> <span class="ot">);</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true"></a>}</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true"></a></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true"></a><span class="co">// Check for specific post</span></span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true"></a><span class="kw">if</span> <span class="ot">(</span> ! current_user_can<span class="ot">(</span> <span class="st">&#39;edit_post&#39;</span><span class="ot">,</span> <span class="kw">$post_id</span> <span class="ot">)</span> <span class="ot">)</span> {</span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true"></a>    wp_die<span class="ot">(</span> <span class="st">&#39;You cannot edit this post&#39;</span> <span class="ot">);</span></span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true"></a>}</span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true"></a></span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true"></a><span class="co">// Check multiple capabilities</span></span>
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true"></a><span class="kw">if</span> <span class="ot">(</span> ! current_user_can<span class="ot">(</span> <span class="st">&#39;edit_posts&#39;</span> <span class="ot">)</span> &amp;&amp; ! current_user_can<span class="ot">(</span> <span class="st">&#39;edit_pages&#39;</span> <span class="ot">)</span> <span class="ot">)</span> {</span>
<span id="cb9-13"><a href="#cb9-13" aria-hidden="true"></a>    <span class="kw">return</span><span class="ot">;</span></span>
<span id="cb9-14"><a href="#cb9-14" aria-hidden="true"></a>}</span></code></pre>
</div>
<p>Common capabilities:</p>
<ul>
<li><code>manage_options</code> &#8211; Administrators only</li>
<li><code>edit_posts</code> &#8211; Can edit posts</li>
<li><code>publish_posts</code> &#8211; Can publish posts</li>
<li><code>edit_others_posts</code> &#8211; Can edit posts by other users</li>
</ul>
<h2 id="data-sanitization">Data Sanitization</h2>
<p>Clean all user input before processing:</p>
<div class="sourceCode" id="cb10">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true"></a><span class="co">// Text fields</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true"></a><span class="kw">$text</span> = sanitize_text_field<span class="ot">(</span> <span class="kw">$_POST</span><span class="ot">[</span><span class="st">&#39;text_field&#39;</span><span class="ot">]</span> <span class="ot">);</span></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true"></a></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true"></a><span class="co">// Textareas</span></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true"></a><span class="kw">$content</span> = sanitize_textarea_field<span class="ot">(</span> <span class="kw">$_POST</span><span class="ot">[</span><span class="st">&#39;content&#39;</span><span class="ot">]</span> <span class="ot">);</span></span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true"></a></span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true"></a><span class="co">// Email addresses</span></span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true"></a><span class="kw">$email</span> = sanitize_email<span class="ot">(</span> <span class="kw">$_POST</span><span class="ot">[</span><span class="st">&#39;email&#39;</span><span class="ot">]</span> <span class="ot">);</span></span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true"></a></span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true"></a><span class="co">// URLs</span></span>
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true"></a><span class="kw">$url</span> = esc_url_raw<span class="ot">(</span> <span class="kw">$_POST</span><span class="ot">[</span><span class="st">&#39;url&#39;</span><span class="ot">]</span> <span class="ot">);</span></span>
<span id="cb10-12"><a href="#cb10-12" aria-hidden="true"></a></span>
<span id="cb10-13"><a href="#cb10-13" aria-hidden="true"></a><span class="co">// File names</span></span>
<span id="cb10-14"><a href="#cb10-14" aria-hidden="true"></a><span class="kw">$filename</span> = sanitize_file_name<span class="ot">(</span> <span class="kw">$_FILES</span><span class="ot">[</span><span class="st">&#39;file&#39;</span><span class="ot">][</span><span class="st">&#39;name&#39;</span><span class="ot">]</span> <span class="ot">);</span></span>
<span id="cb10-15"><a href="#cb10-15" aria-hidden="true"></a></span>
<span id="cb10-16"><a href="#cb10-16" aria-hidden="true"></a><span class="co">// HTML class names</span></span>
<span id="cb10-17"><a href="#cb10-17" aria-hidden="true"></a><span class="kw">$class</span> = sanitize_html_class<span class="ot">(</span> <span class="kw">$_POST</span><span class="ot">[</span><span class="st">&#39;class&#39;</span><span class="ot">]</span> <span class="ot">);</span></span>
<span id="cb10-18"><a href="#cb10-18" aria-hidden="true"></a></span>
<span id="cb10-19"><a href="#cb10-19" aria-hidden="true"></a><span class="co">// Keys</span></span>
<span id="cb10-20"><a href="#cb10-20" aria-hidden="true"></a><span class="kw">$key</span> = sanitize_key<span class="ot">(</span> <span class="kw">$_POST</span><span class="ot">[</span><span class="st">&#39;key&#39;</span><span class="ot">]</span> <span class="ot">);</span></span>
<span id="cb10-21"><a href="#cb10-21" aria-hidden="true"></a></span>
<span id="cb10-22"><a href="#cb10-22" aria-hidden="true"></a><span class="co">// Integers</span></span>
<span id="cb10-23"><a href="#cb10-23" aria-hidden="true"></a><span class="kw">$number</span> = absint<span class="ot">(</span> <span class="kw">$_POST</span><span class="ot">[</span><span class="st">&#39;number&#39;</span><span class="ot">]</span> <span class="ot">);</span></span></code></pre>
</div>
<p>Sanitize input, escape output. This principle prevents most vulnerabilities.</p>
<h2 id="file-upload-security">File Upload Security</h2>
<p>File uploads are high-risk operations:</p>
<div class="sourceCode" id="cb11">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true"></a><span class="kw">function</span> dprt_handle_file_upload<span class="ot">()</span> {</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true"></a>    <span class="kw">if</span> <span class="ot">(</span> ! <span class="kw">isset</span><span class="ot">(</span> <span class="kw">$_FILES</span><span class="ot">[</span><span class="st">&#39;file&#39;</span><span class="ot">]</span> <span class="ot">)</span> <span class="ot">)</span> {</span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true"></a>        <span class="kw">return</span><span class="ot">;</span></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true"></a>    }</span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true"></a></span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true"></a>    <span class="co">// Verify nonce</span></span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true"></a>    check_admin_referer<span class="ot">(</span> <span class="st">&#39;dprt_upload&#39;</span><span class="ot">,</span> <span class="st">&#39;nonce&#39;</span> <span class="ot">);</span></span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true"></a></span>
<span id="cb11-9"><a href="#cb11-9" aria-hidden="true"></a>    <span class="co">// Check capability</span></span>
<span id="cb11-10"><a href="#cb11-10" aria-hidden="true"></a>    <span class="kw">if</span> <span class="ot">(</span> ! current_user_can<span class="ot">(</span> <span class="st">&#39;upload_files&#39;</span> <span class="ot">)</span> <span class="ot">)</span> {</span>
<span id="cb11-11"><a href="#cb11-11" aria-hidden="true"></a>        wp_die<span class="ot">(</span> <span class="st">&#39;Insufficient permissions&#39;</span> <span class="ot">);</span></span>
<span id="cb11-12"><a href="#cb11-12" aria-hidden="true"></a>    }</span>
<span id="cb11-13"><a href="#cb11-13" aria-hidden="true"></a></span>
<span id="cb11-14"><a href="#cb11-14" aria-hidden="true"></a>    <span class="co">// Validate file type</span></span>
<span id="cb11-15"><a href="#cb11-15" aria-hidden="true"></a>    <span class="kw">$allowed_types</span> = <span class="kw">array</span><span class="ot">(</span> <span class="st">&#39;image/jpeg&#39;</span><span class="ot">,</span> <span class="st">&#39;image/png&#39;</span><span class="ot">,</span> <span class="st">&#39;image/gif&#39;</span> <span class="ot">);</span></span>
<span id="cb11-16"><a href="#cb11-16" aria-hidden="true"></a>    <span class="kw">$file_type</span> = <span class="kw">$_FILES</span><span class="ot">[</span><span class="st">&#39;file&#39;</span><span class="ot">][</span><span class="st">&#39;type&#39;</span><span class="ot">];</span></span>
<span id="cb11-17"><a href="#cb11-17" aria-hidden="true"></a></span>
<span id="cb11-18"><a href="#cb11-18" aria-hidden="true"></a>    <span class="kw">if</span> <span class="ot">(</span> ! <span class="fu">in_array</span><span class="ot">(</span> <span class="kw">$file_type</span><span class="ot">,</span> <span class="kw">$allowed_types</span> <span class="ot">)</span> <span class="ot">)</span> {</span>
<span id="cb11-19"><a href="#cb11-19" aria-hidden="true"></a>        wp_die<span class="ot">(</span> <span class="st">&#39;Invalid file type&#39;</span> <span class="ot">);</span></span>
<span id="cb11-20"><a href="#cb11-20" aria-hidden="true"></a>    }</span>
<span id="cb11-21"><a href="#cb11-21" aria-hidden="true"></a></span>
<span id="cb11-22"><a href="#cb11-22" aria-hidden="true"></a>    <span class="co">// Use WordPress upload handler</span></span>
<span id="cb11-23"><a href="#cb11-23" aria-hidden="true"></a>    <span class="kw">$upload</span> = wp_handle_upload<span class="ot">(</span></span>
<span id="cb11-24"><a href="#cb11-24" aria-hidden="true"></a>        <span class="kw">$_FILES</span><span class="ot">[</span><span class="st">&#39;file&#39;</span><span class="ot">],</span></span>
<span id="cb11-25"><a href="#cb11-25" aria-hidden="true"></a>        <span class="kw">array</span><span class="ot">(</span> <span class="st">&#39;test_form&#39;</span> =&gt; <span class="kw">false</span> <span class="ot">)</span></span>
<span id="cb11-26"><a href="#cb11-26" aria-hidden="true"></a>    <span class="ot">);</span></span>
<span id="cb11-27"><a href="#cb11-27" aria-hidden="true"></a></span>
<span id="cb11-28"><a href="#cb11-28" aria-hidden="true"></a>    <span class="kw">if</span> <span class="ot">(</span> <span class="kw">isset</span><span class="ot">(</span> <span class="kw">$upload</span><span class="ot">[</span><span class="st">&#39;error&#39;</span><span class="ot">]</span> <span class="ot">)</span> <span class="ot">)</span> {</span>
<span id="cb11-29"><a href="#cb11-29" aria-hidden="true"></a>        wp_die<span class="ot">(</span> <span class="kw">$upload</span><span class="ot">[</span><span class="st">&#39;error&#39;</span><span class="ot">]</span> <span class="ot">);</span></span>
<span id="cb11-30"><a href="#cb11-30" aria-hidden="true"></a>    }</span>
<span id="cb11-31"><a href="#cb11-31" aria-hidden="true"></a></span>
<span id="cb11-32"><a href="#cb11-32" aria-hidden="true"></a>    <span class="co">// File uploaded successfully</span></span>
<span id="cb11-33"><a href="#cb11-33" aria-hidden="true"></a>    <span class="kw">$file_url</span> = <span class="kw">$upload</span><span class="ot">[</span><span class="st">&#39;url&#39;</span><span class="ot">];</span></span>
<span id="cb11-34"><a href="#cb11-34" aria-hidden="true"></a>}</span></code></pre>
</div>
<p>Never trust uploaded files. Validate type, size, and content.</p>
<h2 id="preventing-direct-file-access">Preventing Direct File Access</h2>
<p>Prevent users from accessing plugin files directly:</p>
<div class="sourceCode" id="cb12">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true"></a><span class="kw">&lt;?php</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true"></a><span class="co">// At the top of every PHP file</span></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true"></a><span class="kw">if</span> <span class="ot">(</span> ! <span class="fu">defined</span><span class="ot">(</span> <span class="st">&#39;ABSPATH&#39;</span> <span class="ot">)</span> <span class="ot">)</span> {</span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true"></a>    <span class="kw">exit</span><span class="ot">;</span> <span class="co">// Exit if accessed directly</span></span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true"></a>}</span></code></pre>
</div>
<p>This prevents attackers from executing PHP files outside WordPress context.</p>
<h2 id="secure-ajax-implementation">Secure AJAX Implementation</h2>
<p>AJAX requests need the same security as form submissions:</p>
<div class="sourceCode" id="cb13">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true"></a><span class="co">// Enqueue script with nonce</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true"></a><span class="kw">function</span> dprt_enqueue_ajax_script<span class="ot">()</span> {</span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true"></a>    wp_enqueue_script<span class="ot">(</span> <span class="st">&#39;dprt-ajax&#39;</span><span class="ot">,</span> plugin_dir_url<span class="ot">(</span> <span class="kw">__FILE__</span> <span class="ot">)</span> . <span class="st">&#39;ajax.js&#39;</span><span class="ot">,</span> <span class="kw">array</span><span class="ot">(</span> <span class="st">&#39;jquery&#39;</span> <span class="ot">)</span> <span class="ot">);</span></span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true"></a>    wp_localize_script<span class="ot">(</span> <span class="st">&#39;dprt-ajax&#39;</span><span class="ot">,</span> <span class="st">&#39;dprtAjax&#39;</span><span class="ot">,</span> <span class="kw">array</span><span class="ot">(</span></span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true"></a>        <span class="st">&#39;ajaxurl&#39;</span> =&gt; admin_url<span class="ot">(</span> <span class="st">&#39;admin-ajax.php&#39;</span> <span class="ot">),</span></span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true"></a>        <span class="st">&#39;nonce&#39;</span> =&gt; wp_create_nonce<span class="ot">(</span> <span class="st">&#39;dprt_ajax&#39;</span> <span class="ot">)</span></span>
<span id="cb13-7"><a href="#cb13-7" aria-hidden="true"></a>    <span class="ot">)</span> <span class="ot">);</span></span>
<span id="cb13-8"><a href="#cb13-8" aria-hidden="true"></a>}</span>
<span id="cb13-9"><a href="#cb13-9" aria-hidden="true"></a></span>
<span id="cb13-10"><a href="#cb13-10" aria-hidden="true"></a><span class="co">// AJAX handler</span></span>
<span id="cb13-11"><a href="#cb13-11" aria-hidden="true"></a><span class="kw">function</span> dprt_ajax_handler<span class="ot">()</span> {</span>
<span id="cb13-12"><a href="#cb13-12" aria-hidden="true"></a>    <span class="co">// Verify nonce</span></span>
<span id="cb13-13"><a href="#cb13-13" aria-hidden="true"></a>    check_ajax_referer<span class="ot">(</span> <span class="st">&#39;dprt_ajax&#39;</span><span class="ot">,</span> <span class="st">&#39;nonce&#39;</span> <span class="ot">);</span></span>
<span id="cb13-14"><a href="#cb13-14" aria-hidden="true"></a></span>
<span id="cb13-15"><a href="#cb13-15" aria-hidden="true"></a>    <span class="co">// Check capabilities</span></span>
<span id="cb13-16"><a href="#cb13-16" aria-hidden="true"></a>    <span class="kw">if</span> <span class="ot">(</span> ! current_user_can<span class="ot">(</span> <span class="st">&#39;manage_options&#39;</span> <span class="ot">)</span> <span class="ot">)</span> {</span>
<span id="cb13-17"><a href="#cb13-17" aria-hidden="true"></a>        wp_send_json_error<span class="ot">(</span> <span class="st">&#39;Insufficient permissions&#39;</span> <span class="ot">);</span></span>
<span id="cb13-18"><a href="#cb13-18" aria-hidden="true"></a>    }</span>
<span id="cb13-19"><a href="#cb13-19" aria-hidden="true"></a></span>
<span id="cb13-20"><a href="#cb13-20" aria-hidden="true"></a>    <span class="co">// Sanitize input</span></span>
<span id="cb13-21"><a href="#cb13-21" aria-hidden="true"></a>    <span class="kw">$data</span> = sanitize_text_field<span class="ot">(</span> <span class="kw">$_POST</span><span class="ot">[</span><span class="st">&#39;data&#39;</span><span class="ot">]</span> <span class="ot">);</span></span>
<span id="cb13-22"><a href="#cb13-22" aria-hidden="true"></a></span>
<span id="cb13-23"><a href="#cb13-23" aria-hidden="true"></a>    <span class="co">// Process and respond</span></span>
<span id="cb13-24"><a href="#cb13-24" aria-hidden="true"></a>    wp_send_json_success<span class="ot">(</span> <span class="kw">array</span><span class="ot">(</span> <span class="st">&#39;result&#39;</span> =&gt; <span class="kw">$processed_data</span> <span class="ot">)</span> <span class="ot">);</span></span>
<span id="cb13-25"><a href="#cb13-25" aria-hidden="true"></a>}</span>
<span id="cb13-26"><a href="#cb13-26" aria-hidden="true"></a>add_action<span class="ot">(</span> <span class="st">&#39;wp_ajax_dprt_action&#39;</span><span class="ot">,</span> <span class="st">&#39;dprt_ajax_handler&#39;</span> <span class="ot">);</span></span></code></pre>
</div>
<h2 id="secure-configuration">Secure Configuration</h2>
<p>Never hardcode sensitive information:</p>
<div class="sourceCode" id="cb14">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true"></a><span class="co">// BAD - hardcoded API key</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true"></a><span class="kw">$api_key</span> = <span class="st">&#39;sk_live_123456789&#39;</span><span class="ot">;</span></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true"></a></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true"></a><span class="co">// GOOD - use constants or options</span></span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true"></a><span class="fu">define</span><span class="ot">(</span> <span class="st">&#39;DPRT_API_KEY&#39;</span><span class="ot">,</span> <span class="st">&#39;sk_live_123456789&#39;</span> <span class="ot">);</span> <span class="co">// In wp-config.php</span></span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true"></a><span class="kw">$api_key</span> = <span class="fu">defined</span><span class="ot">(</span> <span class="st">&#39;DPRT_API_KEY&#39;</span> <span class="ot">)</span> <span class="ot">?</span> <span class="kw">DPRT_API_KEY</span> <span class="ot">:</span> get_option<span class="ot">(</span> <span class="st">&#39;dprt_api_key&#39;</span> <span class="ot">);</span></span></code></pre>
</div>
<p>Store sensitive data in wp-config.php or use environment variables.</p>
<h2 id="security-checklist">Security Checklist</h2>
<p>Before releasing your plugin:</p>
<ul class="task-list">
<li><input type="checkbox" disabled="" /><br />
All user input sanitized</li>
<li><input type="checkbox" disabled="" /><br />
All output escaped</li>
<li><input type="checkbox" disabled="" /><br />
Nonces on all forms and AJAX requests</li>
<li><input type="checkbox" disabled="" /><br />
Capability checks on all admin functions</li>
<li><input type="checkbox" disabled="" /><br />
Prepared statements for all database queries</li>
<li><input type="checkbox" disabled="" /><br />
File upload validation</li>
<li><input type="checkbox" disabled="" /><br />
Direct file access prevention</li>
<li><input type="checkbox" disabled="" /><br />
No hardcoded credentials</li>
<li><input type="checkbox" disabled="" /><br />
Security review by another developer</li>
<li><input type="checkbox" disabled="" /><br />
Testing with security plugins</li>
</ul>
<h2 id="conclusion">Conclusion</h2>
<p>Security isn’t a feature—it’s a requirement. Sanitize all input, escape all output, verify nonces, check capabilities, and use prepared statements. These practices protect users and maintain WordPress ecosystem trust. Make security your default mindset, not an afterthought.</p>
<ul>
<li>Secure communication</li>
<li>Using HTTPS for API calls</li>
<li>SSL/TLS certificate validation</li>
<li>Third-party library security</li>
<li>Keeping dependencies updated</li>
<li>Vulnerability scanning tools</li>
<li>Security auditing and code review</li>
<li>Common security mistakes developers make</li>
<li>Security checklist for plugin release</li>
<li>Responsible disclosure of vulnerabilities</li>
</ul>
<p>Includes code examples, security patterns, and testing procedures for building secure, trustworthy WordPress plugins.</p>
<h2 id="external-links">External Links</h2>
<ol type="1">
<li><a href="https://developer.wordpress.org/plugins/security/">WordPress Plugin Security</a></li>
<li><a href="https://developer.wordpress.org/plugins/security/data-validation/">Data Validation Documentation</a></li>
<li><a href="https://owasp.org/www-project-top-ten/">OWASP Top 10</a></li>
<li><a href="https://wordpress.org/about/security/">WordPress Security White Paper</a></li>
<li><a href="https://wpscan.com/wordpress-security-scanner">WPScan Vulnerability Database</a></li>
</ol>
<h2 id="call-to-action">Call to Action</h2>
<p>Supercharge your development! <a href="https://acfcopilotplugin.com/">ACF Copilot Pro</a> generates ACF field groups with AI, exports to PHP, and accelerates custom field workflows—try it free!</p>
<p>The post <a href="https://developryplugins.com/wordpress-plugin-security-best-practices-prevent-common-vulnerabilities/">WordPress Plugin Security Best Practices: Prevent Common Vulnerabilities</a> appeared first on <a href="https://developryplugins.com">Developry Plugins</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
