Every 39 seconds, a hacker attacks a website. That statistic comes from a University of Maryland study, and it has only gotten worse since then. Automated bots scan the internet 24/7, probing for misconfigured servers, exposed API keys, and missing security headers. They do not care if your site gets 10 visitors or 10 million.
Most developers never check if their website is secure until something goes wrong. A customer reports their account was compromised. Google flags your domain as unsafe. You find your Stripe secret key indexed on GitHub. By then, the damage is done.
The good news: a basic website security check takes about five minutes. You do not need a security background. You do not need expensive tools. You just need to know what to look for.
Here are seven checks you can run right now to find out if your website is secure.
1. Check Your SSL Certificate
SSL (technically TLS) encrypts the connection between your users and your server. Without it, everything -- passwords, credit card numbers, personal data -- travels in plain text that anyone on the network can read.
How to check:
Open your website in Chrome and click the padlock icon (or the tune icon) in the address bar. Click "Connection is secure" and then "Certificate is valid." You will see:
- Issued to: Your domain name
- Issued by: The certificate authority (Let's Encrypt, Cloudflare, etc.)
- Expires on: The expiration date
If your certificate expires within 30 days, renew it now. An expired certificate will show users a full-page browser warning, and most will leave immediately.
Check for mixed content:
Even with a valid certificate, your site might load some resources (images, scripts, fonts) over plain HTTP. This is called mixed content, and it weakens your encryption.
Open DevTools (F12), go to the Console tab, and look for warnings like:
Mixed Content: The page at 'https://yoursite.com' was loaded over HTTPS,
but requested an insecure resource 'http://cdn.example.com/image.jpg'.
Fix these by updating the URLs to use https:// or protocol-relative // prefixes.
What a failing check means: Without valid SSL, your site is vulnerable to man-in-the-middle attacks. Attackers can intercept and modify data in transit. Google also penalizes non-HTTPS sites in search rankings.
2. Test Your Security Headers
Security headers are HTTP response headers that instruct browsers how to handle your content. They are one of the most effective defenses against common attacks, and most websites are missing several of them.
How to check:
Open DevTools (F12), go to the Network tab, reload the page, and click on the first request (your HTML document). Scroll down to the Response Headers section. Look for these headers:
- Strict-Transport-Security (HSTS) -- Forces HTTPS connections. Should include
max-age=31536000; includeSubDomains. - Content-Security-Policy (CSP) -- Controls which scripts, styles, and resources can load. Without it, cross-site scripting attacks become trivially easy.
- X-Frame-Options -- Prevents your site from being embedded in iframes on malicious domains (clickjacking). Should be
DENYorSAMEORIGIN. - X-Content-Type-Options -- Should be
nosniff. Prevents browsers from guessing content types, which can turn a harmless file into an executable script. - Referrer-Policy -- Controls how much URL information leaks to third-party sites.
strict-origin-when-cross-originis a good default. - Permissions-Policy -- Restricts access to browser APIs like camera, microphone, and geolocation.
You can also test from the terminal:
curl -I https://yoursite.com
This prints all response headers. Missing headers will simply not appear in the output.
What a failing check means: Missing security headers leave you open to clickjacking, XSS, MIME sniffing, and protocol downgrade attacks. The good news is they are easy to add. Most frameworks let you set them in a single configuration file. For a deep dive, read our complete security headers guide.
3. Search for Exposed Secrets in Your Source Code
This is the check that surprises most developers. API keys, database credentials, and secret tokens end up in client-side code more often than you would think -- especially in apps built with AI coding assistants that sometimes hardcode values during prototyping.
How to check:
Open your site in a browser and view the page source (Ctrl+U or Cmd+Option+U). Press Ctrl+F and search for:
sk_live(Stripe secret keys)AKIA(AWS access keys)eyJ(JWT tokens, which are base64-encoded and start with this prefix)apikeyorapi_keysecretpasswordtokensupabasecombined withservice_role
Then check your JavaScript bundles. In DevTools, go to Sources, find your JS files, and search the same terms. Bundlers sometimes inline environment variables if you are not careful with your .env configuration.
Check your git history too:
Even if you removed a secret from your code, it might still be in your git history.
git log --all --full-history -S "sk_live" -- .
This searches your entire git history for any commit that added or removed a string containing sk_live. Replace it with whatever secret pattern you are looking for.
What a failing check means: Exposed API keys are a critical severity issue. Attackers actively scan public websites and GitHub repositories for credentials. A leaked Stripe secret key gives full access to your payment system. A leaked Supabase service role key bypasses all row-level security. Rotate any exposed key immediately and remove it from your code. For more detail, see our API key leak detection guide.
4. Test Your CORS Configuration
Cross-Origin Resource Sharing (CORS) controls which external domains can make requests to your API. A misconfigured CORS policy can allow any website to make authenticated requests on behalf of your users.
How to check:
Run this curl command, replacing the URLs with your own:
curl -I -X OPTIONS \
-H "Origin: https://evil-site.com" \
-H "Access-Control-Request-Method: GET" \
https://yoursite.com/api/some-endpoint
Look at the response headers:
Access-Control-Allow-Origin: *
If you see * (wildcard) and your API uses cookies or authentication, you have a problem. This means any website can make requests to your API.
What a bad configuration looks like:
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
This combination is especially dangerous. It tells browsers that any origin can make credentialed requests to your API. An attacker's website could steal your users' data by making requests with their session cookies.
What a good configuration looks like:
Access-Control-Allow-Origin: https://yoursite.com
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Credentials: true
The origin should be your specific domain, not a wildcard. If you need to support multiple domains, validate the Origin header against an allowlist on the server side.
For a comprehensive walkthrough, read our CORS misconfiguration guide.
5. Check for Known Vulnerabilities in Your Dependencies
Your application probably depends on hundreds of open-source packages. Each one is a potential attack surface. Known vulnerabilities in popular packages are published in public databases, and attackers actively exploit them.
How to check:
If you are using Node.js:
npm audit
This scans your package-lock.json against the npm advisory database and lists every known vulnerability, grouped by severity (critical, high, moderate, low).
For automatic fixes:
npm audit fix
For a more thorough scan that includes transitive dependencies:
npx audit-ci --critical
If you are using Python:
pip audit
If you are using Ruby:
bundle audit check --update
What a failing check means: Known vulnerabilities in dependencies are among the most exploited attack vectors. The severity depends on the specific vulnerability. A critical vulnerability in a package that handles user input (like a request parser or template engine) could allow remote code execution. Even moderate vulnerabilities should be patched promptly because attackers combine multiple lower-severity issues to escalate access.
6. Test Your Authentication Flows
Authentication is where most web applications are most vulnerable. A weakness here gives attackers direct access to user accounts.
Things to test manually:
Session fixation: Log in, copy your session cookie value, log out, and log back in. If the session cookie value is the same, your application is not regenerating sessions on login. An attacker who can set a session cookie before the user logs in would then have access to their authenticated session.
Password reset flow: Request a password reset. Check:
- Does the reset link expire? (It should, within 15-60 minutes.)
- Can you use it more than once? (You should not be able to.)
- Does it contain the user's email or ID in the URL? (It should not -- use a random token.)
Brute force protection: Try logging in with the wrong password 10 times in a row. Does anything happen? You should see rate limiting (HTTP 429) after 5-10 failed attempts. Without it, attackers can try thousands of passwords per minute.
Account enumeration: Try logging in with a nonexistent email. If the error says "No account with that email" but says "Incorrect password" for a real email, an attacker can enumerate which email addresses have accounts on your platform. Both cases should return a generic "Invalid email or password" message.
What a failing check means: Authentication vulnerabilities range from high to critical severity. Weak session management can lead to account takeover. Missing rate limiting enables brute-force attacks. These issues require code changes to fix but are well worth the effort.
7. Run an Automated Security Scan
The six checks above cover the most common issues, but they are manual and limited in scope. A website security check tool can test for dozens of additional vulnerability categories in seconds, including things that are impractical to test by hand.
An automated website vulnerability check typically covers:
- SQL injection across all discoverable endpoints
- Cross-site scripting (reflected and stored)
- Insecure cookie configuration (missing Secure, HttpOnly, SameSite flags)
- Open redirect vulnerabilities
- Information disclosure (server version headers, debug endpoints, stack traces)
- DNS configuration issues (SPF, DKIM, DMARC for email security)
- Subdomain takeover risks
- GraphQL introspection exposure
- JWT implementation weaknesses
Running all of these manually would take hours. An automated scanner does it in under a minute.
CheckVibe runs 100+ security checks against your website in about 30 seconds. Paste your URL, hit scan, and get a prioritized report with specific issues and severity ratings. No signup required for your first scan.
What Each Check Reveals: Understanding Severity Levels
Not all security issues are equally urgent. When you run a website security check, the results are typically grouped by severity. Here is what each level means and how to prioritize.
Critical Severity
These need immediate attention. An attacker can exploit them right now to cause serious damage.
- Exposed API keys or secrets -- Leaked credentials in client-side code or public repositories
- SQL injection -- Direct database access through unvalidated input
- Remote code execution -- Vulnerabilities that let attackers run arbitrary code on your server
- Authentication bypass -- Ways to access accounts without valid credentials
Action: Stop what you are doing and fix these now. Rotate any exposed credentials immediately.
High Severity
These are serious but may require more specific conditions to exploit.
- Missing Content-Security-Policy -- Opens the door to cross-site scripting
- Cross-site scripting (XSS) -- Script injection through reflected or stored input
- Insecure CORS configuration -- Unauthorized cross-origin access to your API
- Missing HSTS -- Users can be downgraded from HTTPS to HTTP
Action: Fix within 24-48 hours. These are actively exploitable under the right conditions.
Medium Severity
These represent weaker security posture but are harder to exploit directly.
- Insecure cookie flags -- Missing Secure, HttpOnly, or SameSite attributes
- Information disclosure -- Server version headers, verbose error messages
- Missing X-Frame-Options -- Clickjacking potential
- Weak referrer policy -- URL information leaking to third parties
Action: Fix within a week. These are typically quick configuration changes.
Low Severity
These are best-practice improvements rather than immediate threats.
- Missing Permissions-Policy header -- Browser API access not restricted
- Suboptimal TLS configuration -- Supporting older protocol versions that are not yet broken
- Missing DNS security records -- SPF, DKIM, DMARC not fully configured
Action: Add to your backlog and address in your next maintenance cycle.
What to Do If You Find Issues
Finding vulnerabilities in your own website can feel overwhelming. Here is the practical approach.
Do not panic. Most websites have security issues. The fact that you are checking puts you ahead of the majority of developers.
Prioritize by severity. Fix critical issues first, then high, then medium. Do not let the volume of findings paralyze you. Even fixing one critical issue dramatically reduces your risk.
Use AI fix prompts. If you use Cursor, Copilot, or another AI coding assistant, you can paste the specific finding into your editor and ask for a fix. For example:
My site is missing the Content-Security-Policy header.
I'm using Next.js 16. Add a CSP header in next.config.ts
that allows scripts from 'self' and blocks inline scripts.
Most security issues have straightforward fixes. Missing headers are a configuration change. Exposed secrets require rotation and moving to environment variables. Dependency vulnerabilities are usually fixed by updating the package.
Verify your fixes. After making changes, run the scan again to confirm the issues are resolved. Security is not a one-time task -- it is a continuous process.
The Free Security Scan Option
You can work through all seven checks manually. It will take longer than five minutes, and you will miss things that only automated tools can catch. Or you can get a comprehensive website security check in about 30 seconds.
CheckVibe scans your website against 100+ security checks covering everything in this guide and more:
- 36 security scanners covering SSL, headers, XSS, SQLi, CORS, CSRF, cookies, authentication, API keys, DNS, dependencies, and platform-specific issues
- Site crawling discovers pages and endpoints automatically -- it does not just test your homepage
- AI-powered fix suggestions give you copy-paste prompts for Cursor, Copilot, and other AI editors
- Severity-prioritized results so you know exactly what to fix first
- PDF export for compliance documentation or sharing with your team
- No security expertise required -- findings are written in plain language with specific remediation steps
Paste your URL, hit scan, and see your results. Your first scan is free with no signup required.
How Often Should You Check?
A single scan is a snapshot. Your website's security posture changes every time you deploy code, update a dependency, or change a configuration.
After every deploy is ideal. New code means new potential vulnerabilities. If you added a new API endpoint, changed your authentication logic, or updated your dependencies, scan again.
Weekly at minimum. Even if your code hasn't changed, the threat landscape has. New vulnerabilities are disclosed in popular packages every day. A dependency that was safe last week might have a critical CVE today.
After any dependency update. Running npm update or pip install --upgrade can introduce packages with known vulnerabilities, especially if you are updating major versions.
Use monitoring for continuous checking. Instead of remembering to scan manually, set up scheduled scans. CheckVibe supports daily, weekly, and monthly automated scans with alert rules. You can get notified when your security score drops, when a new critical issue appears, or when your score falls below a threshold you set.
Continuous monitoring is especially important if you are a solo developer or a small team. You cannot manually audit your site every day, but an automated scanner can.
FAQ
Is my website secure if it has HTTPS?
No. HTTPS (SSL/TLS) is necessary but not sufficient. It encrypts data in transit, which prevents eavesdropping, but it does not protect against:
- Cross-site scripting (XSS)
- SQL injection
- Exposed API keys in your client-side code
- Missing security headers
- Insecure authentication
- Vulnerable dependencies
HTTPS is the foundation. The six other checks in this guide cover what HTTPS does not.
Can hackers really find my API keys?
Yes, and they do it constantly. Automated bots scrape websites and public GitHub repositories for credential patterns. Services like Trufflehog and GitLeaks exist specifically for this purpose, and attackers use similar tools.
AWS reports that exposed access keys are typically exploited within minutes of being pushed to a public repository. Stripe actively scans for leaked keys and will notify you, but by the time they do, an attacker may have already used them.
If you are building with AI coding tools like Cursor or Copilot, be extra careful. These tools sometimes hardcode API keys during prototyping, and those values can make it into production if you are not reviewing the generated code carefully.
Do I need a security scanner if I use a framework like Next.js?
Yes. Frameworks handle some security concerns (like CSRF protection in form submissions), but they do not cover everything:
- Next.js does not set security headers by default. You have to configure them in
next.config.ts. - Framework middleware can be bypassed if routes are misconfigured.
- Your application logic (authentication, authorization, input validation) is your responsibility regardless of framework.
- Third-party packages you install can introduce vulnerabilities the framework cannot prevent.
- Platform-specific issues (Supabase RLS, Vercel configuration, environment variable exposure) are outside the framework's scope.
A framework gives you a safer starting point, not a guarantee of security.
What is the most common website vulnerability?
According to the OWASP Top 10, the most common categories are:
- Broken Access Control -- Users accessing data or functions they should not have access to
- Cryptographic Failures -- Weak encryption, exposed secrets, missing HTTPS
- Injection -- SQL injection, XSS, and command injection
In practice, the most common issues we see on scanned websites are missing security headers (especially CSP and HSTS), exposed API keys in client-side JavaScript, and outdated dependencies with known vulnerabilities. These are also the easiest to fix.
How much does a security breach cost?
The IBM Cost of a Data Breach Report puts the global average at $4.88 million. For small businesses, the average is lower but still devastating -- between $120,000 and $1.24 million, which is enough to shut down many startups.
But the cost is not just financial. There is also:
- Reputation damage -- Users lose trust and leave
- Regulatory fines -- GDPR violations can cost up to 4% of annual revenue
- Development time -- Incident response and remediation pull your team away from building
- Legal liability -- Users whose data is exposed may pursue legal action
The cost of prevention is a fraction of the cost of a breach. Running a security scan takes 30 seconds. Recovering from a breach takes months.
Skip the Manual Checks
You now know the seven things to check and why they matter. You can work through them one by one, or you can get all the answers in 30 seconds.
Run a free security scan on CheckVibe -- paste your URL, get a full security report with severity-prioritized findings and AI fix prompts for your code editor. No signup required for your first scan.
Your website is either secure or it is not. The only way to know is to check.