// AppSec blueprint

Web Security Fundamentals: Demystifying HTTPS, SSL Certificates, and CORS

A comprehensive developer's guide to core web security concepts. Demystify how HTTPS works, how SSL/TLS certificates secure channels, and how to configure Cross-Origin Resource Sharing (CORS) safely.

Published: June 5, 2026 · 13 min read · Category: AppSec

Tags: Security, AppSec, HTTPS, SSL, CORS, Web Security, Cryptography

Introduction

Have you ever wondered what happens when you enter your password on a website? Without security measures in place, your password travels across the internet in plain text. Any router, internet service provider, or hacker sitting on a public Wi-Fi network between you and the website can read it as easily as reading a postcard. Similarly, when you build a web app, how does your browser prevent a malicious website from executing scripts that steal your bank session cookies?

The internet is built on open protocols. Originally, security was an afterthought. Today, modern web applications rely on cryptographic systems and browser sandboxing mechanisms to protect users. Among these, HTTPS, SSL/TLS Certificates, and Cross-Origin Resource Sharing (CORS) form the core triangle of web security. However, many developers view these protocols as obstacles that trigger frustrating console errors rather than vital protective shields. This guide demystifies these security fundamentals, showing you exactly how they protect your data and how to configure them for production.


How HTTPS and SSL/TLS Handshakes Work

To secure connection paths across the web, we use HTTPS (Hypertext Transfer Protocol Secure). HTTPS is simply the standard HTTP protocol wrapped in a layer of encryption called TLS (Transport Layer Security, formerly known as SSL).

1. What is an SSL/TLS Certificate?

An SSL/TLS certificate is a digital passport issued by a trusted third party called a Certificate Authority (CA) (e.g., Let's Encrypt). The certificate contains the website's public key, the domain name it is issued to, and the digital signature of the CA. It proves two things:

  • Identity: The website is who it claims to be.
  • Encryption: The connection between the client and server can be securely encrypted.

2. The TLS 1.3 Handshake Protocol

Before a single byte of HTTP data (like web page content) is sent, the client (browser) and server perform a cryptographic handshake to establish a secure, shared key. Here is a visual flow of how a TLS handshake occurs:

Client (Browser)                                        Web Server
       │                                                    │
       │ 1. CLIENT HELLO                                    │
       │ ──( Supported Ciphers, Client Random Key Share )─► │
       │                                                    │
       │ 2. SERVER HELLO                                    │
       │ ◄─( Chosen Cipher, Server Random Key, Certificate )│
       │                                                    │
       │ [ Client validates Certificate against CA roots ]  │
       │ [ Both calculate Symmetric Session Key ]           │
       │                                                    │
       │ 3. HANDSHAKE FINISHED                              │
       │ ◄─( Encrypted confirmation message )────────────── │
       │                                                    │
       │ 4. SECURE CHANNEL ESTABLISHED                      │
       │ ◄══( Data encrypted with Symmetric Session Key )══►│
       │                                                    │

During the handshake:

  • Asymmetric Cryptography (public/private key pair) is used initially to authenticate the server and securely exchange random parameters without anyone intercepting them.
  • Symmetric Cryptography (a single temporary session key) is then generated by both sides. This session key is used to encrypt all actual HTTP traffic because symmetric encryption is much faster and requires less processor power.

Demystifying CORS (Cross-Origin Resource Sharing)

CORS is another concept that often confuses developers. Many write code, run into a CORS error in their browser console, and fix it by installing a browser extension or setting Access-Control-Allow-Origin: * in production—which creates a massive security vulnerability.

1. The Same-Origin Policy (SOP)

To understand CORS, you must first understand the Same-Origin Policy. This is a security rule built into every web browser. It states that scripts running on one origin (e.g., https://malicious-site.com) cannot access data from a different origin (e.g., https://samadshaikh.dev or https://yourbank.com).

An origin is defined by three parts: Protocol (HTTPS), Domain (domain.com), and Port (443). If any of these differ, it is considered a cross-origin request.

2. Why CORS Exists

The Same-Origin Policy is very strict. However, modern websites need to load assets and call APIs from other domains (like loading maps, fonts, or microservices). CORS is a browser-enforced mechanism that allows a server to tell the browser: "Yes, I trust this specific external origin. You are allowed to read my data."

3. The Preflight (OPTIONS) Request

When a browser makes a cross-origin request that could change database state (like a POST request with JSON content), it first sends an empty check-in request called a Preflight Request using the OPTIONS method:

Browser                                                   API Server
   │                                                           │
   │ 1. Preflight OPTIONS Request                              │
   │ ──( Origin: samadshaikh.dev, Method: POST )─────────────► │
   │                                                           │
   │ 2. Preflight Response                                     │
   │ ◄─( Access-Control-Allow-Origin: samadshaikh.dev )─────── │
   │                                                           │
   │ [ Browser validates origin match... Match OK! ]           │
   │                                                           │
   │ 3. Actual HTTP POST Request                               │
   │ ──( JSON Payload / Data )───────────────────────────────► │
   │                                                           │
   └───────────────────────────────────────────────────────────┘

If the server does not return headers authorizing the origin, the browser blocks the response, throwing a CORS error.


Production-Grade Code Configurations

To secure your web applications, you must implement these protocols correctly in your infrastructure and backend code.

1. Nginx SSL Certificate and Secure Header Setup

This configuration runs on your web server. It configures HTTPS parameters, forces modern TLS 1.3 encryption, and applies secure HTTP headers to prevent security exploits:

# filepath: nginx/conf.d/secure_server.conf
server {
    listen 80;
    listen [::]:80;
    server_name samadshaikh.dev;
    
    # Redirect all insecure HTTP traffic to secure HTTPS
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name samadshaikh.dev;

    # SSL Certificate Paths (Managed by Let's Encrypt / Certbot)
    ssl_certificate /etc/letsencrypt/live/samadshaikh.dev/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/samadshaikh.dev/privkey.pem;

    # Enforce modern TLS protocols (Drop old, insecure SSLv3, TLS 1.0, 1.1)
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';

    # Optimize SSL Handshake Session Cache (Saves CPU cycles)
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off;

    # Security Headers
    # 1. HSTS (HTTP Strict Transport Security) - forces browsers to always use HTTPS
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    # 2. Prevent clickjacking attacks
    add_header X-Frame-Options "DENY" always;
    # 3. Prevent browser from sniffing content-type
    add_header X-Content-Type-Options "nosniff" always;
    # 4. Limit cross-origin referrer leakage
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;

    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

2. Express.js (Node.js) Secure CORS Middleware

Here is a production Node.js configuration using the cors package to dynamically validate origins against an environment-configured whitelist instead of using the wildcard (*):

// filepath: src/middleware/cors.ts
import express from 'express';
import cors from 'cors';

const app = express();

// Whitelist of domains allowed to request our API resources
const originWhitelist = [
  'https://samadshaikh.dev',       // Production Portfolio
  'https://samadshaikh.me',        // Production Resume
  'http://localhost:5173'          // Local Vite Dev Server
];

const corsOptions: cors.CorsOptions = {
  origin: (origin, callback) => {
    // Check if origin is in whitelist (or undefined for local tools like curl/Postman)
    if (!origin || originWhitelist.indexOf(origin) !== -1) {
      callback(null, true);
    } else {
      callback(new Error('Blocked by security boundary: CORS Policy Violation'));
    }
  },
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
  allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With'],
  exposedHeaders: ['Content-Range', 'X-Content-Range'],
  credentials: true, // Allow cookies and authorization headers to pass
  maxAge: 86400      // Cache preflight OPTIONS responses for 24 hours (reduces network requests)
};

// Apply CORS middleware to Express application
app.use(cors(corsOptions));

app.post('/api/secure-endpoint', (req, res) => {
  res.json({ message: 'Success! Your connection is authenticated.' });
});

Security & Performance Implementations

Web security configurations require careful management to balance protection with application speed.

  • Performance: SSL Session Resumption: Standard TLS handshakes add latency to web requests. You can optimize this by enabling SSL session cache and session tickets in your Nginx settings. This allows returning users to reconnect using their previous session keys, reducing the handshake duration from two round trips to one.
  • Security: Cross-Site Scripting (XSS): CORS protects you from cross-origin data theft, but it does not protect you from XSS. If an attacker injects a script into your frontend (via a comment box or input field), they can access cookies and localStorage directly. To prevent this, store authentication tokens in cookies configured with the HttpOnly, Secure, and SameSite=Strict flags.
  • Avoid the Wildcard with Credentials: If you need to support authenticated requests (e.g., using cookies or authorization headers), the browser will block the request if your server returns Access-Control-Allow-Origin: . You must configure your server to return the exact origin name in the headers.

Reading Recommendations

To learn more about implementing security frameworks across development operations, check out:

  • Zero-Trust Authentication: JWT Security Best Practices: Secure your authentication workflows using stateless JSON Web Tokens.
  • Securing LLM Integrations: Preventing Prompt Injection: Learn how to protect web applications that incorporate LLMs from data exposure.

References & Resources

  • Mozilla Developer Network (MDN): CORS Web Documentation
  • Let's Encrypt Project: How Let's Encrypt Works
  • OWASP Cheat Sheet Series: Transport Layer Security Cheat Sheet

Feedback & Collaboration

Have you run into CORS errors while building a frontend dashboard, or are you trying to configure SSL parameters for a complex domain structure? Let's discuss! Check out my projects on samadshaikh.dev, view my background on my Resume Portal, or drop me a message via the Connect page.

Written by Samad Shaikh · Back to all articles