<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Bug Circuit</title>
    <description>The latest articles on DEV Community by Bug Circuit (@bugcircuit).</description>
    <link>https://dev.to/bugcircuit</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4055584%2Ff7936355-aba9-4105-93b4-28afbc45ea63.png</url>
      <title>DEV Community: Bug Circuit</title>
      <link>https://dev.to/bugcircuit</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bugcircuit"/>
    <language>en</language>
    <item>
      <title>WooCommerce Security Checklist for Stores</title>
      <dc:creator>Bug Circuit</dc:creator>
      <pubDate>Thu, 20 Aug 2026 11:12:21 +0000</pubDate>
      <link>https://dev.to/bugcircuit/woocommerce-security-checklist-for-stores-3jk5</link>
      <guid>https://dev.to/bugcircuit/woocommerce-security-checklist-for-stores-3jk5</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://bugcircuit.com/blog/woocommerce-security-checklist-for-stores" rel="noopener noreferrer"&gt;Bug Circuit blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fastest way to leak customer data on WooCommerce isn't a genius hacker — it's a forgotten plugin update or a stale WordPress core, and you can close both gaps today.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is for store owners running WooCommerce on WordPress who are worried about a breach hitting customer names, addresses, or order history — not developers looking for a code audit. You'll get a concrete checklist you can work through in one sitting, in the order that actually reduces risk fastest.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real risk isn't your server holding credit cards
&lt;/h2&gt;

&lt;p&gt;Most WooCommerce owners picture a breach as someone stealing credit card numbers off their server. In a properly configured store, that's not actually where the risk lives — if you use Stripe, PayPal, or another hosted payment gateway, card numbers never touch your database at all; they go straight from the customer's browser to the payment processor.&lt;/p&gt;

&lt;p&gt;The real exposure is everything else: names, emails, shipping addresses, order history, and admin credentials, sitting in a WordPress database that's reachable through whichever of your 15 plugins hasn't been updated since last year. WordPress core, WooCommerce, and every plugin you install are all separate pieces of software with separate vulnerabilities — and CISA's Known Exploited Vulnerabilities catalog is full of exactly this pattern: attackers scanning the web for sites still running a patched-months-ago plugin version. &lt;a href="https://www.cisa.gov/known-exploited-vulnerabilities-catalog" rel="noopener noreferrer"&gt;CISA KEV Catalog&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The checklist: do these in order
&lt;/h2&gt;

&lt;p&gt;Work down this list top to bottom — it's ordered by how much risk each item removes per minute spent.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Why it matters&lt;/th&gt;
&lt;th&gt;How often&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Update WordPress core, WooCommerce, theme, and every plugin&lt;/td&gt;
&lt;td&gt;Unpatched software is the #1 entry point attackers scan for&lt;/td&gt;
&lt;td&gt;Weekly, or auto-update minor versions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Delete plugins/themes you're not actively using&lt;/td&gt;
&lt;td&gt;Inactive code still runs and still has vulnerabilities&lt;/td&gt;
&lt;td&gt;Today, then quarterly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Turn on two-factor authentication (2FA) for every admin/shop manager account&lt;/td&gt;
&lt;td&gt;Stops stolen passwords from being enough to log in&lt;/td&gt;
&lt;td&gt;Today&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Confirm your payment gateway is hosted checkout / tokenized (Stripe, PayPal, Square)&lt;/td&gt;
&lt;td&gt;Your server never stores or sees full card numbers&lt;/td&gt;
&lt;td&gt;Verify today&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Set &lt;code&gt;DISALLOW_FILE_EDIT&lt;/code&gt; to true in wp-config.php&lt;/td&gt;
&lt;td&gt;Blocks attackers who get admin access from editing theme/plugin code&lt;/td&gt;
&lt;td&gt;Today&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Add strong security headers (HSTS, CSP, X-Frame-Options)&lt;/td&gt;
&lt;td&gt;Reduces damage from XSS and clickjacking&lt;/td&gt;
&lt;td&gt;Today&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Confirm off-site, automated backups are running&lt;/td&gt;
&lt;td&gt;Lets you recover instead of paying a ransom or rebuilding&lt;/td&gt;
&lt;td&gt;Verify today, then weekly checks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;Rename or remove the default "admin" username; enforce unique logins per staff member&lt;/td&gt;
&lt;td&gt;Stops credential-stuffing and makes breach forensics possible&lt;/td&gt;
&lt;td&gt;Today&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;Install a WordPress firewall/malware scanner (Wordfence, Sucuri, or your host's WAF)&lt;/td&gt;
&lt;td&gt;Blocks known attack patterns before they hit your code&lt;/td&gt;
&lt;td&gt;Today, monitor weekly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;Review user roles — no one has Administrator who only needs Shop Manager&lt;/td&gt;
&lt;td&gt;Limits what a compromised account can do&lt;/td&gt;
&lt;td&gt;Monthly&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Update discipline: the single biggest lever
&lt;/h2&gt;

&lt;p&gt;Open &lt;strong&gt;WordPress admin → Dashboard → Updates&lt;/strong&gt; right now and clear everything queued. Then set a recurring habit:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Enable automatic updates for minor WordPress core releases (Settings → this is on by default since WP 3.7 for security releases).&lt;/li&gt;
&lt;li&gt;Update WooCommerce itself as soon as a new version drops — check the changelog for "security" or "vulnerability" language first.&lt;/li&gt;
&lt;li&gt;Go through every installed plugin individually. If a plugin hasn't been updated by its developer in over a year, treat that as a red flag even if no known vulnerability is public yet.&lt;/li&gt;
&lt;li&gt;Delete anything deactivated. A disabled plugin sitting in &lt;code&gt;/wp-content/plugins/&lt;/code&gt; is still a live target if its files are reachable.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This single habit closes more real-world breach paths than almost anything else on this list — most WordPress compromises trace back to a known, already-patched vulnerability in outdated software, which is exactly the pattern OWASP flags under "Vulnerable and Outdated Components" in its Top 10 risks. &lt;a href="https://owasp.org/www-project-top-ten/" rel="noopener noreferrer"&gt;OWASP Top 10&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Lock down who can log in
&lt;/h2&gt;

&lt;p&gt;Your wp-admin login is the front door. Harden it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Enforce 2FA&lt;/strong&gt; for every account with admin or shop manager access — WP 2FA and Wordfence both offer free options.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kill the shared "admin" account.&lt;/strong&gt; Give every staff member and contractor their own login tied to their name, and remove access the day they leave.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limit login attempts.&lt;/strong&gt; Most security plugins add this by default — it stops brute-force password guessing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set roles correctly.&lt;/strong&gt; A customer service rep processing refunds needs Shop Manager, not Administrator. Fewer people with full access means less damage if one account is compromised.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Disable XML-RPC&lt;/strong&gt; if you don't use the WordPress mobile app or Jetpack — it's a common brute-force and DDoS amplification target.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;WordPress.org's own hardening guide covers the server-level version of these steps if you manage your own hosting. &lt;a href="https://wordpress.org/support/article/hardening-wordpress/" rel="noopener noreferrer"&gt;WordPress.org: Hardening WordPress&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep card data off your server entirely
&lt;/h2&gt;

&lt;p&gt;This is the one that keeps owners up at night, and it's also the one with the cleanest fix: &lt;strong&gt;never let WooCommerce or your server touch a raw card number.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use a gateway that tokenizes on the customer's browser — Stripe, Square, and PayPal's hosted fields all do this. WooCommerce's own checkout blocks integrate directly with these.&lt;/li&gt;
&lt;li&gt;If you're on an older, custom-built checkout that stores card fields locally, migrate off it. That configuration puts you in a much heavier PCI DSS assessment category.&lt;/li&gt;
&lt;li&gt;Confirm your gateway plugin settings show "hosted fields" or "tokenized" rather than a raw credit card number field rendered on your own domain.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Done this way, you typically qualify for the simplest PCI compliance self-assessment (SAQ A), because card data never enters your environment. The Payment Card Industry Security Standards Council publishes the official criteria for which SAQ applies to your setup. &lt;a href="https://www.pcisecuritystandards.org/" rel="noopener noreferrer"&gt;PCI Security Standards Council&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Add security headers your browser already understands
&lt;/h2&gt;

&lt;p&gt;Headers are instructions your server sends telling browsers how to treat your site defensively. Add these via your host, a plugin like Wordfence, or your &lt;code&gt;.htaccess&lt;/code&gt;/nginx config:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Strict-Transport-Security: max-age=31536000; includeSubDomains&lt;/code&gt; — forces HTTPS, blocking downgrade attacks.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;X-Frame-Options: SAMEORIGIN&lt;/code&gt; — stops your checkout page from being embedded in a malicious iframe (clickjacking).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;X-Content-Type-Options: nosniff&lt;/code&gt; — stops browsers from misinterpreting uploaded files as executable scripts.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Content-Security-Policy&lt;/code&gt; — restricts which domains can load scripts on your site, a strong defense against injected skimmer scripts (a real WooCommerce attack pattern known as Magecart-style card skimming).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can check what's currently set on your live store, free, with our &lt;a href="https://bugcircuit.com/tools/security-headers" rel="noopener noreferrer"&gt;security headers scanner&lt;/a&gt; — most WooCommerce sites are missing at least two of these out of the box.&lt;/p&gt;

&lt;h2&gt;
  
  
  Back it up before anything else breaks
&lt;/h2&gt;

&lt;p&gt;A backup won't stop a breach, but it's the difference between a bad afternoon and losing your store. Confirm you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automated, scheduled backups (daily for active stores) stored &lt;strong&gt;off&lt;/strong&gt; the same server — UpdraftPlus, host-native backups, or your hosting provider's snapshot system.&lt;/li&gt;
&lt;li&gt;At least one backup you've actually tested restoring, not just one you assume works.&lt;/li&gt;
&lt;li&gt;Database backups included, not just files — WooCommerce order and customer data lives in the database.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Key takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Outdated WordPress core, WooCommerce, or plugins are the most common way small stores get breached — update weekly and delete what you don't use.&lt;/li&gt;
&lt;li&gt;Use a tokenized checkout (Stripe, PayPal, Square) so raw card numbers never touch your server — this also keeps your PCI compliance burden minimal.&lt;/li&gt;
&lt;li&gt;Turn on 2FA, kill shared admin logins, and match user roles to what each person actually needs.&lt;/li&gt;
&lt;li&gt;Add HSTS, CSP, and X-Frame-Options headers, and confirm off-site backups are actually running and restorable.&lt;/li&gt;
&lt;li&gt;A checklist catches configuration gaps; it won't catch a logic flaw or an exposed endpoint specific to your setup — that takes a person actually testing your live site.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Working through this list yourself fixes the common, well-known gaps. What it can't do is find the issue unique to &lt;em&gt;your&lt;/em&gt; store — a misconfigured REST API endpoint, a coupon logic flaw, an exposed staging URL. That's the gap a real &lt;a href="https://bugcircuit.com/pricing" rel="noopener noreferrer"&gt;manual security audit&lt;/a&gt; closes: a person actually testing your checkout and admin, not a scanner running the same generic ruleset every other site gets. If you want a free first read before spending anything, our &lt;a href="https://bugcircuit.com/free-website-security-check" rel="noopener noreferrer"&gt;free website security check&lt;/a&gt; will tell you, no card required, whether anything critical is already exposed.&lt;/p&gt;

</description>
      <category>woocommerce</category>
      <category>wordpresssecurity</category>
      <category>ecommerce</category>
      <category>pcicompliance</category>
    </item>
    <item>
      <title>How to Stop Brute-Force Attacks on WordPress Login</title>
      <dc:creator>Bug Circuit</dc:creator>
      <pubDate>Sun, 16 Aug 2026 23:12:43 +0000</pubDate>
      <link>https://dev.to/bugcircuit/how-to-stop-brute-force-attacks-on-wordpress-login-kbc</link>
      <guid>https://dev.to/bugcircuit/how-to-stop-brute-force-attacks-on-wordpress-login-kbc</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://bugcircuit.com/blog/how-to-stop-brute-force-attacks-on-wordpress-login" rel="noopener noreferrer"&gt;Bug Circuit blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You stop WordPress brute-force login attacks by rate-limiting failed login attempts, requiring two-factor authentication, and closing off the two doors attackers actually use — &lt;code&gt;wp-login.php&lt;/code&gt; and &lt;code&gt;xmlrpc.php&lt;/code&gt; — while skipping the tweaks that feel like security but don't add real protection.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is for anyone running WordPress — a small business owner, an agency managing client sites, or a solo blogger — who's noticed a wall of failed login attempts in their logs, or just wants to get ahead of it. You'll get a step-by-step hardening stack with exact plugin names and config snippets, plus an honest breakdown of what's real defense versus what's just theater.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a brute-force attack on WordPress actually looks like
&lt;/h2&gt;

&lt;p&gt;Most WordPress attacks aren't a person typing passwords by hand. They're bots working through a list — either guessing many passwords against one username (classic brute force), or trying username/password pairs leaked from &lt;em&gt;other&lt;/em&gt; breaches against your site (credential stuffing, per &lt;a href="https://cheatsheetseries.owasp.org/cheatsheets/Credential_Stuffing_Prevention_Cheat_Sheet.html" rel="noopener noreferrer"&gt;OWASP's Credential Stuffing Prevention Cheat Sheet&lt;/a&gt;). Both hit &lt;code&gt;/wp-login.php&lt;/code&gt; (and &lt;code&gt;/wp-admin/&lt;/code&gt;, which just redirects there) at high volume, hoping your admin account uses a weak or reused password.&lt;/p&gt;

&lt;p&gt;There's a second, less obvious front: &lt;code&gt;xmlrpc.php&lt;/code&gt;. This is WordPress's legacy remote-publishing API, and its &lt;code&gt;system.multicall&lt;/code&gt; method lets an attacker bundle hundreds of username/password guesses into a &lt;em&gt;single&lt;/em&gt; HTTP request. That means basic rate limiting — which usually counts requests, not the login attempts hidden inside them — can miss it entirely. This is one of the most useful facts in this guide, because most login-hardening advice ignores it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The hardening stack: what matters vs. what's theater
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Defense&lt;/th&gt;
&lt;th&gt;Actually stops brute force?&lt;/th&gt;
&lt;th&gt;Effort&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Rate-limit / lock out after failed attempts&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Low (plugin)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Two-factor authentication (2FA)&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Low–medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Disable or restrict XML-RPC&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strong, unique passwords + no shared logins&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WAF / edge rate limiting (e.g. Cloudflare)&lt;/td&gt;
&lt;td&gt;Yes, blocks before WordPress even loads&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hide/rename &lt;code&gt;wp-login.php&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Partial — cuts noise, not a real barrier&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rename the "admin" username&lt;/td&gt;
&lt;td&gt;Partial — stops the laziest bots only&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Login CAPTCHA&lt;/td&gt;
&lt;td&gt;Partial — slows automation, not a full stop&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If you only have time for two things, do the first two rows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Limit login attempts and lock accounts out
&lt;/h2&gt;

&lt;p&gt;Install &lt;strong&gt;Limit Login Attempts Reloaded&lt;/strong&gt; (free, wordpress.org) and configure:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Lockout after &lt;strong&gt;4 failed attempts&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Lockout duration: &lt;strong&gt;20 minutes&lt;/strong&gt;, doubling on repeat offenses.&lt;/li&gt;
&lt;li&gt;"Cookie-based brute-force protection" and IP logging turned on so you can see who's knocking.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you're behind Cloudflare (even the free tier), add a rate-limiting rule: block or CAPTCHA-challenge any IP sending more than 5 POST requests to &lt;code&gt;/wp-login.php&lt;/code&gt; within 1 minute. Edge-level rate limiting stops traffic before it ever reaches your server, which matters if you're on shared hosting where WordPress itself can get overwhelmed just processing the attempts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Turn on two-factor authentication (2FA)
&lt;/h2&gt;

&lt;p&gt;This is the single highest-leverage step. Even if a bot guesses your password, it still can't log in without the second factor. Use the official &lt;strong&gt;Two Factor&lt;/strong&gt; plugin (wordpress.org, maintained by WordPress core contributors) or the 2FA module in Wordfence or Solid Security (formerly iThemes Security). Enforce it on every account with Administrator or Editor access — not just yours. CISA lists multi-factor authentication as one of the highest-impact steps anyone can take to prevent account takeover; see their &lt;a href="https://www.cisa.gov/secure-our-world/turn-mfa" rel="noopener noreferrer"&gt;guidance on turning on MFA&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Disable or restrict XML-RPC
&lt;/h2&gt;

&lt;p&gt;Most sites don't need XML-RPC anymore — WordPress 5.6+ added Application Passwords (under &lt;strong&gt;Users → Profile → Application Passwords&lt;/strong&gt;) and a REST API that cover what the old Jetpack/mobile-app integrations used it for. If you don't use the WordPress mobile app or Jetpack's older connection method, block it outright.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Apache (.htaccess):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Files xmlrpc.php&amp;gt;
Require all denied
&amp;lt;/Files&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Nginx:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;location = /xmlrpc.php {
    deny all;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you &lt;em&gt;do&lt;/em&gt; need XML-RPC (some Jetpack features still use it), don't disable the whole file — just remove the dangerous multicall method with a small must-use plugin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nf"&gt;add_filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'xmlrpc_methods'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$methods&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;unset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$methods&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'system.multicall'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$methods&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4: IP-level lockout with fail2ban (self-managed servers/VPS)
&lt;/h2&gt;

&lt;p&gt;If you manage your own server, install the &lt;strong&gt;WP fail2ban&lt;/strong&gt; plugin, which logs failed WordPress login attempts to syslog in a format fail2ban can parse, then add a jail:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[wordpress]
enabled  = true
filter   = wordpress
logpath  = /var/log/auth.log
maxretry = 5
findtime = 600
bantime  = 3600
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This bans the &lt;em&gt;IP address&lt;/em&gt; at the firewall level after repeated failures — the attacker can't even reach &lt;code&gt;wp-login.php&lt;/code&gt; again, not just get denied by it. On managed hosting (WP Engine, Kinsey, most shared hosts) you won't have shell access for this; lean on your host's built-in brute-force protection instead, which most reputable WordPress hosts now include.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Hiding wp-login.php — useful, but don't count on it
&lt;/h2&gt;

&lt;p&gt;Plugins like &lt;strong&gt;WPS Hide Login&lt;/strong&gt; let you change your login URL from &lt;code&gt;/wp-login.php&lt;/code&gt; to something custom, like &lt;code&gt;/portal-access&lt;/code&gt;. This is "security through obscurity" — it doesn't fix a vulnerability, it just makes your site a less visible target to the dumbest, most generic bots scanning the entire internet for &lt;code&gt;/wp-login.php&lt;/code&gt;. It genuinely does cut down log noise and server load. It should never be your &lt;em&gt;only&lt;/em&gt; defense, because a single leaked link, a misconfigured cache, or a targeted attacker (rather than a mass scanner) bypasses it instantly.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's mostly theater
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Renaming the "admin" username alone&lt;/strong&gt; — helps against the laziest scripts, does nothing against credential stuffing using real emails.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A CAPTCHA with no rate limiting behind it&lt;/strong&gt; — slows bots down, doesn't stop a patient attacker.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"We're secure" trust badges&lt;/strong&gt; — cosmetic, provide zero technical protection.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of these are harmful to have, but don't let them substitute for 2FA and rate limiting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick setup checklist
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Login lockout after 4–5 failed attempts (plugin or edge rule)&lt;/li&gt;
&lt;li&gt;[ ] 2FA enforced on every admin/editor account&lt;/li&gt;
&lt;li&gt;[ ] XML-RPC blocked, or &lt;code&gt;system.multicall&lt;/code&gt; removed if you need it&lt;/li&gt;
&lt;li&gt;[ ] Unique, strong passwords — no shared logins across staff&lt;/li&gt;
&lt;li&gt;[ ] fail2ban or host-level IP lockout if you're on a VPS&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.toOptional"&gt; &lt;/a&gt; login URL hidden to cut down bot noise&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're not sure any of this is actually configured correctly on your site, &lt;a href="https://wordpress.org/documentation/article/hardening-wordpress/" rel="noopener noreferrer"&gt;WordPress.org's own hardening guide&lt;/a&gt; is a solid technical reference to check settings against — or run our &lt;a href="https://bugcircuit.com/free-website-security-check" rel="noopener noreferrer"&gt;free passive security check&lt;/a&gt; to see what's exposed without touching your site.&lt;/p&gt;

&lt;p&gt;If you're already seeing signs something's wrong — unfamiliar admin users, spam pages appearing, a host warning you — that's a different problem than prevention; our &lt;a href="https://bugcircuit.com/website-hacked" rel="noopener noreferrer"&gt;guide on what to do if your website's been hacked&lt;/a&gt; walks through the recovery steps. And if you're just trying to figure out your overall exposure before it gets to that point, our guide on &lt;a href="https://bugcircuit.com/guides/is-my-website-hackable" rel="noopener noreferrer"&gt;how to tell if your website is hackable&lt;/a&gt; is a good next read.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Rate limiting plus two-factor authentication stops the overwhelming majority of WordPress brute-force attempts — everything else is secondary.&lt;/li&gt;
&lt;li&gt;XML-RPC's &lt;code&gt;system.multicall&lt;/code&gt; lets attackers test hundreds of passwords in one request, so basic rate limiting alone can miss it — block or restrict it directly.&lt;/li&gt;
&lt;li&gt;Hiding &lt;code&gt;wp-login.php&lt;/code&gt; reduces bot noise but is not a real security control on its own.&lt;/li&gt;
&lt;li&gt;Renaming the "admin" username and adding a CAPTCHA are minor helpers, not defenses — don't rely on them alone.&lt;/li&gt;
&lt;li&gt;If you manage your own server, fail2ban with the WP fail2ban plugin adds real IP-level lockout; on managed hosting, confirm your host already does this.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hardening login is one piece of the picture — it won't catch a vulnerable plugin, an outdated theme, or a misconfigured form elsewhere on the site. A &lt;a href="https://bugcircuit.com/pricing" rel="noopener noreferrer"&gt;Circuit audit&lt;/a&gt; is $49 and gets a real person manually checking your whole site, not just the login page, with a written report of exactly what's wrong and how to fix it. No pressure — it's just the honest next step once the login is locked down.&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>bruteforce</category>
      <category>loginsecurity</category>
      <category>xmlrpc</category>
    </item>
    <item>
      <title>What a Website Security Audit Report Looks Like</title>
      <dc:creator>Bug Circuit</dc:creator>
      <pubDate>Sat, 15 Aug 2026 17:12:10 +0000</pubDate>
      <link>https://dev.to/bugcircuit/what-a-website-security-audit-report-looks-like-31hh</link>
      <guid>https://dev.to/bugcircuit/what-a-website-security-audit-report-looks-like-31hh</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://bugcircuit.com/blog/what-a-website-security-audit-report-looks-like" rel="noopener noreferrer"&gt;Bug Circuit blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A website security audit report is a document that lists every vulnerability a human tester found on your site, ranked by how dangerous it is, with proof it's real and exact steps to fix it — not a scanner printout of vague warnings.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is for anyone about to pay for a security audit (ours or anyone else's) who wants to know what they're actually buying before they hand over a card number. Below is a real, annotated sample report structure with example findings, so you can see exactly what a manual audit produces — and what to be suspicious of if a report doesn't look like this.&lt;/p&gt;

&lt;h2&gt;
  
  
  The three parts every real report has
&lt;/h2&gt;

&lt;p&gt;A legitimate manual audit report has three sections, in this order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Executive summary&lt;/strong&gt; — one page, plain English, no jargon. What was tested, how many issues were found at each severity, and the overall risk picture in 3-4 sentences a non-technical owner can read in 30 seconds.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Findings list&lt;/strong&gt; — every individual vulnerability, one at a time, each with the same fields (below). This is the bulk of the report.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fix guidance&lt;/strong&gt; — for each finding, the exact change to make: a setting to flip, a line to add to a config file, a plugin to update, code to patch.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If a report you're evaluating skips straight from a summary to a generic "harden your site" checklist with no specific findings tied to your actual site, it wasn't a real audit of your site — it was a template.&lt;/p&gt;

&lt;h2&gt;
  
  
  Anatomy of one finding, annotated
&lt;/h2&gt;

&lt;p&gt;Here's what a single, real finding looks like inside the report, field by field.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;What it means&lt;/th&gt;
&lt;th&gt;Example from a real finding&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Title&lt;/td&gt;
&lt;td&gt;Short name for the issue&lt;/td&gt;
&lt;td&gt;Missing HTTP security headers on all pages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Severity&lt;/td&gt;
&lt;td&gt;How bad it is if left unfixed (table below)&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Location&lt;/td&gt;
&lt;td&gt;The exact URL, page, or endpoint affected&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;https://example.com/*&lt;/code&gt; (site-wide)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Description&lt;/td&gt;
&lt;td&gt;What the problem is, in plain English&lt;/td&gt;
&lt;td&gt;Your site doesn't send a &lt;code&gt;Content-Security-Policy&lt;/code&gt; or &lt;code&gt;X-Frame-Options&lt;/code&gt; header, so a browser has no instructions to block malicious scripts or clickjacking attempts if an attacker manages to inject content.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Evidence&lt;/td&gt;
&lt;td&gt;Proof it's real — a screenshot, a response header dump, a request/response pair&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;curl -I https://example.com&lt;/code&gt; response showing no &lt;code&gt;Strict-Transport-Security&lt;/code&gt;, &lt;code&gt;X-Content-Type-Options&lt;/code&gt;, or &lt;code&gt;Content-Security-Policy&lt;/code&gt; headers present&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Impact&lt;/td&gt;
&lt;td&gt;What an attacker could actually do with it&lt;/td&gt;
&lt;td&gt;An attacker who finds a second, smaller bug (like a comment field that isn't sanitized) could chain it with this gap to run scripts in your visitors' browsers or embed your login page in an invisible iframe to steal credentials&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fix&lt;/td&gt;
&lt;td&gt;The exact change to make&lt;/td&gt;
&lt;td&gt;Add these headers via your server config or CDN: &lt;code&gt;Content-Security-Policy: default-src 'self'&lt;/code&gt;, &lt;code&gt;X-Content-Type-Options: nosniff&lt;/code&gt;, &lt;code&gt;Strict-Transport-Security: max-age=31536000; includeSubDomains&lt;/code&gt;, &lt;code&gt;X-Frame-Options: DENY&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reference&lt;/td&gt;
&lt;td&gt;Where to read more&lt;/td&gt;
&lt;td&gt;&lt;a href="https://owasp.org/www-project-secure-headers/" rel="noopener noreferrer"&gt;OWASP Secure Headers Project&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Every finding in a real report has all eight of those fields. If a "finding" is just a sentence with no evidence and no exact fix, that's filler, not an audit result — it's padding a page count, not proving a risk. You can check your own headers right now with our &lt;a href="https://bugcircuit.com/tools/security-headers" rel="noopener noreferrer"&gt;security headers scanner&lt;/a&gt; to see where you'd land before paying for anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  How severity is actually decided
&lt;/h2&gt;

&lt;p&gt;Severity isn't a vibe — it's based on how easy the bug is to exploit and how much damage it causes. Most manual auditors (us included) follow the same logic as the industry-standard &lt;a href="https://owasp.org/www-community/OWASP_Risk_Rating_Methodology" rel="noopener noreferrer"&gt;OWASP Risk Rating Methodology&lt;/a&gt;, which weighs exploitability against impact.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Severity&lt;/th&gt;
&lt;th&gt;What it means&lt;/th&gt;
&lt;th&gt;Typical example&lt;/th&gt;
&lt;th&gt;Fix urgency&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Critical&lt;/td&gt;
&lt;td&gt;Actively exploitable, no login required, major damage (data theft, full takeover)&lt;/td&gt;
&lt;td&gt;SQL injection on a login form; exposed &lt;code&gt;.env&lt;/code&gt; file with database credentials&lt;/td&gt;
&lt;td&gt;Fix within 24-48 hours&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Exploitable with some effort or partial access; serious damage&lt;/td&gt;
&lt;td&gt;Admin panel reachable with a default or weak password; outdated plugin with a public, known exploit&lt;/td&gt;
&lt;td&gt;Fix within a week&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Requires specific conditions or user interaction; moderate damage&lt;/td&gt;
&lt;td&gt;Reflected cross-site scripting (XSS) in a search field; missing security headers&lt;/td&gt;
&lt;td&gt;Fix within a month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Hard to exploit or limited impact on its own&lt;/td&gt;
&lt;td&gt;Verbose server error messages revealing software versions&lt;/td&gt;
&lt;td&gt;Fix when convenient&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Informational&lt;/td&gt;
&lt;td&gt;Not a vulnerability, but worth knowing&lt;/td&gt;
&lt;td&gt;TLS certificate expiring in 60 days&lt;/td&gt;
&lt;td&gt;No action required now, just a heads-up&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For the specific mechanics of an issue like reflected XSS, &lt;a href="https://owasp.org/www-community/attacks/xss/" rel="noopener noreferrer"&gt;OWASP's cross-site scripting page&lt;/a&gt; is the primary reference auditors cite — a good report should link to sources like this instead of just asserting "this is dangerous, trust us."&lt;/p&gt;

&lt;h2&gt;
  
  
  A short sample findings list, as it would appear in a report
&lt;/h2&gt;

&lt;p&gt;Here's what the findings section of a real small-business site report might contain — condensed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;[Critical] Publicly accessible &lt;code&gt;.env&lt;/code&gt; file exposing database credentials&lt;/strong&gt; — &lt;code&gt;https://example.com/.env&lt;/code&gt; returns the raw file instead of a 404. Contains database username, password, and API keys in plain text. Fix: block dotfiles in your web server config (e.g., Apache: &lt;code&gt;&amp;lt;FilesMatch "^\."&amp;gt;Require all denied&amp;lt;/FilesMatch&amp;gt;&lt;/code&gt;) and rotate every credential in the file immediately.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;[High] Outdated WordPress plugin with a known, public vulnerability&lt;/strong&gt; — Contact Form 7 running an old version with a documented flaw listed in the &lt;a href="https://nvd.nist.gov/" rel="noopener noreferrer"&gt;NVD&lt;/a&gt; database. Fix: update to the current version via WordPress admin → Plugins, or remove the plugin if unused. Check &lt;a href="https://www.cisa.gov/known-exploited-vulnerabilities-catalog" rel="noopener noreferrer"&gt;CISA's Known Exploited Vulnerabilities catalog&lt;/a&gt; for anything actively being used in real attacks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;[Medium] Login page has no rate limiting&lt;/strong&gt; — An attacker can attempt unlimited password guesses against &lt;code&gt;/wp-login.php&lt;/code&gt; with no lockout. Fix: install a login-attempt limiter (e.g., Limit Login Attempts Reloaded) or add rate limiting at the server/CDN level.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;[Low] Server reveals its exact software version in error pages&lt;/strong&gt; — Gives an attacker a head start on picking which known exploits to try. Fix: disable detailed error output in production (&lt;code&gt;display_errors = Off&lt;/code&gt; in PHP, or the equivalent in your framework).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Notice each one names a real, specific location on the actual site — never "your site may be vulnerable to XSS somewhere." That specificity is the entire value of paying a human instead of running a free scanner yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Manual report vs. automated scanner printout
&lt;/h2&gt;

&lt;p&gt;The biggest giveaway of a low-effort "audit" is that it's just an automated scan with a cover page. Automated tools are useful and we use them too, but on their own they flag lots of things that aren't actually exploitable, and they miss logic flaws entirely — like a checkout page that lets you edit the price in a hidden form field, or an account page that shows another customer's order if you change a number in the URL. Those require a person actually clicking around and thinking like an attacker. We cover the difference in more depth in our guide to &lt;a href="https://bugcircuit.com/guides/manual-vs-automated-penetration-testing" rel="noopener noreferrer"&gt;manual vs. automated penetration testing&lt;/a&gt; if you want the full breakdown.&lt;/p&gt;

&lt;h2&gt;
  
  
  Checklist: is the report you're about to pay for real?
&lt;/h2&gt;

&lt;p&gt;Before you pay for any audit, check the sample report (a legitimate vendor will show you one) against this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Every finding names an exact URL or location on your actual site — not a generic statement&lt;/li&gt;
&lt;li&gt;[ ] Every finding includes evidence (screenshot, header output, or request/response)&lt;/li&gt;
&lt;li&gt;[ ] Every finding has a severity rating with a stated reason, not just a color&lt;/li&gt;
&lt;li&gt;[ ] Every finding includes a specific fix, not "contact a developer"&lt;/li&gt;
&lt;li&gt;[ ] The report cites external references (OWASP, CISA, NVD) for technical claims&lt;/li&gt;
&lt;li&gt;[ ] There's an executive summary a non-technical owner can actually understand&lt;/li&gt;
&lt;li&gt;[ ] The vendor tells you plainly what was and wasn't tested (scope)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're not sure whether your site even needs this yet, our &lt;a href="https://bugcircuit.com/free-website-security-check" rel="noopener noreferrer"&gt;free website security check&lt;/a&gt; gives you a fast passive read and a plain yes/no on anything critical, no card required — and if you want to understand the risk picture in general first, our guide on &lt;a href="https://bugcircuit.com/guides/is-my-website-hackable" rel="noopener noreferrer"&gt;how to tell if your website is hackable&lt;/a&gt; walks through the warning signs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A real audit report has three parts: executive summary, individual findings, and specific fixes — not just a scanner printout.&lt;/li&gt;
&lt;li&gt;Every finding should include eight things: title, severity, exact location, description, evidence, impact, fix, and a reference.&lt;/li&gt;
&lt;li&gt;Severity should follow a defined methodology (like &lt;a href="https://owasp.org/www-community/OWASP_Risk_Rating_Methodology" rel="noopener noreferrer"&gt;OWASP's Risk Rating Methodology&lt;/a&gt;), not a gut feeling.&lt;/li&gt;
&lt;li&gt;Manual testing catches logic flaws (like editable prices or exposed other-customer data) that automated scanners miss entirely.&lt;/li&gt;
&lt;li&gt;Ask to see a sample report before paying for any audit — a real vendor will show you one without hesitation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to see this done on your own site instead of a sample, &lt;a href="https://bugcircuit.com/pricing" rel="noopener noreferrer"&gt;Circuit&lt;/a&gt; is a $49 one-time manual audit: a real person tests your site and hands you a report built exactly like the one above, with every finding tied to your actual pages and evidence attached — no subscription, no upsell pressure, just the report.&lt;/p&gt;

</description>
      <category>securityaudit</category>
      <category>vulnerabilityreport</category>
      <category>websitesecurity</category>
      <category>owasp</category>
    </item>
    <item>
      <title>Sucuri vs Wordfence: Which One Do You Need?</title>
      <dc:creator>Bug Circuit</dc:creator>
      <pubDate>Fri, 14 Aug 2026 11:12:47 +0000</pubDate>
      <link>https://dev.to/bugcircuit/sucuri-vs-wordfence-which-one-do-you-need-2m7f</link>
      <guid>https://dev.to/bugcircuit/sucuri-vs-wordfence-which-one-do-you-need-2m7f</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://bugcircuit.com/blog/sucuri-vs-wordfence-which-one-do-you-need" rel="noopener noreferrer"&gt;Bug Circuit blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sucuri catches malware after it's already on your site; Wordfence blocks a lot of attacks before they land — most small WordPress sites should start with Wordfence's free plugin and only add Sucuri's paid firewall if they need CDN-level protection or coverage beyond WordPress.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This guide is for owners of small WordPress sites — agencies, local businesses, indie SaaS running on WordPress — trying to decide between Sucuri and Wordfence, or wondering if they need both. You'll get a plain-English breakdown of what each tool actually does, a side-by-side comparison, and a short checklist for picking one. At the end, we cover the part neither tool touches: your actual configuration, user accounts, and custom code — the stuff a scanner can't judge for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Wordfence actually does
&lt;/h2&gt;

&lt;p&gt;Wordfence is a WordPress plugin built by Defiant Inc. It has three main jobs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Endpoint firewall&lt;/strong&gt; — code that loads with WordPress itself, before your theme or plugins run, and blocks malicious requests (SQL injection attempts, known exploit patterns, brute-force logins) at the PHP level.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Malware scanner&lt;/strong&gt; — compares your core files, themes, and plugins against known-good copies and flags anything that's been changed or injected.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Login security&lt;/strong&gt; — two-factor authentication (2FA, a second login step beyond your password), CAPTCHA on the login form, and lockouts after repeated failed attempts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because the firewall runs inside your WordPress install, it only protects that one site — and only WordPress. The free version updates its attack-signature rules on a 30-day delay; Wordfence Premium gets those updates in real time. See Wordfence's own documentation for what each tier includes: &lt;a href="https://www.wordfence.com/help/firewall/" rel="noopener noreferrer"&gt;wordfence.com/help/firewall&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Sucuri actually does
&lt;/h2&gt;

&lt;p&gt;Sucuri (owned by GoDaddy) ships two different things under one name, and mixing them up is where most confusion starts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sucuri Security plugin (free)&lt;/strong&gt; — a WordPress plugin that does malware and integrity scanning, activity logging, and hardening tips. It does &lt;strong&gt;not&lt;/strong&gt; include a firewall.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sucuri Website Firewall (paid)&lt;/strong&gt; — a cloud/DNS-level proxy. You point your domain's DNS at Sucuri, and every visitor's traffic passes through their servers before it ever reaches yours. It filters attacks, includes a CDN (content delivery network, which also speeds up your site), and absorbs DDoS traffic floods.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because the paid firewall sits in front of your DNS rather than inside WordPress, it can protect any platform — Shopify, plain HTML, Magento, WordPress, anything with a domain. Sucuri's paid plans also include malware removal if your site does get infected. Details: &lt;a href="https://sucuri.net/website-firewall/" rel="noopener noreferrer"&gt;sucuri.net/website-firewall&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sucuri vs Wordfence: side-by-side
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Wordfence&lt;/th&gt;
&lt;th&gt;Sucuri&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Firewall location&lt;/td&gt;
&lt;td&gt;On your server (application-level)&lt;/td&gt;
&lt;td&gt;In front of your server (DNS/network-level)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Works on non-WordPress sites&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes (paid firewall)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Free tier includes a firewall&lt;/td&gt;
&lt;td&gt;Yes, with delayed rule updates&lt;/td&gt;
&lt;td&gt;No — scanner only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Includes a CDN&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes (paid plan)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DDoS mitigation&lt;/td&gt;
&lt;td&gt;Limited, server-side only&lt;/td&gt;
&lt;td&gt;Yes — traffic never reaches your server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Malware removal service&lt;/td&gt;
&lt;td&gt;Not built in; manual cleanup&lt;/td&gt;
&lt;td&gt;Included on paid plans&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2FA / login hardening&lt;/td&gt;
&lt;td&gt;Built in, well regarded&lt;/td&gt;
&lt;td&gt;Basic hardening tips only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Performance cost&lt;/td&gt;
&lt;td&gt;Adds PHP processing per request&lt;/td&gt;
&lt;td&gt;Offloads processing to their network&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best fit&lt;/td&gt;
&lt;td&gt;Single WordPress site, tight budget&lt;/td&gt;
&lt;td&gt;Multi-platform, high-traffic, or already-hacked sites&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The application-level vs. network-level distinction matters more than most comparisons admit — it's an architecture difference, not just a feature list, and it changes what each tool can physically stop. OWASP's explainer on web application firewalls covers why placement matters: &lt;a href="https://owasp.org/www-community/Web_Application_Firewall" rel="noopener noreferrer"&gt;owasp.org/www-community/Web_Application_Firewall&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which one do you actually need?
&lt;/h2&gt;

&lt;p&gt;Answer these honestly:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Is your site WordPress-only, on a normal budget?&lt;/strong&gt; Start with Wordfence's free plugin and turn on 2FA for every admin account right away — that alone stops most automated account-takeover attempts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Has your site already been hacked, or do you need cleanup fast?&lt;/strong&gt; Sucuri's paid plan bundles cleanup with the firewall, so you're not paying separately for incident response. See our guide on &lt;a href="https://bugcircuit.com/website-hacked" rel="noopener noreferrer"&gt;what to do if your website's been hacked&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Do you run more than one platform, or need a CDN anyway?&lt;/strong&gt; Sucuri's network-level firewall does double duty as performance infrastructure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Is your hosting slow or resource-limited?&lt;/strong&gt; Sucuri offloads filtering off your server entirely; Wordfence's endpoint firewall adds a small amount of PHP processing to every request.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Do you want strong login protection for a small team?&lt;/strong&gt; Wordfence's 2FA and login security are widely used and well documented.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can run Wordfence's scanner and Sucuri's firewall at the same time without conflict, since one operates at the DNS layer and the other inside WordPress. Just avoid paying for two overlapping firewalls unless you have a specific reason, like wanting Sucuri's CDN but preferring Wordfence's login tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  The gap neither tool covers
&lt;/h2&gt;

&lt;p&gt;Here's the part most comparisons skip: both tools watch for &lt;em&gt;known&lt;/em&gt; attack patterns and file changes. Neither one reads your actual setup and tells you it's wrong. A scanner can't see that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An old contractor's admin account is still active, with a password from years ago and no 2FA.&lt;/li&gt;
&lt;li&gt;Your contact form saves uploaded files to a publicly readable folder.&lt;/li&gt;
&lt;li&gt;A custom plugin your developer wrote builds SQL queries with string concatenation instead of prepared statements.&lt;/li&gt;
&lt;li&gt;A database backup is sitting somewhere public that no scanner ever looks at.&lt;/li&gt;
&lt;li&gt;A staging copy of your site, running an old WordPress version, is still indexed and reachable.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are &lt;strong&gt;security misconfigurations and logic flaws&lt;/strong&gt; — one of the most common categories OWASP tracks in its Top 10 list of web application risks: &lt;a href="https://owasp.org/Top10/A05_2021-Security_Misconfiguration/" rel="noopener noreferrer"&gt;owasp.org/Top10/A05_2021-Security_Misconfiguration&lt;/a&gt;. No signature-based scanner catches a misconfigured permission or an over-privileged account, because there's no known-bad pattern to match — it's simply wrong for &lt;em&gt;your&lt;/em&gt; site.&lt;/p&gt;

&lt;p&gt;This is also why staying current on updates matters regardless of which plugin you run. CISA's guidance on patching is a useful baseline reminder that a firewall doesn't replace timely updates: &lt;a href="https://www.cisa.gov/news-events/news/understanding-patches-and-software-updates" rel="noopener noreferrer"&gt;cisa.gov: Understanding Patches and Software Updates&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  A quick self-check before you decide
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Run a passive check on your headers and DNS setup — our free &lt;a href="https://bugcircuit.com/tools/security-headers" rel="noopener noreferrer"&gt;security headers tool&lt;/a&gt; shows what's missing in under a minute.&lt;/li&gt;
&lt;li&gt;[ ] List every admin and editor account on your site — do they all still need access?&lt;/li&gt;
&lt;li&gt;[ ] Confirm 2FA is on for every account with publish or admin rights.&lt;/li&gt;
&lt;li&gt;[ ] Make sure your backups live somewhere the public internet can't reach.&lt;/li&gt;
&lt;li&gt;[ ] If you're unsure whether your setup is exploitable at all, our &lt;a href="https://bugcircuit.com/guides/is-my-website-hackable" rel="noopener noreferrer"&gt;guide on how to tell if your website is hackable&lt;/a&gt; walks through the warning signs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Where a human audit fits in
&lt;/h2&gt;

&lt;p&gt;Wordfence and Sucuri are both good at what they're built for: catching known attack signatures and known-bad file changes, continuously, for a low yearly cost. Neither is designed to sit down and think about your specific setup the way a person would — reviewing your actual user list, reading your custom code for logic bugs, or noticing that a form field passes user input straight into a database query.&lt;/p&gt;

&lt;p&gt;That's the gap a manual audit fills, and it's a genuinely different kind of check than either plugin runs. For a fuller breakdown of what a scanner catches versus what a person tests, see our &lt;a href="https://bugcircuit.com/guides/manual-vs-automated-penetration-testing" rel="noopener noreferrer"&gt;manual vs. automated penetration testing guide&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Wordfence's firewall runs on your server and protects WordPress only; Sucuri's paid firewall runs at the DNS level and protects any platform, with a CDN included.&lt;/li&gt;
&lt;li&gt;Wordfence's free tier includes a firewall with delayed rule updates; Sucuri's free tier is scan-only — the firewall is a paid add-on.&lt;/li&gt;
&lt;li&gt;You can run both at once without conflict, but paying for two overlapping firewalls rarely makes sense.&lt;/li&gt;
&lt;li&gt;Neither tool checks your admin accounts, custom code, or configuration for logic flaws — that takes a person reviewing your actual setup.&lt;/li&gt;
&lt;li&gt;Run a free passive check first to see what's exposed before deciding which paid tier, if any, you actually need.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bug Circuit's &lt;a href="https://bugcircuit.com/pricing" rel="noopener noreferrer"&gt;$49 manual audit&lt;/a&gt; is built for exactly that gap: a real person checks your site's configuration, accounts, and code — not just file signatures — and hands you a plain-English report of what's wrong and how to fix it. If you want a free yes/no on critical issues first, start with our &lt;a href="https://bugcircuit.com/free-website-security-check" rel="noopener noreferrer"&gt;free website security check&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>sucuri</category>
      <category>wordfence</category>
      <category>wordpresssecurity</category>
      <category>websitefirewall</category>
    </item>
    <item>
      <title>What Is Cross-Site Scripting (XSS)? Plain-English Guide</title>
      <dc:creator>Bug Circuit</dc:creator>
      <pubDate>Wed, 12 Aug 2026 17:12:34 +0000</pubDate>
      <link>https://dev.to/bugcircuit/what-is-cross-site-scripting-xss-plain-english-guide-6ad</link>
      <guid>https://dev.to/bugcircuit/what-is-cross-site-scripting-xss-plain-english-guide-6ad</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://bugcircuit.com/blog/what-is-cross-site-scripting-xss-plain-english-guide" rel="noopener noreferrer"&gt;Bug Circuit blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cross-site scripting (XSS) is a security bug that lets an attacker sneak their own code into a page your visitors trust, so it runs inside their browser as if your site wrote it — quietly stealing login sessions, redirecting payments, or planting fake forms.&lt;/strong&gt; It's one of the oldest and still most common web vulnerabilities, and it doesn't require breaking into your server — just finding one spot on your site that echoes back user input without cleaning it up first.&lt;/p&gt;

&lt;p&gt;This is for owners of WordPress sites, Shopify stores, indie SaaS apps, or small business sites who've heard the term "XSS," maybe seen it flagged by a scanner, and want to know in plain English what it actually does and whether their contact or comment form is a target. By the end, you'll know how to test for it yourself and what a real fix looks like.&lt;/p&gt;

&lt;h2&gt;
  
  
  The short version: how XSS actually works
&lt;/h2&gt;

&lt;p&gt;Every web page is a mix of your content and, sometimes, content your visitors typed in — a comment, a search term, a name field, a support ticket. Your site's job is to display that input back safely, as plain text.&lt;/p&gt;

&lt;p&gt;XSS happens when your site instead treats that input as &lt;em&gt;code&lt;/em&gt; and runs it. If someone types &lt;code&gt;&amp;lt;script&amp;gt;steal_your_cookies()&amp;lt;/script&amp;gt;&lt;/code&gt; into a form and your page prints it straight into the HTML without encoding it, the browser doesn't see text — it sees an instruction to execute. The script isn't hosted on some attacker's server pretending to be you; it runs directly inside your page, in the visitor's browser, with full access to whatever your page can see.&lt;/p&gt;

&lt;p&gt;OWASP, the nonprofit that maintains the standard reference for web vulnerabilities, &lt;a href="https://owasp.org/www-community/attacks/xss/" rel="noopener noreferrer"&gt;defines XSS as an injection attack&lt;/a&gt; where malicious scripts are injected into otherwise trusted, benign websites — and it's serious enough to be folded into the OWASP Top 10's &lt;a href="https://owasp.org/Top10/A03_2021-Injection/" rel="noopener noreferrer"&gt;Injection category&lt;/a&gt;, a list of the most critical risks to web applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  The three flavors of XSS (and why the difference matters)
&lt;/h2&gt;

&lt;p&gt;Not all XSS behaves the same way, and the type affects who's at risk and how urgently it needs fixing.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Where the malicious script lives&lt;/th&gt;
&lt;th&gt;How it usually gets delivered&lt;/th&gt;
&lt;th&gt;Real-world risk&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Stored (persistent) XSS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Saved in your database — a comment, review, forum post, profile bio&lt;/td&gt;
&lt;td&gt;Attacker submits it once through a form&lt;/td&gt;
&lt;td&gt;Every visitor who later views that page runs the script automatically — the most dangerous variant&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Reflected XSS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Bounced back in the page's response, never saved&lt;/td&gt;
&lt;td&gt;A crafted link with the script in the URL, sent via email or ad&lt;/td&gt;
&lt;td&gt;Only affects someone who clicks the malicious link&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;DOM-based XSS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Injected entirely in the browser by client-side JavaScript&lt;/td&gt;
&lt;td&gt;Page JavaScript reads something like the URL fragment and writes it into the page without checking it&lt;/td&gt;
&lt;td&gt;Can happen even if your server-side code is perfectly clean&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Stored XSS is the one to worry about most on a small site, because a single successful comment-form submission can quietly compromise every visitor who reads that page afterward — no clicking required.&lt;/p&gt;

&lt;h2&gt;
  
  
  What an attacker can actually do once their script runs
&lt;/h2&gt;

&lt;p&gt;Once a script executes in a visitor's browser on your domain, it inherits whatever trust that visitor has placed in your site. Concretely, that means an attacker can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hijack a logged-in session.&lt;/strong&gt; Read the session cookie or auth token and reuse it to log in as that user — including an admin — without ever knowing the password.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inject a fake payment form.&lt;/strong&gt; Overlay a convincing "update your card details" box on your real checkout or account page, capturing card numbers that go straight to the attacker instead of your payment processor.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redirect or phish.&lt;/strong&gt; Silently forward the visitor to a lookalike login page, or pop a fake "session expired, log in again" prompt that harvests credentials.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Log keystrokes&lt;/strong&gt; or grab form data before it's even submitted.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deface or spread.&lt;/strong&gt; On stored XSS, the payload can rewrite the page for every subsequent visitor, or worm through comment sections automatically.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of this requires the attacker to find a way into your hosting account or database directly — the browser does the work for them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is your contact or comment form actually exposed?
&lt;/h2&gt;

&lt;p&gt;Any place your site takes text from a stranger and later displays it back — to that same visitor or to anyone else, including your own staff — is a candidate. Common spots on small sites:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Comment sections and product reviews&lt;/li&gt;
&lt;li&gt;Contact forms that echo the name back on a "Thanks, {name}!" confirmation page&lt;/li&gt;
&lt;li&gt;Search boxes that show "No results for {your search}"&lt;/li&gt;
&lt;li&gt;Support/ticket forms an admin later opens in a dashboard&lt;/li&gt;
&lt;li&gt;User profile fields (bio, display name, website URL)&lt;/li&gt;
&lt;li&gt;Any WordPress plugin or theme that hasn't been updated in over a year&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your site is on WordPress, outdated plugins are the single most common source — vulnerable versions get published with fixes in the changelog, so an attacker just needs to know your plugin version. Not sure where you stand? Our &lt;a href="https://bugcircuit.com/free-website-security-check" rel="noopener noreferrer"&gt;free website security check&lt;/a&gt; flags exposed input points and out-of-date software without needing a login or card.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to check it yourself (safely)
&lt;/h2&gt;

&lt;p&gt;You can do a basic, non-destructive test on your &lt;em&gt;own&lt;/em&gt; site — never test a site you don't own or have permission to test.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Find a form field that gets displayed back somewhere (comment box, contact form, search).&lt;/li&gt;
&lt;li&gt;Submit a harmless test string: &lt;code&gt;&amp;lt;script&amp;gt;alert('test')&amp;lt;/script&amp;gt;&lt;/code&gt; or, if angle brackets get stripped, try &lt;code&gt;"&amp;gt;&amp;lt;img src=x onerror=alert(1)&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Load the page where that input is displayed back.&lt;/li&gt;
&lt;li&gt;If a popup box appears saying "test" or "1" — your input isn't being encoded, and that field is vulnerable.&lt;/li&gt;
&lt;li&gt;If the text shows up literally as &lt;code&gt;&amp;lt;script&amp;gt;alert('test')&amp;lt;/script&amp;gt;&lt;/code&gt; on the page (not as a popup), the field is encoding it correctly.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Delete your test comment afterward. This manual check only catches the obvious cases — automated scanners and a trained eye catch far more, including DOM-based XSS that never touches your server logs at all, which is one reason a &lt;a href="https://bugcircuit.com/guides/manual-vs-automated-penetration-testing" rel="noopener noreferrer"&gt;manual review typically finds more than automated scanning alone&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to actually fix it
&lt;/h2&gt;

&lt;p&gt;The fix depends on where the bug lives, but the core principle from OWASP's &lt;a href="https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html" rel="noopener noreferrer"&gt;Cross-Site Scripting Prevention Cheat Sheet&lt;/a&gt; is simple: never let untrusted input become code.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Encode output, don't just filter input.&lt;/strong&gt; Escape special characters (&lt;code&gt;&amp;lt;&lt;/code&gt;, &lt;code&gt;&amp;gt;&lt;/code&gt;, &lt;code&gt;"&lt;/code&gt;, &lt;code&gt;'&lt;/code&gt;, &lt;code&gt;&amp;amp;&lt;/code&gt;) whenever user data is written into HTML, so &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; renders as text, not code. Every modern templating framework (React, Vue, Twig, Blade) does this automatically by default — don't bypass it with functions like &lt;code&gt;dangerouslySetInnerHTML&lt;/code&gt; or &lt;code&gt;v-html&lt;/code&gt; unless the content is sanitized first.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sanitize rich text properly.&lt;/strong&gt; If you must allow some HTML (e.g., a WYSIWYG comment box), run it through a real sanitizer library like &lt;a href="https://github.com/cure53/DOMPurify" rel="noopener noreferrer"&gt;DOMPurify&lt;/a&gt; — don't hand-write a regex filter, which almost always misses an edge case.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set a Content-Security-Policy header.&lt;/strong&gt; This tells the browser which sources of script it's allowed to run, so even an injected &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag gets blocked. A reasonable starting policy: &lt;code&gt;Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'&lt;/code&gt;. See &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy" rel="noopener noreferrer"&gt;MDN's CSP reference&lt;/a&gt; for the full syntax. You can check what headers your site currently sends with our &lt;a href="https://bugcircuit.com/tools/security-headers" rel="noopener noreferrer"&gt;security headers scanner&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lock down cookies so a successful XSS can't be turned into a session hijack.&lt;/strong&gt; Set &lt;code&gt;Set-Cookie: sessionid=&amp;lt;value&amp;gt;; HttpOnly; Secure; SameSite=Strict&lt;/code&gt; — &lt;code&gt;HttpOnly&lt;/code&gt; stops JavaScript from reading the cookie at all, which blunts the most common XSS payoff even if a script does slip through.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep CMS/plugins current and remove unused ones.&lt;/strong&gt; On WordPress, update core, theme, and every plugin promptly, and consider a web application firewall plugin (e.g., Wordfence or Sucuri) as a second layer, not a replacement for fixing the actual code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of these fixes require a rebuild — most are a template change, one HTTP header, and a cookie flag.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;XSS lets an attacker's script run inside your visitors' browsers on your own domain — it doesn't require hacking your server directly.&lt;/li&gt;
&lt;li&gt;Stored XSS (comments, reviews, profile fields) is the highest-risk type because it hits every visitor automatically, not just people who click a bad link.&lt;/li&gt;
&lt;li&gt;Watch any field that echoes user input back — contact forms, search boxes, comments — and test with a harmless &lt;code&gt;&amp;lt;script&amp;gt;alert(1)&amp;lt;/script&amp;gt;&lt;/code&gt; payload on your own site only.&lt;/li&gt;
&lt;li&gt;Fix it with output encoding, a Content-Security-Policy header, and &lt;code&gt;HttpOnly&lt;/code&gt;/&lt;code&gt;Secure&lt;/code&gt;/&lt;code&gt;SameSite&lt;/code&gt; cookie flags — not a hand-rolled filter.&lt;/li&gt;
&lt;li&gt;Automated scanners miss a lot of real-world XSS, especially DOM-based cases; that's the gap a manual review is built to close.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you'd rather have a person check for this instead of guessing from a checklist, that's exactly what &lt;a href="https://bugcircuit.com/pricing" rel="noopener noreferrer"&gt;Circuit&lt;/a&gt; is: a $49 one-time manual audit where a real security engineer tests your forms, comments, and inputs by hand and hands you a written report with exact fixes — not just a scanner printout. If you're not sure your site's been affected already, our guide on &lt;a href="https://bugcircuit.com/guides/is-my-website-hackable" rel="noopener noreferrer"&gt;signs your website might be hackable&lt;/a&gt; is a good next read.&lt;/p&gt;

</description>
      <category>xss</category>
      <category>crosssitescripting</category>
      <category>websecurity</category>
      <category>sessionhijacking</category>
    </item>
    <item>
      <title>What Is a Website Vulnerability? Explained Simply</title>
      <dc:creator>Bug Circuit</dc:creator>
      <pubDate>Thu, 06 Aug 2026 11:12:22 +0000</pubDate>
      <link>https://dev.to/bugcircuit/what-is-a-website-vulnerability-explained-simply-1e9l</link>
      <guid>https://dev.to/bugcircuit/what-is-a-website-vulnerability-explained-simply-1e9l</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://bugcircuit.com/blog/what-is-a-website-vulnerability-explained-simply" rel="noopener noreferrer"&gt;Bug Circuit blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A website vulnerability is a weakness in your site's code, settings, or software that could let someone do something they shouldn't — like read your database, take over an admin account, or deface your homepage.&lt;/strong&gt; It's the &lt;em&gt;flaw&lt;/em&gt;, not the attack itself. Whether that flaw ever gets used against you depends on a few other things we'll walk through below.&lt;/p&gt;

&lt;p&gt;This guide is for site owners who just got a scan report, a security questionnaire from a client, or a vague warning from their host, and are staring at words like "critical severity" or "reflected XSS" with no idea what to do next. By the end, you'll know the difference between a vulnerability, an exploit, and risk; what each severity label actually means; the vulnerability types you'll run into most often; and how to decide what to fix first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vulnerability vs. exploit vs. risk — the three words people mix up
&lt;/h2&gt;

&lt;p&gt;These three words get used interchangeably, but they mean different things, and knowing the difference changes how you react to a report.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Term&lt;/th&gt;
&lt;th&gt;What it means&lt;/th&gt;
&lt;th&gt;Owner-language example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Vulnerability&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The weakness itself — a bug, misconfiguration, or missing protection&lt;/td&gt;
&lt;td&gt;Your contact form doesn't check what type of file gets uploaded&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Exploit&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The actual method or code used to take advantage of that weakness&lt;/td&gt;
&lt;td&gt;Someone uploads a disguised script through that form instead of a resume&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Risk&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The realistic chance and impact of that exploit happening to &lt;em&gt;your&lt;/em&gt; site&lt;/td&gt;
&lt;td&gt;Low risk if the form is rarely used and files aren't executed; high risk if uploaded files are stored in a public, executable folder&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The U.S. government's official definition, from NIST's Computer Security Resource Center glossary, calls a vulnerability a "weakness in an information system... that could be exploited by a threat source" — note the word &lt;em&gt;could&lt;/em&gt;. A vulnerability existing doesn't mean you've been attacked; it means the door isn't fully locked yet. (Source: &lt;a href="https://csrc.nist.gov/glossary/term/vulnerability" rel="noopener noreferrer"&gt;NIST CSRC Glossary, "vulnerability"&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;That's also why two sites with the identical vulnerability can carry very different risk. A stale WordPress plugin on a personal blog is a nuisance. The same plugin on a site processing customer credit cards is a real problem — same vulnerability, very different risk. This is the piece automated scanners are worst at, and it's the main thing a human reviewer adds: judgment about &lt;em&gt;your&lt;/em&gt; actual setup, not just a checklist match. Our &lt;a href="https://bugcircuit.com/guides/manual-vs-automated-penetration-testing" rel="noopener noreferrer"&gt;guide to manual vs. automated penetration testing&lt;/a&gt; goes deeper on why that context matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  How severity ratings actually work
&lt;/h2&gt;

&lt;p&gt;Most scan reports label each finding Critical, High, Medium, or Low. These labels usually trace back to CVSS (Common Vulnerability Scoring System), an industry-standard 0–10 scoring formula maintained by FIRST.org and used in the U.S. National Vulnerability Database. The score weighs things like: can it be exploited remotely with no login required, does it need user interaction, and what does the attacker gain — read access, full control, or just a crash?&lt;/p&gt;

&lt;p&gt;Here's how NVD maps the numeric score to the label you see on your report:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;CVSS v3.1 score&lt;/th&gt;
&lt;th&gt;Severity label&lt;/th&gt;
&lt;th&gt;Rough translation for owners&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;9.0 – 10.0&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Critical&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Fix immediately — remote takeover or full data exposure with little effort&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7.0 – 8.9&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;High&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Fix this week — serious impact, though it may need specific conditions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4.0 – 6.9&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Medium&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Fix this month — real but limited impact, or harder to pull off&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.1 – 3.9&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Low&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Fix when convenient — minor impact or very hard to exploit&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;(Source: &lt;a href="https://nvd.nist.gov/vuln-metrics/cvss" rel="noopener noreferrer"&gt;NVD Vulnerability Metrics / CVSS&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Two caveats worth knowing. First, severity measures &lt;em&gt;technical&lt;/em&gt; impact, not your business impact — a Medium finding on your customer database can matter more to you than a Critical finding on a page nobody visits. Second, CISA maintains a separate list called the Known Exploited Vulnerabilities (KEV) catalog, tracking flaws that attackers are &lt;em&gt;actively&lt;/em&gt; using in the wild right now, regardless of their CVSS score. If a vulnerability on your site shows up there, treat it as urgent no matter what label a scanner gave it. (Source: &lt;a href="https://www.cisa.gov/known-exploited-vulnerabilities-catalog" rel="noopener noreferrer"&gt;CISA Known Exploited Vulnerabilities Catalog&lt;/a&gt;)&lt;/p&gt;

&lt;h2&gt;
  
  
  The vulnerability types you'll actually see on a small-site report
&lt;/h2&gt;

&lt;p&gt;Most small-business site findings fall into a handful of buckets tracked by OWASP, the nonprofit that maintains the industry-standard list of web app risks. You don't need to memorize the names — just recognize the shape of the problem when you see it.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category (OWASP Top 10)&lt;/th&gt;
&lt;th&gt;Plain-English description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Broken access control&lt;/td&gt;
&lt;td&gt;A logged-in user (or nobody at all) can reach pages, files, or data they shouldn't — e.g., changing a URL's ID number to view someone else's order&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Injection (SQLi, XSS)&lt;/td&gt;
&lt;td&gt;Untrusted input gets treated as code — a comment box or search bar lets an attacker run database commands or scripts in visitors' browsers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Security misconfiguration&lt;/td&gt;
&lt;td&gt;Default passwords, open admin panels, directory listing left on, or debug mode exposed on a live site&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vulnerable/outdated components&lt;/td&gt;
&lt;td&gt;An old plugin, theme, or library with a known, published bug that hasn't been patched&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Authentication failures&lt;/td&gt;
&lt;td&gt;Weak or reused passwords, no lockout after failed logins, no multi-factor login option&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cryptographic failures&lt;/td&gt;
&lt;td&gt;Sensitive data (passwords, card numbers) sent or stored without proper encryption, or an expired/misconfigured SSL certificate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Missing security headers&lt;/td&gt;
&lt;td&gt;The site doesn't tell browsers to enforce HTTPS, block content-sniffing, or restrict where scripts can load from&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;(Source: &lt;a href="https://owasp.org/www-project-top-ten/" rel="noopener noreferrer"&gt;OWASP Top 10&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;A few of these you can spot yourself in minutes. Our free &lt;a href="https://bugcircuit.com/tools/security-headers" rel="noopener noreferrer"&gt;security headers checker&lt;/a&gt; scans for that last row instantly, and our &lt;a href="https://bugcircuit.com/guides/is-my-website-hackable" rel="noopener noreferrer"&gt;guide on whether your website is hackable&lt;/a&gt; walks through the visible warning signs for the others.&lt;/p&gt;

&lt;h2&gt;
  
  
  A quick self-check before you panic (or don't)
&lt;/h2&gt;

&lt;p&gt;When a report lands, run through this before deciding what to prioritize:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Read the finding title, not just the severity tag.&lt;/strong&gt; "SQL Injection on login form" is worse than a Critical-labeled but theoretical issue that needs local server access.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check if it's on the live site or just staging/dev.&lt;/strong&gt; A vulnerability on a password-protected dev environment is far lower real-world risk.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ask what data or access it touches.&lt;/strong&gt; Customer emails and payment data matter more than a typo on an unused page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check the CISA KEV catalog&lt;/strong&gt; if a CVE number is listed — is this being actively exploited right now, anywhere?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confirm it's not a false positive.&lt;/strong&gt; Automated scanners frequently flag things that a human glance rules out in seconds — this is the single biggest source of wasted panic for small site owners.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you're already seeing strange behavior — unexpected admin users, spam pages appearing, a host warning — that's a different situation than a routine scan finding. Our &lt;a href="https://bugcircuit.com/website-hacked" rel="noopener noreferrer"&gt;what to do if your website's been hacked&lt;/a&gt; guide covers the immediate response steps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;vulnerability&lt;/strong&gt; is the weakness, an &lt;strong&gt;exploit&lt;/strong&gt; is the method used against it, and &lt;strong&gt;risk&lt;/strong&gt; is how much it actually matters for your specific site — a report should never be read as "vulnerability = you're already hacked."&lt;/li&gt;
&lt;li&gt;Severity labels (Critical/High/Medium/Low) come from CVSS scoring 0–10, but they measure technical impact only — always weigh a finding against what data or access it actually touches on your site.&lt;/li&gt;
&lt;li&gt;If a CVE is listed on CISA's Known Exploited Vulnerabilities catalog, treat it as urgent regardless of its severity label.&lt;/li&gt;
&lt;li&gt;Most small-site findings fall into a few repeatable buckets — outdated plugins, missing headers, weak access control, injection flaws — and each has a well-known, standard fix.&lt;/li&gt;
&lt;li&gt;Automated scans are a good first pass but flag plenty of noise; a human reviewer who understands your specific setup is what turns a scary-looking list into a short, correctly prioritized to-do.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you'd rather not decode a scan report alone, a real engineer can manually audit your site and hand you a plain-English list of what's actually urgent, with exact fixes — &lt;a href="https://bugcircuit.com/pricing" rel="noopener noreferrer"&gt;Circuit&lt;/a&gt; starts at $49, one time, no subscription required.&lt;/p&gt;

</description>
      <category>vulnerabilities</category>
      <category>severityratings</category>
      <category>riskassessment</category>
      <category>owasp</category>
    </item>
    <item>
      <title>What Is SQL Injection? How a Form Leaks Data</title>
      <dc:creator>Bug Circuit</dc:creator>
      <pubDate>Sat, 01 Aug 2026 23:13:49 +0000</pubDate>
      <link>https://dev.to/bugcircuit/what-is-sql-injection-how-a-form-leaks-data-fil</link>
      <guid>https://dev.to/bugcircuit/what-is-sql-injection-how-a-form-leaks-data-fil</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://bugcircuit.com/blog/what-is-sql-injection-how-a-form-leaks-data" rel="noopener noreferrer"&gt;Bug Circuit blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SQL injection is when an attacker types database commands into an ordinary web form — a search box, a login field, a "forgot password" box — and your website mistakenly runs those commands, often handing over every row in your database.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Who this is for
&lt;/h2&gt;

&lt;p&gt;You run a small business website — a WordPress store, a Shopify-adjacent tool, an indie SaaS, or a site your agency built years ago — and someone mentioned "SQL injection" in a security questionnaire, a scary blog post, or a scan report. This guide explains what it actually is, how a single unprotected form can leak your whole customer and orders table, why "nobody's targeting little old me" doesn't protect you, and exactly what to check and fix. No jargon left unexplained.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is SQL Injection, in Plain English?
&lt;/h2&gt;

&lt;p&gt;Your website's database (usually MySQL, PostgreSQL, or similar) stores everything: customer logins, orders, emails, sometimes payment references. To talk to that database, your website's code writes instructions in a language called &lt;strong&gt;SQL&lt;/strong&gt; (Structured Query Language) — for example, "get me the customer whose email is X."&lt;/p&gt;

&lt;p&gt;The problem happens when a developer builds that instruction by gluing raw user input directly into the command, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'" + userInput + "'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;userInput&lt;/code&gt; is a normal email address, this works fine. But if an attacker types something like &lt;code&gt;' OR '1'='1&lt;/code&gt; into that box instead of an email, the database now reads a completely different instruction:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="s1"&gt;'1'&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'1'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since &lt;code&gt;'1'='1'&lt;/code&gt; is always true, the database returns &lt;em&gt;every&lt;/em&gt; user — not the one row the form intended. That's SQL injection: user input escaping the box it was meant to stay in and being executed as a command. &lt;a href="https://owasp.org/www-community/attacks/SQL_Injection" rel="noopener noreferrer"&gt;OWASP's SQL Injection reference&lt;/a&gt; has the full technical breakdown, and injection flaws have sat in the &lt;a href="https://owasp.org/Top10/A03_2021-Injection/" rel="noopener noreferrer"&gt;OWASP Top 10&lt;/a&gt; — the industry's standard list of the most common, most serious web application risks — for over two decades.&lt;/p&gt;

&lt;h2&gt;
  
  
  How One Search Box Can Leak an Entire Database
&lt;/h2&gt;

&lt;p&gt;A login form is the classic example, but a &lt;em&gt;search box&lt;/em&gt; is often worse, because search queries are naturally built from user text and often aren't protected as carefully.&lt;/p&gt;

&lt;p&gt;Say your site has a product search that runs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;LIKE&lt;/span&gt; &lt;span class="s1"&gt;'%searchterm%'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If that query isn't built safely, an attacker can type a search term that isn't a search term at all — it's a &lt;strong&gt;UNION-based injection&lt;/strong&gt;, which stitches a second, attacker-chosen query onto the first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="s1"&gt;' UNION SELECT email, password FROM users -- 
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If it works, the "product search" results page now quietly displays customer emails and password hashes instead of products. From there, an attacker can usually enumerate table names, dump the orders table, or pull payment-related fields — all through a box that was only ever supposed to filter a product list. No login required, no password guessed. One text field with no guardrails was the entire perimeter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why "We're Too Small to Target" Doesn't Hold Up
&lt;/h2&gt;

&lt;p&gt;The instinct — "my site has 200 customers, nobody cares" — misunderstands how these attacks actually happen in 2026. Almost no one is manually typing payloads into your search box because they've heard of your business. Automated bots continuously crawl the open web, fingerprint what software and plugins a site is running, and fire known injection payloads at every form field they find — at a scale of thousands of sites per hour, with zero regard for how small you are.&lt;/p&gt;

&lt;p&gt;This is exactly why CISA and the FBI issued a joint alert urging software makers to eliminate SQL injection through secure design, rather than treat it as a risk individual site owners can outsmart with obscurity — see &lt;a href="https://www.cisa.gov/resources-tools/resources/secure-by-design" rel="noopener noreferrer"&gt;CISA's Secure by Design alert on SQL injection&lt;/a&gt;. A vulnerable field is vulnerable whether one person or one million people know your brand name. If you want a sense of how exposed your specific site looks to that kind of automated scanning, our &lt;a href="https://bugcircuit.com/free-website-security-check" rel="noopener noreferrer"&gt;free website security check&lt;/a&gt; runs a passive pass with no card and no login required.&lt;/p&gt;

&lt;h2&gt;
  
  
  What It Looks Like When It Happens
&lt;/h2&gt;

&lt;p&gt;SQL injection incidents on small sites tend to follow one of a few patterns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Login bypass&lt;/strong&gt; — attacker logs in as admin without a real password, using an &lt;code&gt;OR '1'='1'&lt;/code&gt;-style payload.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data dump&lt;/strong&gt; — attacker uses &lt;code&gt;UNION SELECT&lt;/code&gt; to pull customer emails, hashed passwords, or order history out through a search or filter field.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blind injection&lt;/strong&gt; — the page doesn't show data directly, but the attacker asks the database true/false questions one bit at a time (does row 1 start with 'a'? 'b'? ...) until they've reconstructed the data — slower, but works even when nothing looks obviously broken.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Destructive injection&lt;/strong&gt; — instead of reading data, the attacker deletes or alters it (&lt;code&gt;DROP TABLE&lt;/code&gt;), which is rarer but far more damaging to recover from.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're trying to work out whether an incident like this has already happened to you, our guide on &lt;a href="https://bugcircuit.com/website-hacked" rel="noopener noreferrer"&gt;signs your website may have been hacked&lt;/a&gt; walks through the concrete indicators to check first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is Your Site at Risk? A 5-Minute Checklist
&lt;/h2&gt;

&lt;p&gt;You don't need to read code to get a first read on your exposure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] &lt;strong&gt;Any custom-built form or search box&lt;/strong&gt; (not a stock plugin) that a developer wrote from scratch to query your database.&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Old or unmaintained plugins/themes&lt;/strong&gt;, especially on WordPress — outdated database-querying plugins are a common source.&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Error messages that reveal SQL&lt;/strong&gt; — try typing a single quote &lt;code&gt;'&lt;/code&gt; into a search or login field. If you see a database error mentioning "SQL syntax" or a table/column name, that's a strong red flag.&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;No web application firewall (WAF)&lt;/strong&gt; in front of the site (Cloudflare, Sucuri, or similar) filtering malicious-looking requests.&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;A database user with full admin rights&lt;/strong&gt; used for the website's day-to-day queries, instead of a limited-permission account.&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;No recent professional review&lt;/strong&gt; of the code that handles forms, search, and login.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you checked more than one box, treat it as a real priority, not a someday task.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Developers Fix It (and How to Verify the Fix)
&lt;/h2&gt;

&lt;p&gt;The fix is well-established: never let raw user input become part of the SQL command itself. Instead, the query structure is fixed in advance, and user input is passed in separately as a value — called a &lt;strong&gt;parameterized query&lt;/strong&gt; or &lt;strong&gt;prepared statement&lt;/strong&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Language / stack&lt;/th&gt;
&lt;th&gt;Vulnerable pattern (avoid)&lt;/th&gt;
&lt;th&gt;Safe pattern (use)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;PHP + MySQL&lt;/td&gt;
&lt;td&gt;&lt;code&gt;"SELECT * FROM users WHERE email='$email'"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;mysqli_prepare()&lt;/code&gt; / PDO with &lt;code&gt;?&lt;/code&gt; placeholders and &lt;code&gt;bindParam&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Node.js + MySQL&lt;/td&gt;
&lt;td&gt;Template string built into &lt;code&gt;query()&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;connection.query('...WHERE email = ?', [email])&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Python + PostgreSQL&lt;/td&gt;
&lt;td&gt;f-string built into &lt;code&gt;cursor.execute()&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;cursor.execute("...WHERE email = %s", (email,))&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WordPress plugins&lt;/td&gt;
&lt;td&gt;Raw &lt;code&gt;$wpdb-&amp;gt;query()&lt;/code&gt; with variables inline&lt;/td&gt;
&lt;td&gt;&lt;code&gt;$wpdb-&amp;gt;prepare()&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;On top of parameterized queries, a solid fix also includes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Least-privilege database accounts&lt;/strong&gt; — the account your website uses shouldn't be able to &lt;code&gt;DROP&lt;/code&gt; tables or read databases it doesn't need.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A WAF&lt;/strong&gt; as a second layer that blocks obvious injection payloads before they reach your app.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generic error pages&lt;/strong&gt; — never show raw database errors to visitors; log them internally instead.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Regular patching&lt;/strong&gt; of your CMS, plugins, and frameworks, since many public SQL injection reports are tied to specific vendor versions.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Verifying this properly — confirming every form actually uses parameterized queries rather than just "looking fine" in a browser — is genuinely a job for a human reviewing the code and testing each input field, not a five-minute self-check. That's the gap between an automated scanner glancing at your site and someone actually trying the payloads by hand; our guide on &lt;a href="https://bugcircuit.com/guides/manual-vs-automated-penetration-testing" rel="noopener noreferrer"&gt;manual vs. automated penetration testing&lt;/a&gt; explains the difference in plain terms if you want to understand what you're paying for either way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;SQL injection happens when user input (search terms, login fields) gets executed as a database command instead of being treated as plain text — a decades-old, still-common flaw per &lt;a href="https://owasp.org/Top10/A03_2021-Injection/" rel="noopener noreferrer"&gt;OWASP&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;One vulnerable search box or login field can expose your entire customer and orders database — no password-guessing required.&lt;/li&gt;
&lt;li&gt;Automated bots scan for this constantly and don't care how small you are; "too small to target" is not a defense.&lt;/li&gt;
&lt;li&gt;The real fix is parameterized queries everywhere user input touches the database, plus least-privilege DB accounts, a WAF, and hidden error messages.&lt;/li&gt;
&lt;li&gt;A quick self-check (try typing &lt;code&gt;'&lt;/code&gt; into your forms) can flag obvious problems, but only a human review can confirm every field is actually safe.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Not sure where you stand?
&lt;/h2&gt;

&lt;p&gt;You don't need to take our word for any of this — start with the &lt;a href="https://bugcircuit.com/free-website-security-check" rel="noopener noreferrer"&gt;free passive security check&lt;/a&gt;, which gives you a quick yes/no read on critical issues with no card and no login. If you want someone to actually try these payloads against your forms and hand you a plain-English report of exactly what's exposed and how to fix it, that's what our &lt;a href="https://bugcircuit.com/pricing" rel="noopener noreferrer"&gt;$49 manual audit&lt;/a&gt; is for — a real engineer testing your site by hand, not another automated scan.&lt;/p&gt;

</description>
      <category>sqlinjection</category>
      <category>webapplicationsecurity</category>
      <category>owasp</category>
      <category>websitesecurity</category>
    </item>
    <item>
      <title>Domain Blacklisted? How to Delist and Recover</title>
      <dc:creator>Bug Circuit</dc:creator>
      <pubDate>Fri, 31 Jul 2026 20:42:16 +0000</pubDate>
      <link>https://dev.to/bugcircuit/domain-blacklisted-how-to-delist-and-recover-44oj</link>
      <guid>https://dev.to/bugcircuit/domain-blacklisted-how-to-delist-and-recover-44oj</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://bugcircuit.com/blog/domain-blacklisted-how-to-delist-and-recover" rel="noopener noreferrer"&gt;Bug Circuit blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A blacklisted domain almost always means your site or your email sending was compromised and abused for spam or malware — the fix is to clean up the actual security hole first, then request delisting directly from Spamhaus, Barracuda, and/or Google Safe Browsing through their official removal tools.&lt;/strong&gt; Skipping straight to the delisting request without fixing the cause is the single biggest reason domains get re-listed within days.&lt;/p&gt;

&lt;p&gt;This is for small business owners, indie SaaS founders, and agencies who got a bounced-email notice mentioning "blocked" or "blacklisted," or who opened their site in Chrome and saw a red "Dangerous site" warning. You'll get the exact delisting steps for the three blacklists that cause the most real-world pain, plus the root-cause checklist that actually keeps you off the list.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why domains get blacklisted in the first place
&lt;/h2&gt;

&lt;p&gt;Blacklists (also called blocklists or RBLs — real-time blackhole lists) exist so email providers and browsers can automatically reject traffic from known-bad sources. Your domain or IP doesn't get flagged at random. It's almost always one of these:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A compromised website&lt;/strong&gt; is sending spam through a mail script, a hacked contact form, or a webshell an attacker installed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Malware or a phishing kit&lt;/strong&gt; got uploaded to your site (often through an outdated plugin or theme), so Google Safe Browsing flags visitors before they load the infected page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Weak email authentication&lt;/strong&gt; — no SPF, DKIM, or DMARC — let someone spoof your domain to send phishing or spam, which mail providers then trace back to you.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A shared host or reused password&lt;/strong&gt; got breached elsewhere, and the same credentials were reused to log into your site or hosting panel.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;a href="https://owasp.org/Top10/A05_2021-Security_Misconfiguration/" rel="noopener noreferrer"&gt;OWASP Top 10 guidance on security misconfiguration&lt;/a&gt; covers exactly the kind of default settings, exposed admin panels, and unpatched software that lead to this chain of events. If you're not sure which of these applies to you, our guide on &lt;a href="https://bugcircuit.com/guides/is-my-website-hackable" rel="noopener noreferrer"&gt;whether your site is actually hackable&lt;/a&gt; walks through the common entry points.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Confirm which blacklist you're actually on
&lt;/h2&gt;

&lt;p&gt;Don't guess — check first, because each list has a different removal process. Two free ways to check:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;MXToolbox Blacklist Check&lt;/strong&gt; (mxtoolbox.com/blacklists.aspx) — enter your domain or mail server IP and it queries dozens of blacklists at once, including Spamhaus and Barracuda.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google Safe Browsing Transparency Report&lt;/strong&gt; (transparencyreport.google.com/safe-browsing/search) — enter your domain to see if Google currently flags it as unsafe and why.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you got a specific bounce message from a mail server, read it carefully — it usually names the exact list (e.g., "550 5.7.1 blocked by Spamhaus SBL") and often includes a lookup link.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to delist from Spamhaus
&lt;/h2&gt;

&lt;p&gt;Spamhaus runs several lists — the most common for small businesses are the &lt;strong&gt;SBL&lt;/strong&gt; (IP-based, spam sources) and the &lt;strong&gt;DBL&lt;/strong&gt; (Domain Block List, for domains used in spam links or phishing).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to Spamhaus's own lookup tool at &lt;strong&gt;check.spamhaus.org&lt;/strong&gt; and enter your domain or IP.&lt;/li&gt;
&lt;li&gt;If listed, click through to the specific listing page — it explains &lt;em&gt;why&lt;/em&gt; you were listed (spam trap hit, phishing URL, compromised host, etc.).&lt;/li&gt;
&lt;li&gt;Fix the underlying issue (see the root-cause checklist below) &lt;strong&gt;before&lt;/strong&gt; submitting removal — Spamhaus explicitly asks you to confirm the problem is resolved.&lt;/li&gt;
&lt;li&gt;Submit a removal request through the link on that listing page. Spamhaus's &lt;a href="https://www.spamhaus.org/faq/section/Spamhaus%20DBL" rel="noopener noreferrer"&gt;official FAQ on the Domain Block List&lt;/a&gt; explains what evidence they expect and how long review typically takes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Spamhaus removals are usually processed within a few hours to a couple of days once you've genuinely fixed the cause.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to delist from Barracuda (BRBL)
&lt;/h2&gt;

&lt;p&gt;Barracuda's Reputation Block List is common on corporate mail servers and G Suite/Microsoft 365 gateways that use Barracuda filtering.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check your status at &lt;strong&gt;barracudacentral.org/lookups&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;If listed, go to Barracuda's official &lt;strong&gt;&lt;a href="https://www.barracudacentral.org/rbl/removal-request" rel="noopener noreferrer"&gt;removal request form&lt;/a&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Enter the flagged IP or domain and submit. Barracuda's system runs an automated re-check; if your mail server no longer shows spam-like behavior, it's typically delisted within a few hours.&lt;/li&gt;
&lt;li&gt;If it relists shortly after, that's a strong signal the compromise wasn't actually fixed — go back to the root-cause checklist.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How to delist from Google Safe Browsing
&lt;/h2&gt;

&lt;p&gt;This is the one that shows visitors a full-page red warning, so it hurts the most visibly.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Verify your site in &lt;strong&gt;Google Search Console&lt;/strong&gt; (search.google.com/search-console) if you haven't already.&lt;/li&gt;
&lt;li&gt;Open the &lt;strong&gt;Security Issues&lt;/strong&gt; report in the left sidebar. Google lists exactly what it found — injected spam content, malware, or a phishing page — and often the specific infected URLs.&lt;/li&gt;
&lt;li&gt;Remove the malicious code, files, or redirects (see checklist below).&lt;/li&gt;
&lt;li&gt;Back in Search Console, click &lt;strong&gt;Request a Review&lt;/strong&gt; and describe what you fixed.&lt;/li&gt;
&lt;li&gt;Google typically re-crawls and clears flagged sites within a few days if the issue is genuinely resolved; see Google's own &lt;a href="https://developers.google.com/search/docs/monitor-debug/security/hacked-overview" rel="noopener noreferrer"&gt;"Fix hacked pages" guide&lt;/a&gt; for the full remediation walkthrough they expect before you request review.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Blacklist comparison at a glance
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Blacklist&lt;/th&gt;
&lt;th&gt;What it flags&lt;/th&gt;
&lt;th&gt;Where to check&lt;/th&gt;
&lt;th&gt;Where to request removal&lt;/th&gt;
&lt;th&gt;Typical turnaround&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Spamhaus SBL/DBL&lt;/td&gt;
&lt;td&gt;Spam-sending IPs, spammy/phishing domains&lt;/td&gt;
&lt;td&gt;check.spamhaus.org&lt;/td&gt;
&lt;td&gt;Listing page → removal link&lt;/td&gt;
&lt;td&gt;Hours–2 days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Barracuda BRBL&lt;/td&gt;
&lt;td&gt;Spam-sending mail servers&lt;/td&gt;
&lt;td&gt;barracudacentral.org/lookups&lt;/td&gt;
&lt;td&gt;barracudacentral.org/rbl/removal-request&lt;/td&gt;
&lt;td&gt;Hours–1 day&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google Safe Browsing&lt;/td&gt;
&lt;td&gt;Malware, phishing pages on your site&lt;/td&gt;
&lt;td&gt;Search Console → Security Issues&lt;/td&gt;
&lt;td&gt;Search Console → Request Review&lt;/td&gt;
&lt;td&gt;1–5 days&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Fix the root cause first — or you'll be back on the list
&lt;/h2&gt;

&lt;p&gt;This is the step people skip, and it's why the same domain shows up on these lists again and again. Before requesting delisting, work through this checklist:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Scan every file on the server for unexpected PHP/JS files, especially in &lt;code&gt;/uploads&lt;/code&gt;, &lt;code&gt;/tmp&lt;/code&gt;, and theme/plugin folders (webshells often hide with names close to legitimate files).&lt;/li&gt;
&lt;li&gt;[ ] Check for unauthorized admin accounts or unfamiliar users in your CMS.&lt;/li&gt;
&lt;li&gt;[ ] Rotate &lt;strong&gt;every&lt;/strong&gt; credential: hosting panel, CMS admin, database, FTP/SFTP, and any API keys stored in config files.&lt;/li&gt;
&lt;li&gt;[ ] Update the CMS core, all plugins, and the theme to the latest versions — most compromises come through a known, already-patched vulnerability.&lt;/li&gt;
&lt;li&gt;[ ] Check &lt;code&gt;.htaccess&lt;/code&gt;, &lt;code&gt;wp-config.php&lt;/code&gt;, and any cron jobs for injected redirects or scheduled scripts you didn't add.&lt;/li&gt;
&lt;li&gt;[ ] Restore from a known-clean backup if one exists from before the compromise, then re-apply only the legitimate changes since.&lt;/li&gt;
&lt;li&gt;[ ] Check outbound mail logs for a spike in sent volume — that's usually the smoking gun for spam-based blacklisting.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you found active malware or a defaced page, our &lt;a href="https://bugcircuit.com/website-hacked" rel="noopener noreferrer"&gt;hacked website recovery guide&lt;/a&gt; covers the full incident-response sequence in more detail.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stop it from happening through email spoofing
&lt;/h2&gt;

&lt;p&gt;A lot of domain blacklisting isn't from a hacked website at all — it's from a domain with no email authentication, which lets attackers send phishing mail that &lt;em&gt;looks&lt;/em&gt; like it's from you. Three DNS records fix this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SPF&lt;/strong&gt; — lists which servers are allowed to send mail for your domain.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DKIM&lt;/strong&gt; — cryptographically signs your outgoing mail so it can't be forged in transit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DMARC&lt;/strong&gt; — tells receiving mail servers what to do with mail that fails SPF/DKIM, e.g.:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@yourdomain.com;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without DMARC, spoofed mail sent "from" your domain can trigger spam-trap hits that get &lt;em&gt;your&lt;/em&gt; domain blacklisted, even though you never sent it. Run your domain through our &lt;a href="https://bugcircuit.com/tools/email-spoofing" rel="noopener noreferrer"&gt;email spoofing and DMARC checker&lt;/a&gt; to see your current exposure — it's free and takes under a minute.&lt;/p&gt;

&lt;h2&gt;
  
  
  How long full recovery actually takes
&lt;/h2&gt;

&lt;p&gt;Delisting itself is usually fast once the cause is fixed — hours to a few days per list. The part that takes longer is confirming the compromise is fully gone: checking logs for persistence mechanisms, verifying no backdoor survived the cleanup, and monitoring outbound mail and file integrity for a week or two afterward. Rushing the delisting request before that confirmation is exactly how domains bounce on and off the same list.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Blacklisting is a symptom — find and fix the actual compromise (hacked files, phishing malware, or spoofed email) before requesting removal.&lt;/li&gt;
&lt;li&gt;Spamhaus, Barracuda, and Google Safe Browsing each have their own free lookup and removal tools — use the official one, never a paid "instant delisting" service.&lt;/li&gt;
&lt;li&gt;Rotate every credential and update every plugin/theme as part of cleanup, not just the file that looked obviously malicious.&lt;/li&gt;
&lt;li&gt;Add SPF, DKIM, and DMARC so spoofed phishing mail can't get your domain flagged for something you didn't send.&lt;/li&gt;
&lt;li&gt;If you're not sure your cleanup was complete, a second set of eyes on the actual codebase is worth it before you declare victory.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want confirmation that the compromise is actually gone — not just that the warning page disappeared — a real person manually auditing your site catches backdoors and leftover malware that automated scanners miss. &lt;a href="https://bugcircuit.com/pricing" rel="noopener noreferrer"&gt;Circuit&lt;/a&gt; is a $49 one-time manual audit with a full written report of what's still wrong and exactly how to fix it, and you can start with a &lt;a href="https://bugcircuit.com/free-website-security-check" rel="noopener noreferrer"&gt;free passive security check&lt;/a&gt; if you just want a first read on your risk.&lt;/p&gt;

</description>
      <category>blacklist</category>
      <category>spamhaus</category>
      <category>googlesafebrowsing</category>
      <category>websitehacked</category>
    </item>
    <item>
      <title>Host Suspended Your Site for Malware? Do This</title>
      <dc:creator>Bug Circuit</dc:creator>
      <pubDate>Fri, 31 Jul 2026 02:35:33 +0000</pubDate>
      <link>https://dev.to/bugcircuit/host-suspended-your-site-for-malware-do-this-46j1</link>
      <guid>https://dev.to/bugcircuit/host-suspended-your-site-for-malware-do-this-46j1</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://bugcircuit.com/blog/host-suspended-your-site-for-malware-do-this" rel="noopener noreferrer"&gt;Bug Circuit blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If your host suspended your site for malware, the fastest way back online is: get the exact scan report from your host, remove the malicious files (not just disable the infected plugin), rotate every password and secret key, update everything, run a clean third-party scan, and send your host proof of all of it before you ask for reinstatement.&lt;/strong&gt; Skipping the "proof" step is the single biggest reason sites get re-suspended within days.&lt;/p&gt;

&lt;p&gt;This is for site owners staring at a "suspended due to malicious content" email from GoDaddy, Bluehost, SiteGround, Hostinger, WP Engine, or a similar host, with no idea what to do next. By the end you'll have a step-by-step process to identify the infection, clean it properly, and get your host to turn the site back on — plus what to do so it doesn't happen again.&lt;/p&gt;

&lt;h2&gt;
  
  
  What "suspended for malware" actually means
&lt;/h2&gt;

&lt;p&gt;Hosts don't suspend sites to be difficult. Malware on your site can spam other customers' shared servers, get the host's whole IP range blocked by email providers, or trigger &lt;a href="https://transparencyreport.google.com/safe-browsing/search" rel="noopener noreferrer"&gt;Google Safe Browsing&lt;/a&gt; warnings that make the host's network look untrustworthy. Suspension is the host protecting its own infrastructure — your reinstatement path exists, but you have to do the cleanup, and you usually have to prove it.&lt;/p&gt;

&lt;p&gt;Common triggers: a hidden backdoor script uploaded through an outdated plugin, injected spam links or redirects, a cryptomining script, or your site being used to host a phishing page. All of these get caught the same way — by a scanner (the host's own, or Google's) flagging known malicious patterns.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Get the exact reason from your host
&lt;/h2&gt;

&lt;p&gt;Don't start deleting files yet. Open a support ticket and ask specifically for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;scan report&lt;/strong&gt; or list of flagged files and paths&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;date/time&lt;/strong&gt; the infection was detected&lt;/li&gt;
&lt;li&gt;Whether they've already &lt;strong&gt;quarantined or restored&lt;/strong&gt; anything&lt;/li&gt;
&lt;li&gt;Their &lt;strong&gt;exact reinstatement requirements&lt;/strong&gt; (some hosts want a signed statement, some want a specific scanner's clean report, some will rescan themselves)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Many hosts (GoDaddy, Bluehost/EIG-family brands, SiteGround) run automated malware scanners on shared hosting and will hand you a file list on request — this saves you hours of guessing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Check how bad it looks from the outside
&lt;/h2&gt;

&lt;p&gt;Before touching code, check what the internet already knows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Search &lt;code&gt;site:yourdomain.com&lt;/code&gt; in Google — spammy titles or foreign-language pages you didn't write are a strong signal of injected content.&lt;/li&gt;
&lt;li&gt;Check your domain's status at Google's &lt;a href="https://transparencyreport.google.com/safe-browsing/search" rel="noopener noreferrer"&gt;Safe Browsing site status tool&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Log into &lt;a href="https://search.google.com/search-console" rel="noopener noreferrer"&gt;Google Search Console&lt;/a&gt; and check the &lt;strong&gt;Security Issues&lt;/strong&gt; report if the site is verified — it often names the exact malware type (e.g., "injected content," "harmful downloads").&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you're not sure whether the site is actually compromised or just misflagged, our &lt;a href="https://bugcircuit.com/free-website-security-check" rel="noopener noreferrer"&gt;free website security check&lt;/a&gt; can give you a quick read before you spend hours digging.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Find and remove the malicious code
&lt;/h2&gt;

&lt;p&gt;This is the part people rush and get wrong. Disabling the plugin the malware came in through does &lt;strong&gt;not&lt;/strong&gt; remove a backdoor the attacker already planted elsewhere.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you have a clean backup from before the infection date&lt;/strong&gt;, restoring it is usually faster and safer than manual cleanup — as long as you also patch the entry point (Step 5) before putting it back online.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you don't have a clean backup&lt;/strong&gt;, look for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Obfuscated PHP: &lt;code&gt;eval(base64_decode(...))&lt;/code&gt;, &lt;code&gt;gzinflate(...)&lt;/code&gt;, &lt;code&gt;str_rot13(...)&lt;/code&gt; inside theme or plugin files that shouldn't contain them&lt;/li&gt;
&lt;li&gt;Files with recent modified dates you don't recognize, especially in &lt;code&gt;/wp-content/uploads/&lt;/code&gt; (uploads folders shouldn't contain &lt;code&gt;.php&lt;/code&gt; files at all)&lt;/li&gt;
&lt;li&gt;Extra admin accounts you didn't create (check Users in your CMS admin, or the database &lt;code&gt;wp_users&lt;/code&gt; table directly)&lt;/li&gt;
&lt;li&gt;Unfamiliar entries in &lt;code&gt;.htaccess&lt;/code&gt;, especially &lt;code&gt;RewriteCond&lt;/code&gt;/&lt;code&gt;RewriteRule&lt;/code&gt; blocks that redirect mobile visitors or search-engine bots to a different site&lt;/li&gt;
&lt;li&gt;Scheduled tasks (cron jobs) you didn't set up, in your hosting control panel or via a plugin like WP Crontrol&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Compare core CMS files against a fresh download of the same version — any core file that differs from the official release is suspect. Google's own &lt;a href="https://developers.google.com/search/docs/monitor-debug/security/clean-site" rel="noopener noreferrer"&gt;"Clean up your hacked site" guide&lt;/a&gt; walks through this file-by-file comparison process in more detail.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Lock the doors — rotate every credential
&lt;/h2&gt;

&lt;p&gt;Attackers who got in once often leave themselves a way back in. Before you reopen the site:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Change your &lt;strong&gt;hosting/cPanel password&lt;/strong&gt;, &lt;strong&gt;database password&lt;/strong&gt;, &lt;strong&gt;FTP/SFTP password&lt;/strong&gt;, and every &lt;strong&gt;admin account password&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Regenerate WordPress secret keys via &lt;a href="https://api.wordpress.org/secret-key/1.1/salt/" rel="noopener noreferrer"&gt;api.wordpress.org/secret-key/1.1/salt/&lt;/a&gt; and paste them into &lt;code&gt;wp-config.php&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Delete any admin user you don't recognize&lt;/li&gt;
&lt;li&gt;Revoke and reissue API keys for any connected services (payment processors, email senders, CDNs)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 5: Update everything before you reopen
&lt;/h2&gt;

&lt;p&gt;Outdated, unpatched software is how most of these infections start — it's consistently one of the top causes tracked in the &lt;a href="https://owasp.org/Top10/A06_2021-Vulnerable_and_Outdated_Components/" rel="noopener noreferrer"&gt;OWASP Top 10&lt;/a&gt; under vulnerable and outdated components. Update your CMS core, every theme, and every plugin to their latest versions, and &lt;strong&gt;remove anything inactive&lt;/strong&gt; you're not using — an unused plugin can still be exploited even if it's switched off.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: Get a clean scan your host will accept
&lt;/h2&gt;

&lt;p&gt;Most hosts won't take your word for it. Run one (ideally two) of these before you file for reinstatement:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scanner&lt;/th&gt;
&lt;th&gt;Good for&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Sucuri SiteCheck (free)&lt;/td&gt;
&lt;td&gt;Quick outside-in check&lt;/td&gt;
&lt;td&gt;Scans the live site remotely, no login needed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wordfence / MalCare (WordPress)&lt;/td&gt;
&lt;td&gt;Full file-system scan&lt;/td&gt;
&lt;td&gt;Checks every file against known-malware signatures&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Host's own scanner&lt;/td&gt;
&lt;td&gt;Reinstatement requirement&lt;/td&gt;
&lt;td&gt;Some hosts only accept their own rescan as proof&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Keep a screenshot or exported report of the clean result — you'll attach it to your reinstatement request.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 7: Ask for reinstatement — and prove it's clean
&lt;/h2&gt;

&lt;p&gt;Reply to your original support ticket with:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What the infection was and where it was (referencing their scan report)&lt;/li&gt;
&lt;li&gt;What you removed and what you patched (be specific: "deleted &lt;code&gt;wp-content/uploads/2024/xx.php&lt;/code&gt;, updated Plugin X from 4.1 to 4.9")&lt;/li&gt;
&lt;li&gt;Your clean scan report or screenshot&lt;/li&gt;
&lt;li&gt;Confirmation that passwords and keys were rotated&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After reinstatement, if Search Console showed a Security Issues warning, submit a &lt;strong&gt;review request&lt;/strong&gt; there too — that's a separate step from your host unsuspending you, and it's what actually clears the browser warning for visitors.&lt;/p&gt;

&lt;h2&gt;
  
  
  DIY cleanup vs. professional help
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;DIY&lt;/th&gt;
&lt;th&gt;Host's paid cleanup&lt;/th&gt;
&lt;th&gt;Manual audit ($49)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Speed&lt;/td&gt;
&lt;td&gt;Hours to days, depends on skill&lt;/td&gt;
&lt;td&gt;Usually 24–72 hrs&lt;/td&gt;
&lt;td&gt;2–4 business days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Finds the &lt;em&gt;root cause&lt;/em&gt;, not just the file&lt;/td&gt;
&lt;td&gt;Sometimes — easy to miss backdoors&lt;/td&gt;
&lt;td&gt;Varies by host&lt;/td&gt;
&lt;td&gt;Yes, plus a written report of every issue found, with fixes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ongoing protection&lt;/td&gt;
&lt;td&gt;You're on your own&lt;/td&gt;
&lt;td&gt;Ends after cleanup&lt;/td&gt;
&lt;td&gt;Can pair with &lt;a href="https://bugcircuit.com/pricing" rel="noopener noreferrer"&gt;Signal&lt;/a&gt; for 3 months of cover + fixes to critical issues&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cost&lt;/td&gt;
&lt;td&gt;Free (your time)&lt;/td&gt;
&lt;td&gt;Often $100–$300+&lt;/td&gt;
&lt;td&gt;$49 one-time&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If you cleaned it yourself and just want a second set of eyes to confirm nothing was missed before you tell your host it's fixed, that's exactly the kind of check a manual audit is good for — it's not a substitute for the cleanup itself, but it catches what automated scanners and a rushed manual pass often miss. Compare that to a full &lt;a href="https://bugcircuit.com/guides/how-much-does-a-penetration-test-cost" rel="noopener noreferrer"&gt;penetration test cost&lt;/a&gt; if you're weighing options, and see how &lt;a href="https://bugcircuit.com/guides/manual-vs-automated-penetration-testing" rel="noopener noreferrer"&gt;manual review differs from automated scanning&lt;/a&gt; if you're deciding which route fits.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to stop this from happening again
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Turn on automatic updates for your CMS core and plugins where your host supports it&lt;/li&gt;
&lt;li&gt;Set up basic &lt;a href="https://bugcircuit.com/tools/security-headers" rel="noopener noreferrer"&gt;security headers&lt;/a&gt; — they won't stop every attack, but they close off easy wins like clickjacking and some injection vectors&lt;/li&gt;
&lt;li&gt;Keep offsite backups on a schedule your host doesn't control, so a future infection doesn't wipe your only clean copy&lt;/li&gt;
&lt;li&gt;Run a &lt;a href="https://bugcircuit.com/free-website-security-check" rel="noopener noreferrer"&gt;free security check&lt;/a&gt; periodically, and read &lt;a href="https://bugcircuit.com/guides/is-my-website-hackable" rel="noopener noreferrer"&gt;how to tell if your site is hackable&lt;/a&gt; before the next scare&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For background on the general categories of attacks hosts are scanning for, CISA's &lt;a href="https://www.cisa.gov/topics/cyber-threats-and-advisories/malware-phishing-and-ransomware" rel="noopener noreferrer"&gt;malware, phishing, and ransomware overview&lt;/a&gt; is a solid plain-English primer if you want to understand the bigger picture beyond your own incident.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Get the host's exact scan report first — don't guess at what's infected&lt;/li&gt;
&lt;li&gt;A clean backup restore plus patching the entry point beats manual file-by-file removal when you have one&lt;/li&gt;
&lt;li&gt;Rotate every password and secret key, not just the CMS admin password&lt;/li&gt;
&lt;li&gt;Run a clean third-party scan and attach the report to your reinstatement request — hosts rarely reinstate on your word alone&lt;/li&gt;
&lt;li&gt;Fix the update/backup habits that let it happen, or expect a repeat&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you'd rather have a person confirm the infection is fully gone (and check for anything else an attacker could come back through) before you go back to your host, a &lt;a href="https://bugcircuit.com/pricing" rel="noopener noreferrer"&gt;Circuit audit&lt;/a&gt; is a $49 manual review with a written report — a second, human set of eyes on exactly this kind of situation.&lt;/p&gt;

</description>
      <category>malwareremoval</category>
      <category>websitehacked</category>
      <category>hosting</category>
      <category>incidentresponse</category>
    </item>
    <item>
      <title>Website Redirecting to Spam? How to Stop It</title>
      <dc:creator>Bug Circuit</dc:creator>
      <pubDate>Fri, 31 Jul 2026 02:29:37 +0000</pubDate>
      <link>https://dev.to/bugcircuit/website-redirecting-to-spam-how-to-stop-it-2a9l</link>
      <guid>https://dev.to/bugcircuit/website-redirecting-to-spam-how-to-stop-it-2a9l</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://bugcircuit.com/blog/website-redirecting-to-spam-how-to-stop-it" rel="noopener noreferrer"&gt;Bug Circuit blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If your website sends visitors to a spam, scam, or gambling site, you've almost certainly been hacked — and the redirect is hiding in one of four places: your &lt;code&gt;.htaccess&lt;/code&gt; file, injected JavaScript, your WordPress database or a rogue plugin, or your DNS records.&lt;/strong&gt; The fix depends entirely on which one it is, so guessing (or just reinstalling your theme) usually doesn't work.&lt;/p&gt;

&lt;p&gt;This is for site owners — WordPress, Shopify, or a hand-built site — who've noticed weird redirects, gotten a "this site may be hacked" warning in Google, or had a customer say "your link took me somewhere sketchy." You'll get a step-by-step way to find exactly where the redirect is firing from, plus how to close it, including the sneaky version that only redirects mobile visitors or people coming from Google.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why "website redirecting to another site" is almost always a hack, not a bug
&lt;/h2&gt;

&lt;p&gt;A legitimate site doesn't randomly start sending people to pill ads, fake tech-support pages, or spam text in another language. When that happens, it's almost always &lt;strong&gt;malware planted after your site, a plugin, or your hosting account got compromised&lt;/strong&gt; — commonly through a stolen FTP/hosting password, an outdated plugin with a known vulnerability, or a compromised admin account. Google's own guidance on hacked sites confirms this pattern and calls out redirect hacks specifically as a common attack type (&lt;a href="https://developers.google.com/search/docs/monitor-debug/security/hacked-overview" rel="noopener noreferrer"&gt;Google Search Central: hacked sites overview&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;The attacker's goal is usually SEO spam or ad fraud: they want your site's existing traffic and search ranking to funnel visitors to their pages, without you noticing for as long as possible. That's why these redirects are almost never "always on" — they're built to hide from you, the owner, while still firing for real visitors and search engines.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 4 hiding spots, compared
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Where it hides&lt;/th&gt;
&lt;th&gt;How it usually triggers&lt;/th&gt;
&lt;th&gt;Who notices it first&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;.htaccess&lt;/code&gt; (Apache config file)&lt;/td&gt;
&lt;td&gt;Rewrite rules that check the visitor's User-Agent or Referer&lt;/td&gt;
&lt;td&gt;Google Search Console, mobile users&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Injected JavaScript&lt;/td&gt;
&lt;td&gt;Obfuscated &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; in a theme file or footer that runs on page load&lt;/td&gt;
&lt;td&gt;Desktop visitors, browser warnings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WordPress database / rogue plugin&lt;/td&gt;
&lt;td&gt;Malicious &lt;code&gt;siteurl&lt;/code&gt;/&lt;code&gt;home&lt;/code&gt; value, or a fake plugin registering a redirect hook&lt;/td&gt;
&lt;td&gt;Everyone, all the time (often the noisiest one)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DNS records&lt;/td&gt;
&lt;td&gt;A/CNAME record repointed to attacker infrastructure&lt;/td&gt;
&lt;td&gt;Everyone, but looks like the "whole site is down or moved"&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Step 1: Rule out DNS first — it's the fastest check
&lt;/h2&gt;

&lt;p&gt;Before you touch any files, confirm your domain is actually pointing at your own server. If your DNS was hijacked (usually via a compromised domain registrar or DNS provider account, not your website itself), no amount of file cleanup will fix it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;dig example.com A +short
dig example.com NS +short
whois example.com
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compare the A record IP against the IP your host gives you in your hosting control panel. If it doesn't match, or the nameservers (NS records) aren't the ones your registrar or DNS host assigned you, your DNS has been changed — go straight to your registrar, reset that account's password, and revert the records. This is a domain-account problem, not a website problem, so cleaning WordPress won't help.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Check if the redirect is conditional (mobile-only or Google-only)
&lt;/h2&gt;

&lt;p&gt;This is the step people miss. Many redirect hacks are deliberately conditional — they only fire for mobile users or for visitors arriving from a search engine, so the site owner checking it on a desktop browser sees nothing wrong. Test it the way an attacker built it to be tested:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Simulate a normal visit&lt;/span&gt;
curl &lt;span class="nt"&gt;-I&lt;/span&gt; https://example.com

&lt;span class="c"&gt;# Simulate Googlebot&lt;/span&gt;
curl &lt;span class="nt"&gt;-A&lt;/span&gt; &lt;span class="s2"&gt;"Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"&lt;/span&gt; &lt;span class="nt"&gt;-I&lt;/span&gt; https://example.com

&lt;span class="c"&gt;# Simulate someone clicking through from a Google search on mobile&lt;/span&gt;
curl &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"https://www.google.com/search?q=example"&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt; &lt;span class="s2"&gt;"Mozilla/5.0 (Linux; Android 10; Mobile)"&lt;/span&gt; &lt;span class="nt"&gt;-I&lt;/span&gt; https://example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look at the response headers. If the Googlebot or Google-referrer request returns a &lt;code&gt;301&lt;/code&gt; or &lt;code&gt;302&lt;/code&gt; with a &lt;code&gt;Location:&lt;/code&gt; header pointing somewhere unfamiliar, but your plain request doesn't, you've confirmed a conditional redirect — and you now know it's checking User-Agent and/or Referer, which narrows the search to &lt;code&gt;.htaccess&lt;/code&gt; or JavaScript (the next two steps).&lt;/p&gt;

&lt;p&gt;Also check Google Search Console's Security Issues report (Search Console → Security &amp;amp; Manual Actions) — Google flags this exact "cloaked redirect" pattern when it crawls your site, per their &lt;a href="https://developers.google.com/search/docs/monitor-debug/security/hacked-overview" rel="noopener noreferrer"&gt;hacked-site cleanup guide&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Search .htaccess for User-Agent or Referer rules
&lt;/h2&gt;

&lt;p&gt;Open &lt;code&gt;.htaccess&lt;/code&gt; in your site's root directory (via FTP/SFTP or your host's file manager) and look for &lt;code&gt;RewriteCond&lt;/code&gt; lines referencing &lt;code&gt;HTTP_USER_AGENT&lt;/code&gt; or &lt;code&gt;HTTP_REFERER&lt;/code&gt;, especially ones mentioning "google," "bing," "yahoo," or "mobile." A legitimate rule rarely needs to check for search engine names. A malicious block often looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight apache"&gt;&lt;code&gt;&lt;span class="nc"&gt;RewriteCond&lt;/span&gt; %{HTTP_REFERER} google\.com [NC,OR]
&lt;span class="nc"&gt;RewriteCond&lt;/span&gt; %{HTTP_USER_AGENT} Mobile
&lt;span class="nc"&gt;RewriteRule&lt;/span&gt; ^(.*)$ http://spam-domain.example/landing.php [R=302,L]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Delete any block you don't recognize, save, and re-run the &lt;code&gt;curl&lt;/code&gt; tests from Step 2 to confirm it's gone. Keep a backup copy of the file before editing, in case you need to compare it later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Search for injected JavaScript
&lt;/h2&gt;

&lt;p&gt;If &lt;code&gt;.htaccess&lt;/code&gt; is clean but the redirect still fires (especially only on desktop, or only after a delay), the payload is likely JavaScript stuffed into a theme file, a widget, or a compromised plugin's assets. Search your theme folder for obvious obfuscation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-rl&lt;/span&gt; &lt;span class="s2"&gt;"eval("&lt;/span&gt; wp-content/themes/
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-rl&lt;/span&gt; &lt;span class="s2"&gt;"base64_decode&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;gzinflate&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;String.fromCharCode"&lt;/span&gt; wp-content/themes/ wp-content/plugins/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Real theme code almost never uses &lt;code&gt;eval()&lt;/code&gt; combined with &lt;code&gt;base64_decode&lt;/code&gt; — that combination is a near-universal signature of injected malware, because it lets the attacker hide the real payload from casual inspection. Also check &lt;code&gt;footer.php&lt;/code&gt; and &lt;code&gt;header.php&lt;/code&gt; for &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags you didn't add. OWASP's guidance on unvalidated redirects and forwards is a good primer on why these injections work so well (&lt;a href="https://owasp.org/www-project-top-ten/" rel="noopener noreferrer"&gt;OWASP Top Ten&lt;/a&gt;): browsers and users trust redirects that appear to come from a site they already trust.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Check the WordPress database and plugins
&lt;/h2&gt;

&lt;p&gt;If you're on WordPress, the hack often lives in the database itself, not the files. Two places to check, using WP-CLI:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Site URL hijack&lt;/strong&gt; — run &lt;code&gt;wp option get siteurl&lt;/code&gt; and &lt;code&gt;wp option get home&lt;/code&gt;. If either points to a domain that isn't yours, that's your redirect source.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A rogue or disguised plugin&lt;/strong&gt; — run &lt;code&gt;wp plugin list&lt;/code&gt; and look for anything you don't recognize, or a "legit-looking" plugin name you never installed. Also compare your core files against the official versions with &lt;code&gt;wp core verify-checksums&lt;/code&gt;, a built-in WP-CLI command that flags any modified core file.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Malicious code also frequently gets planted directly in the &lt;code&gt;wp_posts&lt;/code&gt; or &lt;code&gt;wp_options&lt;/code&gt; table as a serialized PHP snippet that runs on &lt;code&gt;init&lt;/code&gt;. This is harder to spot by eye than a file, which is one reason a manual, human-led review tends to catch what a quick automated scan misses.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fix checklist, in order
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Confirm DNS A/NS records match your actual host (Step 1)&lt;/li&gt;
&lt;li&gt;[ ] Test with &lt;code&gt;curl&lt;/code&gt; using Googlebot and mobile User-Agents to catch conditional redirects (Step 2)&lt;/li&gt;
&lt;li&gt;[ ] Remove suspicious &lt;code&gt;RewriteCond&lt;/code&gt;/&lt;code&gt;RewriteRule&lt;/code&gt; blocks from &lt;code&gt;.htaccess&lt;/code&gt; (Step 3)&lt;/li&gt;
&lt;li&gt;[ ] Grep theme/plugin files for &lt;code&gt;eval(&lt;/code&gt;, &lt;code&gt;base64_decode&lt;/code&gt;, and obfuscated &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; blocks (Step 4)&lt;/li&gt;
&lt;li&gt;[ ] Check &lt;code&gt;wp option get siteurl&lt;/code&gt;/&lt;code&gt;home&lt;/code&gt; and run &lt;code&gt;wp core verify-checksums&lt;/code&gt; (Step 5)&lt;/li&gt;
&lt;li&gt;[ ] Change all passwords — hosting, FTP, WordPress admin, registrar — since redirects usually mean broader access was gained, not just one file&lt;/li&gt;
&lt;li&gt;[ ] Update every plugin, theme, and WordPress core to the latest version&lt;/li&gt;
&lt;li&gt;[ ] Re-check Search Console's Security Issues report after cleanup and request a review&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Run our &lt;a href="https://bugcircuit.com/free-website-security-check" rel="noopener noreferrer"&gt;free website security check&lt;/a&gt; after cleanup to confirm the redirect and any related malware are actually gone, not just hidden again.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to stop DIY-ing it
&lt;/h2&gt;

&lt;p&gt;If you've been through all four checks and the redirect keeps coming back, or you're not comfortable editing &lt;code&gt;.htaccess&lt;/code&gt; and database values on a live production site, that's the point to bring in a second pair of eyes. Automated scanners are good at flagging known malware signatures but routinely miss custom, hand-placed redirects like the ones above — that gap is exactly why manual review exists; see our comparison of &lt;a href="https://bugcircuit.com/guides/manual-vs-automated-penetration-testing" rel="noopener noreferrer"&gt;manual vs. automated penetration testing&lt;/a&gt; for why it matters here. It's also worth reading &lt;a href="https://bugcircuit.com/guides/is-my-website-hackable" rel="noopener noreferrer"&gt;is my website hackable&lt;/a&gt; to understand what let the attacker in, so you're not just cleaning the symptom and leaving the door open.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A spam redirect almost always means compromise, not a bug — and it hides in &lt;code&gt;.htaccess&lt;/code&gt;, injected JavaScript, your WordPress database/plugins, or DNS.&lt;/li&gt;
&lt;li&gt;Test with &lt;code&gt;curl&lt;/code&gt; using a Googlebot User-Agent and a Google referrer before assuming your site is clean — many redirects are deliberately conditional and invisible on a normal desktop visit.&lt;/li&gt;
&lt;li&gt;Rule out DNS first with &lt;code&gt;dig&lt;/code&gt; — if the A or NS records are wrong, no file cleanup will fix it.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;eval()&lt;/code&gt; combined with &lt;code&gt;base64_decode&lt;/code&gt; in theme or plugin files is a near-certain sign of injected malware.&lt;/li&gt;
&lt;li&gt;After cleaning up, change every password tied to the site (hosting, FTP, WordPress, registrar) — the redirect was a symptom of broader access, not an isolated glitch.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you've gone through this checklist and still aren't fully sure it's clean — or you'd rather have someone find the exact injection point for you — &lt;a href="https://bugcircuit.com/pricing" rel="noopener noreferrer"&gt;Bug Circuit's Circuit audit&lt;/a&gt; is $49 for a human security engineer to manually trace it, document exactly what was changed and where, and hand you the precise fix. No card needed to start with the &lt;a href="https://bugcircuit.com/free-website-security-check" rel="noopener noreferrer"&gt;free check&lt;/a&gt; first.&lt;/p&gt;

</description>
      <category>websitehacked</category>
      <category>redirectmalware</category>
      <category>wordpresssecurity</category>
      <category>dnshijack</category>
    </item>
    <item>
      <title>Fix the 'Not Secure' Warning on Your Website</title>
      <dc:creator>Bug Circuit</dc:creator>
      <pubDate>Fri, 31 Jul 2026 02:29:21 +0000</pubDate>
      <link>https://dev.to/bugcircuit/fix-the-not-secure-warning-on-your-website-4gc3</link>
      <guid>https://dev.to/bugcircuit/fix-the-not-secure-warning-on-your-website-4gc3</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://bugcircuit.com/blog/fix-the-not-secure-warning-on-your-website" rel="noopener noreferrer"&gt;Bug Circuit blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The "Not Secure" warning means your site either has no SSL certificate, an expired one, or is loading some content over an insecure &lt;code&gt;http://&lt;/code&gt; connection — and you fix it by installing (or renewing) a certificate, forcing every page to load over &lt;code&gt;https://&lt;/code&gt;, and cleaning up any leftover &lt;code&gt;http://&lt;/code&gt; links.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is for any small business owner, blogger, or shop owner who opened their site and saw "Not Secure" next to the address bar — and now customers are asking about it (or worse, leaving). You don't need to be technical. Below is the exact sequence: diagnose, fix, verify, in about 20-40 minutes depending on your platform.&lt;/p&gt;

&lt;h2&gt;
  
  
  What "Not Secure" actually means
&lt;/h2&gt;

&lt;p&gt;Every browser checks whether your site is using &lt;strong&gt;HTTPS&lt;/strong&gt; — the encrypted version of the web address protocol. HTTPS relies on an &lt;strong&gt;SSL/TLS certificate&lt;/strong&gt;, a small file that proves your domain is who it says it is and encrypts the connection between your visitor's browser and your server. Chrome explains its address-bar security indicators directly here: &lt;a href="https://support.google.com/chrome/answer/95617" rel="noopener noreferrer"&gt;Chrome's "Not secure" warning explained&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You'll see the warning for one of three reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;No certificate at all&lt;/strong&gt; — your site is still served over plain &lt;code&gt;http://&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A broken certificate&lt;/strong&gt; — expired, self-signed, or issued for the wrong domain (e.g., it covers &lt;code&gt;example.com&lt;/code&gt; but not &lt;code&gt;www.example.com&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mixed content&lt;/strong&gt; — the page itself loads over HTTPS, but it's pulling in an image, script, or stylesheet from an &lt;code&gt;http://&lt;/code&gt; address, so the browser can't call the whole page secure.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All three are fixable without touching code. Here's the order to work through them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Diagnose which one you have
&lt;/h2&gt;

&lt;p&gt;Before fixing anything, find out exactly what's broken:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click the padlock or "i" icon in your browser's address bar and choose &lt;strong&gt;Certificate is not valid&lt;/strong&gt; or &lt;strong&gt;Connection is not secure&lt;/strong&gt; to see the reason.&lt;/li&gt;
&lt;li&gt;Run your domain through &lt;a href="https://www.ssllabs.com/ssltest/" rel="noopener noreferrer"&gt;Qualys SSL Labs' free SSL Test&lt;/a&gt; — it grades your certificate and flags expired, mismatched, or misconfigured setups in plain terms.&lt;/li&gt;
&lt;li&gt;If the padlock looks fine but you still see a warning or a "not fully secure" icon, open your browser's developer console (F12 → Console tab) and look for lines mentioning "Mixed Content" — that confirms issue #3 above.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Write down which case you're in; it determines which step below actually applies to you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Install or renew the SSL certificate
&lt;/h2&gt;

&lt;p&gt;If you have no certificate or an expired one, get a new one. Most hosts now offer this for free:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;How to get/renew the certificate&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;WordPress (shared hosting)&lt;/td&gt;
&lt;td&gt;Host's control panel → SSL/TLS → "Enable free SSL" (usually powered by &lt;a href="https://letsencrypt.org/getting-started/" rel="noopener noreferrer"&gt;Let's Encrypt&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shopify&lt;/td&gt;
&lt;td&gt;Settings → Domains — SSL is automatic and free; if it's missing, remove and re-add the domain&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Squarespace / Wix&lt;/td&gt;
&lt;td&gt;Settings → Domains → SSL — toggle on; provisioning can take up to 24-48 hours&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cloudflare (in front of any site)&lt;/td&gt;
&lt;td&gt;SSL/TLS tab → set mode to "Full" or "Full (strict)", not "Flexible"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Custom server / VPS&lt;/td&gt;
&lt;td&gt;Install &lt;a href="https://certbot.eff.org/" rel="noopener noreferrer"&gt;Certbot&lt;/a&gt; for free Let's Encrypt certificates, set to auto-renew every 90 days&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Let's Encrypt certificates expire every 90 days by design, specifically so renewal gets automated rather than forgotten — that's the single most common cause of a site suddenly going "Not Secure" after working fine for months. Confirm your host has auto-renewal turned on, not a manual reminder on someone's calendar.&lt;/p&gt;

&lt;p&gt;One more gotcha: make sure the certificate covers every version of your domain you actually use — &lt;code&gt;example.com&lt;/code&gt;, &lt;code&gt;www.example.com&lt;/code&gt;, and any subdomains. A certificate issued for only one of those will show "Not Secure" on the others.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Force every visitor onto HTTPS
&lt;/h2&gt;

&lt;p&gt;Having a certificate isn't enough if your site still lets people load the &lt;code&gt;http://&lt;/code&gt; version. You need a &lt;strong&gt;redirect&lt;/strong&gt; that automatically bumps every visitor to &lt;code&gt;https://&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;WordPress:&lt;/strong&gt; install the free plugin &lt;strong&gt;Really Simple SSL&lt;/strong&gt; — it detects your certificate and forces the redirect with one click, no code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloudflare:&lt;/strong&gt; SSL/TLS → Edge Certificates → turn on &lt;strong&gt;"Always Use HTTPS."&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Apache (.htaccess):&lt;/strong&gt; add this to the top of your &lt;code&gt;.htaccess&lt;/code&gt; file:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight apache"&gt;&lt;code&gt;  &lt;span class="nc"&gt;RewriteEngine&lt;/span&gt; &lt;span class="ss"&gt;On&lt;/span&gt;
  &lt;span class="nc"&gt;RewriteCond&lt;/span&gt; %{HTTPS} &lt;span class="ss"&gt;off&lt;/span&gt;
  &lt;span class="nc"&gt;RewriteRule&lt;/span&gt; ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Nginx:&lt;/strong&gt; in your server block:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;  &lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;example.com&lt;/span&gt; &lt;span class="s"&gt;www.example.com&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kn"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;301&lt;/span&gt; &lt;span class="s"&gt;https://&lt;/span&gt;&lt;span class="nv"&gt;$host$request_uri&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the redirect works, add one more header to tell browsers to &lt;em&gt;always&lt;/em&gt; use HTTPS for your domain from now on, even if someone types &lt;code&gt;http://&lt;/code&gt; again later: &lt;code&gt;Strict-Transport-Security: max-age=31536000; includeSubDomains&lt;/code&gt;. This is called &lt;strong&gt;HSTS&lt;/strong&gt;, and OWASP's cheat sheet covers exactly how to set it safely: &lt;a href="https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Strict_Transport_Security_Cheat_Sheet.html" rel="noopener noreferrer"&gt;OWASP HSTS Cheat Sheet&lt;/a&gt;. You can check whether yours (and other security headers) are already in place with our free &lt;a href="https://bugcircuit.com/tools/security-headers" rel="noopener noreferrer"&gt;security headers checker&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Clean up mixed content
&lt;/h2&gt;

&lt;p&gt;If the padlock shows a warning icon even after Steps 2-3, some element on the page is still loading over plain &lt;code&gt;http://&lt;/code&gt;. Browsers block or flag this because an attacker on the same network could tamper with that one insecure file and use it to attack the rest of the page — Mozilla's developer docs explain the mechanics here: &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Security/Mixed_content" rel="noopener noreferrer"&gt;MDN: Mixed content&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Common culprits and fixes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Old image or script tags&lt;/strong&gt; hardcoded as &lt;code&gt;http://yoursite.com/logo.png&lt;/code&gt; — change them to &lt;code&gt;https://&lt;/code&gt; or, better, a protocol-relative &lt;code&gt;//yoursite.com/logo.png&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Embedded content&lt;/strong&gt; (YouTube videos, fonts, ad scripts, widgets) pulled from a third party still on &lt;code&gt;http://&lt;/code&gt; — check the embed code and swap to the provider's &lt;code&gt;https://&lt;/code&gt; version.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database-stored links&lt;/strong&gt; in WordPress posts/pages from before you had SSL — use the plugin &lt;strong&gt;Better Search Replace&lt;/strong&gt; (or Really Simple SSL's built-in "Mixed Content Fixer") to bulk-update &lt;code&gt;http://yoursite.com&lt;/code&gt; to &lt;code&gt;https://yoursite.com&lt;/code&gt; across your database.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After fixing, reload the page and re-check the browser console — no more "Mixed Content" warnings means you're done.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Verify the fix actually stuck
&lt;/h2&gt;

&lt;p&gt;Check all of these before calling it fixed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] &lt;code&gt;https://yourdomain.com&lt;/code&gt; loads with a padlock, no warning&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;http://yourdomain.com&lt;/code&gt; automatically redirects to &lt;code&gt;https://&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;http://www.yourdomain.com&lt;/code&gt; and &lt;code&gt;https://www.yourdomain.com&lt;/code&gt; also redirect correctly&lt;/li&gt;
&lt;li&gt;[ ] Browser console shows zero mixed-content errors on your homepage and top 2-3 pages&lt;/li&gt;
&lt;li&gt;[ ] SSL Labs test shows grade A or A+, not a warning&lt;/li&gt;
&lt;li&gt;[ ] Certificate expiry date is at least a month out, and auto-renewal is confirmed on&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If any box stays unchecked after these steps, the underlying cause is usually a caching layer (CDN or browser cache serving an old version) — clear your CDN cache and hard-refresh before troubleshooting further.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;"Not Secure" almost always means one of three things: no certificate, a broken/expired certificate, or mixed content — diagnose which one first.&lt;/li&gt;
&lt;li&gt;Get a free certificate from Let's Encrypt (via your host or Certbot) and confirm auto-renewal is on, since 90-day expiry is the #1 cause of recurring warnings.&lt;/li&gt;
&lt;li&gt;Force HTTPS with a 301 redirect (plugin, Cloudflare toggle, or a few lines in &lt;code&gt;.htaccess&lt;/code&gt;/Nginx config), then add an HSTS header.&lt;/li&gt;
&lt;li&gt;Hunt down and update any leftover &lt;code&gt;http://&lt;/code&gt; links in images, embeds, or your database — that's what causes mixed-content warnings even after the certificate is fixed.&lt;/li&gt;
&lt;li&gt;Re-test with SSL Labs and your browser console before considering it closed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you've fixed the padlock but you're still wondering what else on your site might be exposed, that's worth a second look — our guide on &lt;a href="https://bugcircuit.com/guides/is-my-website-hackable" rel="noopener noreferrer"&gt;what makes a website hackable&lt;/a&gt; covers the other common gaps. And if you'd rather have a person confirm everything is actually locked down (not just the padlock, but the whole site), Bug Circuit's &lt;a href="https://bugcircuit.com/pricing" rel="noopener noreferrer"&gt;Circuit audit&lt;/a&gt; is a one-time $49 manual review by a real security engineer, with a full report of anything else worth fixing. You can also start with a &lt;a href="https://bugcircuit.com/free-website-security-check" rel="noopener noreferrer"&gt;free passive security check&lt;/a&gt; — no card, no login — before deciding if you need more.&lt;/p&gt;

</description>
      <category>ssl</category>
      <category>https</category>
      <category>websitesecurity</category>
      <category>notsecurewarning</category>
    </item>
    <item>
      <title>12 Signs Your Website Has Been Hacked</title>
      <dc:creator>Bug Circuit</dc:creator>
      <pubDate>Fri, 31 Jul 2026 02:23:38 +0000</pubDate>
      <link>https://dev.to/bugcircuit/12-signs-your-website-has-been-hacked-4e0h</link>
      <guid>https://dev.to/bugcircuit/12-signs-your-website-has-been-hacked-4e0h</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://bugcircuit.com/blog/12-signs-your-website-has-been-hacked" rel="noopener noreferrer"&gt;Bug Circuit blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If your site shows a browser warning, redirects visitors somewhere strange, has admin accounts you didn't create, or your emails are suddenly bouncing, treat it as hacked until you've checked and ruled it out.&lt;/strong&gt; None of these signs alone is proof, but two or more together is a strong signal.&lt;/p&gt;

&lt;p&gt;This is for any small business owner, freelancer, or agency running a WordPress site, Shopify store, or small SaaS app who's noticed something "off" and wants to know if it's a hack or a glitch. You'll get a plain-English checklist of the 12 most common symptoms, what each one actually means, how urgent it is, and the exact first steps to take.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick-scan checklist
&lt;/h2&gt;

&lt;p&gt;Run down this table first. Anything in the Critical or High row means stop reading and act now — jump to "What to do right now" below.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Sign&lt;/th&gt;
&lt;th&gt;What it usually means&lt;/th&gt;
&lt;th&gt;Urgency&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Browser or antivirus blocks your site&lt;/td&gt;
&lt;td&gt;Malware or phishing content detected&lt;/td&gt;
&lt;td&gt;Critical&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google flags you in Search Console&lt;/td&gt;
&lt;td&gt;Confirmed malware, spam, or hacked content&lt;/td&gt;
&lt;td&gt;Critical&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Visitors get redirected to another site&lt;/td&gt;
&lt;td&gt;Malicious redirect script injected&lt;/td&gt;
&lt;td&gt;Critical&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Homepage defaced or shows a ransom note&lt;/td&gt;
&lt;td&gt;Active, confirmed compromise&lt;/td&gt;
&lt;td&gt;Critical&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;New admin/user accounts you didn't create&lt;/td&gt;
&lt;td&gt;Attacker has persistent access&lt;/td&gt;
&lt;td&gt;Critical&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unknown PHP/script files in your file manager&lt;/td&gt;
&lt;td&gt;A backdoor was uploaded&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Site is suddenly slow or host suspends you&lt;/td&gt;
&lt;td&gt;Server resources hijacked (e.g., crypto-mining)&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Popups or ads only visitors see, not you&lt;/td&gt;
&lt;td&gt;Cloaked malware showing different content to bots vs. humans&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Emails from your domain bounce or land in spam&lt;/td&gt;
&lt;td&gt;Domain blacklisted or used to send spam&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Customers report fraud after buying from you&lt;/td&gt;
&lt;td&gt;Payment page or card data possibly skimmed&lt;/td&gt;
&lt;td&gt;Critical&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gibberish or spammy pages show up in Google&lt;/td&gt;
&lt;td&gt;"SEO spam" injection targeting search rankings&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Can't log in / login page looks different&lt;/td&gt;
&lt;td&gt;Credentials changed or a fake login page installed&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  The 12 signs, explained
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Your browser or antivirus blocks the site
&lt;/h3&gt;

&lt;p&gt;If Chrome, Safari, or your antivirus shows a "Deceptive site ahead" or "This site may harm your computer" warning, Google or another security vendor has already detected malware or phishing on your pages. Check your status directly with &lt;a href="https://transparencyreport.google.com/safe-browsing/search" rel="noopener noreferrer"&gt;Google's Safe Browsing site status tool&lt;/a&gt; — it's free and takes ten seconds.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Google Search Console shows a Security Issues warning
&lt;/h3&gt;

&lt;p&gt;If you have Search Console set up, go to &lt;strong&gt;Security &amp;amp; Manual Actions &amp;gt; Security Issues&lt;/strong&gt;. A message here ("hacked content," "harmful content," or "URL injection") is Google's own confirmation, not a guess. Google documents the common causes and cleanup steps in its &lt;a href="https://developers.google.com/search/docs/monitor-debug/security/hacked-overview" rel="noopener noreferrer"&gt;hacked-sites help center&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Visitors get redirected to a random site
&lt;/h3&gt;

&lt;p&gt;Someone lands on your homepage and ends up on a casino, pharmacy, or fake-prize site instead. This is almost always a malicious redirect injected into your theme files, &lt;code&gt;.htaccess&lt;/code&gt;, or a compromised plugin. It often only fires for visitors coming from Google, so you may not notice it browsing directly — test in an incognito window from a search result, not by typing your URL.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Gibberish or spammy pages show up in your Google results
&lt;/h3&gt;

&lt;p&gt;Search &lt;code&gt;site:yourdomain.com&lt;/code&gt; in Google. If you see pages you never wrote — often in Japanese, Chinese, or stuffed with pharmacy/gambling keywords — that's "SEO spam injection." Attackers create thousands of hidden pages on your domain to piggyback on its search authority.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. There's an admin account you didn't create
&lt;/h3&gt;

&lt;p&gt;Check &lt;strong&gt;Users &amp;gt; All Users&lt;/strong&gt; in WordPress, or run &lt;code&gt;wp user list --role=administrator&lt;/code&gt; if you have WP-CLI access. An unfamiliar admin (sometimes with a generic name like "support" or "admin2") means an attacker created persistent access — even if you change your password, they can still log back in through that account.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Unfamiliar files appear in your file manager
&lt;/h3&gt;

&lt;p&gt;Look in &lt;code&gt;wp-content/uploads/&lt;/code&gt;, your theme folder, or your site root for &lt;code&gt;.php&lt;/code&gt; files that don't belong there — uploads folders should never contain executable scripts. A quick way to spot recently added files via SSH: &lt;code&gt;find . -type f -mtime -14 -name "*.php"&lt;/code&gt;. These are frequently backdoors that let an attacker back in even after you "clean" the visible hack.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Your site is suddenly slow, or your host suspends it for "resource abuse"
&lt;/h3&gt;

&lt;p&gt;A hosting email about excessive CPU use, or a site that crawls to a halt, can mean an attacker installed a script that mines cryptocurrency or sends spam email using your server's resources. Check your hosting control panel's resource-usage graph for an unexplained spike.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Emails from your domain bounce or land in spam
&lt;/h3&gt;

&lt;p&gt;If customer emails suddenly bounce, or your own test emails land in spam, your domain may have been used to send spam and gotten blacklisted, or your SPF/DKIM/DMARC records were tampered with. Run a free check with &lt;a href="https://bugcircuit.com/tools/email-spoofing" rel="noopener noreferrer"&gt;our email spoofing and DNS checker&lt;/a&gt; to confirm your records are intact and your domain isn't blacklisted.&lt;/p&gt;

&lt;h3&gt;
  
  
  9. Popups, fake update prompts, or ads appear — but only for visitors
&lt;/h3&gt;

&lt;p&gt;If customers report seeing "Your Flash Player is out of date" popups or unexpected ads, but you see nothing when you visit, that's likely cloaking: malicious code detects it's talking to a real visitor (not a search bot or the site owner) and serves different, malicious content. This is a classic technique to avoid detection while still infecting visitors — &lt;a href="https://cheatsheetseries.owasp.org/cheatsheets/Incident_Response_Cheat_Sheet.html" rel="noopener noreferrer"&gt;OWASP's guidance on detecting and responding to this kind of compromise&lt;/a&gt; is a solid technical reference if you want the deeper mechanics.&lt;/p&gt;

&lt;h3&gt;
  
  
  10. You can't log in, or the login page looks different
&lt;/h3&gt;

&lt;p&gt;A changed login URL, a login form that looks slightly off, or a password reset that silently fails can mean an attacker replaced your login page with a fake one to harvest credentials, or locked you out after taking over the account.&lt;/p&gt;

&lt;h3&gt;
  
  
  11. Customers report fraud charges right after buying from you
&lt;/h3&gt;

&lt;p&gt;This is one of the most serious signs on this list. If several customers report card fraud shortly after a purchase, your checkout page or payment integration may have been tampered with (a "web skimmer") to capture card details in real time. Treat this as a critical, drop-everything incident — it can trigger real financial harm to real people.&lt;/p&gt;

&lt;h3&gt;
  
  
  12. The homepage is defaced, or there's a ransom note
&lt;/h3&gt;

&lt;p&gt;The most obvious sign: your homepage is replaced with a message, a flag, a group's logo, or a ransom demand. This confirms an active compromise with write access to your files. &lt;a href="https://www.cisa.gov/report" rel="noopener noreferrer"&gt;CISA's incident reporting guidance&lt;/a&gt; explains when and how to report an incident like this, particularly if customer data may be involved.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to do right now
&lt;/h2&gt;

&lt;p&gt;If two or more of the signs above match, work through this in order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Take a backup of the current (compromised) state first&lt;/strong&gt; — you'll want evidence, and a clean restore point may need comparison.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Change every password&lt;/strong&gt;: hosting account, CMS admin, database, FTP/SFTP, and any team logins. Use unique, long passwords for each.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check for accounts and files you didn't create&lt;/strong&gt; (signs #4 and #5 above) and remove anything unfamiliar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ask your host for their malware scan/cleanup tool&lt;/strong&gt; — most reputable hosts have one, and can also tell you if other sites on shared hosting were the entry point.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify your DNS and email records&lt;/strong&gt; haven't been changed using &lt;a href="https://bugcircuit.com/tools/email-spoofing" rel="noopener noreferrer"&gt;our email spoofing checker&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Request a review in Google Search Console&lt;/strong&gt; once you're confident the site is clean, so the browser warnings and search flags get lifted.&lt;/li&gt;
&lt;li&gt;If money, customer data, or payment details were involved, &lt;strong&gt;document everything&lt;/strong&gt; and consider your legal/regulatory notification obligations.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you're not confident doing this yourself — and most non-technical owners aren't — that's exactly the gap a manual audit closes. For the full step-by-step process (not just the checklist), see our &lt;a href="https://bugcircuit.com/website-hacked" rel="noopener noreferrer"&gt;complete guide to what to do when your website's been hacked&lt;/a&gt;. If you just want a free first read before spending anything, our &lt;a href="https://bugcircuit.com/free-website-security-check" rel="noopener noreferrer"&gt;free website security check&lt;/a&gt; will tell you, no card required, whether something critical is actually going on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Two or more signs from the checklist above (especially anything marked Critical) means you should act now, not "when you get a chance."&lt;/li&gt;
&lt;li&gt;A hacked site almost always has a hidden backdoor file or extra admin account — cleaning the visible symptom without finding that is why sites get re-hacked within days.&lt;/li&gt;
&lt;li&gt;Bounced email and blacklisting are DNS-level symptoms; check your SPF/DKIM/DMARC records, don't just resend the email.&lt;/li&gt;
&lt;li&gt;Google Search Console's Security Issues report is the most reliable free confirmation you can get in under a minute.&lt;/li&gt;
&lt;li&gt;If fraud is involved, or you're not sure what you're looking at, a second pair of trained eyes beats guessing — a $49 manual audit finds and documents the actual cause instead of you chasing symptoms in the dark.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bug Circuit's $49 Circuit audit has a real engineer manually go through your site, confirm which of these signs are real, find the backdoor or root cause, and hand you a plain-English report with exact fixes — see &lt;a href="https://bugcircuit.com/pricing" rel="noopener noreferrer"&gt;pricing&lt;/a&gt; if you want a professional to confirm and fix it rather than guess.&lt;/p&gt;

</description>
      <category>websitehacked</category>
      <category>malware</category>
      <category>incidentresponse</category>
      <category>wordpresssecurity</category>
    </item>
  </channel>
</rss>
