43% of cyberattacks target small businesses, according to the Verizon Data Breach Investigations Report. Most of those breaches are preventable. This is the technical implementation guide, covering each security layer in order of priority, with specific actions rather than general advice.
Security layer order of priority:
- HTTPS everywhere
- Authentication (MFA, RBAC, session management)
- SQL injection prevention (parameterised queries)
- XSS and CSRF defences
- HTTP security headers
- Dependency updates
- WordPress-specific hardening (where applicable)
- Backups and incident response plan
1. HTTPS and TLS, Encrypt Everything
Why it is non-negotiable
HTTPS encrypts all communication between a user's browser and your server. Without it, any network observer, an ISP, a router on a shared coffee shop WiFi, can read form data, session cookies, and login credentials in plain text. In 2026, there is no legitimate reason for any website to serve non-sensitive pages over HTTP, and no reason whatsoever to serve forms, user accounts, or payment flows without HTTPS. Google marks non-HTTPS sites as 'Not Secure' in Chrome. Most hosting providers provide free TLS certificates via Let's Encrypt.
Implementation checklist
- Install a TLS certificate. Use Let's Encrypt (free) via Certbot or your hosting panel.
- Redirect all HTTP traffic to HTTPS with a 301. No exceptions for any page.
- Enable HSTS (HTTP Strict Transport Security) with a max-age of at least one year (31536000).
- Set cookie attributes: Secure, HttpOnly, SameSite=Lax (or Strict).
- Use TLS 1.2 minimum. Disable TLS 1.0 and 1.1. Test your TLS configuration at ssllabs.com.
- Automate certificate renewal. Let's Encrypt certificates expire every 90 days. Configure auto-renewal via Certbot or your hosting panel and test that it works.
HSTS header (add to server config):
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload2. Authentication, Who Gets In and What They Can Do
Multi-factor authentication (MFA)
MFA requires a second verification step beyond a password. Even if a password is compromised (via phishing, a leaked database, or a brute force attack), MFA prevents the attacker from completing login without access to the second factor. At minimum, implement MFA on all admin accounts. For applications handling user data, financial transactions, or business operations, offer MFA to all users.
Password requirements
- Minimum 12 characters. Longer matters more than complexity rules.
- Hash passwords with bcrypt or Argon2. Never MD5 or SHA-1.
- Check new passwords against the HaveIBeenPwned breached password API at registration.
- Implement account lockout or rate limiting after 5 to 10 failed attempts.
Role-based access control (RBAC)
Implement the principle of least privilege. Every user account should only have access to the data and operations necessary for their role. An editor should not be able to delete accounts. An API key for a reporting dashboard should be read-only. A customer service agent should see order data but not payment card numbers.
Session management
- Use cryptographically random session tokens. Never sequential IDs.
- Invalidate sessions server-side on logout. A client-side cookie delete is not enough.
- Set session expiry. Inactive sessions should expire after a reasonable period (30-60 minutes for sensitive applications).
- Regenerate session ID on privilege escalation (after login, after MFA).
3. SQL Injection, Parameterise Everything
SQL injection remains one of the most dangerous and most preventable vulnerabilities in web applications. It occurs when user input is included directly in a SQL query without sanitisation, allowing an attacker to manipulate the query structure to extract data, modify records, or in some configurations execute system commands.
The prevention is straightforward
Use parameterised queries (also called prepared statements) for every database operation that includes user input. Never concatenate user input into SQL strings. Use an ORM (Drizzle, Prisma, SQLAlchemy, ActiveRecord) that handles parameterisation automatically. If you must write raw SQL, use your database driver's placeholder syntax for parameters.
Vulnerable (never do this):
db.query("SELECT * FROM users WHERE email = '" + email + "'")Safe (parameterised):
db.query("SELECT * FROM users WHERE email = $1", [email])Input validation, whitelisting expected formats, is a secondary defence but not a replacement for parameterised queries. Validate that an email address matches an email regex before using it in a query, but also parameterise the query regardless of validation.
4. XSS and CSRF, Client-Side Attack Vectors
Cross-Site Scripting (XSS)
XSS occurs when an attacker can inject malicious JavaScript into a web page that other users then execute. A stored XSS attack injected into a comment field or user profile can steal session cookies, redirect users, or capture form input from every user who views that content.
- Escape all user-generated content before rendering it as HTML. Modern frameworks (React, Vue, Angular) do this automatically for interpolated values. Avoid dangerouslySetInnerHTML in React unless the content is sanitised server-side.
- Implement a Content Security Policy (CSP) that restricts which scripts can execute. CSP is the most effective mitigation against XSS.
- Set HttpOnly on session cookies to prevent JavaScript from accessing them even if XSS succeeds.
Cross-Site Request Forgery (CSRF)
CSRF tricks a logged-in user's browser into sending an authenticated request to your application from a different site. If a user is logged into your app and visits an attacker's page, the attacker can trigger state-changing actions (transfers, account changes, deletions) by including a form or image tag that requests your site.
- Use CSRF tokens on all state-changing forms. The token is a random value tied to the session, submitted with the form and verified server-side.
- Set SameSite=Strict or SameSite=Lax on session cookies. This prevents cross-site cookie submission for most CSRF scenarios.
- Verify the Origin or Referer header on sensitive requests to confirm the request originates from your domain.
5. HTTP Security Headers, Browser-Enforced Protection
HTTP security headers instruct the browser to enforce security policies at the network and DOM level. They add a layer of protection that is independent of your application code.
| Header | What it does | Recommended value |
|---|---|---|
| Strict-Transport-Security | Forces HTTPS for all future requests | max-age=31536000; includeSubDomains |
| Content-Security-Policy | Controls which resources load | default-src 'self' |
| X-Frame-Options | Prevents clickjacking via iframes | SAMEORIGIN |
| X-Content-Type-Options | Prevents MIME type sniffing | nosniff |
| Referrer-Policy | Controls referrer information sharing | strict-origin-when-cross-origin |
| Permissions-Policy | Restricts browser feature access | camera=(), microphone=() |
Test your security headers at securityheaders.com for a free grade and specific recommendations. Note: on static exports like Next.js output: "export", headers must be set at the host layer (Cloudflare, Nginx, CDN) not in the framework config.
6. Keep Dependencies Updated, Outdated Libraries Are Attack Surfaces
The majority of successful web application attacks exploit known vulnerabilities in outdated libraries and packages. Every npm package, Python pip package, WordPress plugin, and PHP library in your application is a potential attack surface if it is not kept up to date. Once a security vulnerability is publicly disclosed, it is a race between the attacker who can now target all unpatched installations and the developer who needs to update.
Automated dependency scanning
- Dependabot (GitHub): automatically opens pull requests when your dependencies have available updates or known vulnerabilities. Enable it in your GitHub repository settings.
- npm audit: run in your CI pipeline to block deployments when high-severity vulnerabilities are present.
- pip-audit: equivalent for Python projects.
- Snyk or Socket: more comprehensive SCA (software composition analysis) with runtime monitoring.
WordPress plugin management
WordPress plugin vulnerabilities are the most common attack vector for WordPress sites. Update plugins within 48 hours of a security release. Remove unused plugins, inactive plugins are still attack surfaces. Use the WPScan vulnerability database to check plugin security status.
7. WordPress-Specific Security
WordPress powers 43.5% of all websites, and attracts proportionally more attacks. WordPress core is secure when updated. The vulnerabilities are almost always in outdated plugins and themes, default configurations, and weak credentials.
Essential WordPress security checklist
- Update: WordPress core, all plugins, and all themes. Automate where possible.
- Remove the default "admin" username, create a new admin user with a unique name.
- Enable MFA on all admin accounts.
- Limit login attempts to prevent brute force attacks (Limit Login Attempts Reloaded).
- Change the default WordPress login URL from /wp-admin/ (reduces automated attacks).
- Set correct file permissions: 644 for files, 755 for directories, 600 for wp-config.php.
- Disable XML-RPC if not needed, it is a common brute force target.
- Install a security plugin (Wordfence, Sucuri) for malware scanning and firewall.
- Disable directory listing, ensure Options -Indexes is in your .htaccess.
See our WordPress security service for professionally managed WordPress security.
8. Backups and What to Do When Something Goes Wrong
The 3-2-1 backup rule
- 3 copies of your data.
- 2 different storage media or services.
- 1 copy offsite, in a different geographic location and a different account.
Ransomware attacks encrypt all drives accessible from the infected system. An offsite backup in a separate cloud account is not accessible to ransomware running on your web server.
Backup schedule
Database: daily minimum. Hourly for high-transaction sites. File system: weekly. After significant deployments. Test restores monthly, a backup you have not tested is not a backup.
Incident response, if your site is compromised
Step 1: Take the site offline. Put it in maintenance mode.
Step 2: Preserve logs. Do not delete anything before forensic review.
Step 3: Identify the attack vector. How did they get in?
Step 4: Remove malicious code. Scan all files and database content.
Step 5: Restore from a clean backup predating the compromise.
Step 6: Patch the vulnerability used for entry.
Step 7: Change all passwords, database, admin accounts, hosting, email.
Step 8: Report to affected users if personal data was exposed (GDPR, CCPA obligations).
Related Reading
Working on a secure website build project?
Written scope before billing. $30/hr. We tell you if we're not the right fit.

Akash Singh
·View full profileCTO and Co-Founder, CV Infotech · Gurugram, India
Akash has been building software for clients in the USA, UK, Australia, and Canada since 2012. He leads a 100% in-house team and personally manages every client relationship and technical decision. Francisco Escobar has worked with him since 2012. Steven has trusted the team with his AI platforms since 2019. 512 verified 5.0 reviews on Freelancer.com.
