Skip to content
OY ozgur yildiz
home writing work about
say hi →
/ writing / tags / #Security

#Security

38 posts tagged with this topic. ← All tags

  • Nov 17, 2025

    Content Security Policy: the header that stops injected scripts cold.

    How Content Security Policy works, how to write a CSP header, and how to deploy it without breaking your application.

  • Oct 30, 2025

    TLS/HTTPS: what happens in the handshake and why it takes time.

    A step-by-step look at the TLS handshake, what each round trip accomplishes, and how TLS 1.3 and session resumption reduce the cost.

  • Mar 31, 2025

    WebSocket authentication: passing a token without cookies.

    WebSocket connections don't support Authorization headers in the browser. The patterns for authenticating WebSocket connections -- query params, first-message auth, and cookie-based approaches.

  • Oct 17, 2024

    Multi-stage Docker builds: the technique that cuts image size by 60%.

    Multi-stage builds compile or bundle your application in one stage and copy only the artifacts to a minimal production image, leaving build tools and dev dependencies behind.

  • Oct 14, 2024

    Docker volumes: why your data disappears and how to make it persist.

    Containers have ephemeral storage — data written inside a container is lost when it's deleted. Volumes are how you make data survive container restarts and replacements.

  • Oct 10, 2024

    docker-compose for Node + MongoDB: local dev without installing anything.

    A complete docker-compose setup for a Node.js API and MongoDB that gives every developer an identical local environment without installing Node or MongoDB on their machine.

  • Oct 7, 2024

    A Dockerfile for a Node app that actually works in production.

    A production-ready Node.js Dockerfile with a non-root user, proper signal handling, layer caching optimization, and a minimal base image.

  • Oct 3, 2024

    Docker images vs containers: the mental model in 3 sentences.

    Developers often conflate Docker images and containers. The distinction is simple but important — getting it right makes every other Docker concept easier to understand.

  • Sep 30, 2024

    Write migrations that can run twice without breaking anything.

    Idempotent migrations don't fail if they've already been applied. This property makes deployments safer and CI pipelines more reliable.

  • Sep 26, 2024

    EXPLAIN ANALYZE: reading a query plan to find the slow part.

    EXPLAIN ANALYZE runs a query and shows exactly how PostgreSQL executed it — which indexes were used, how many rows were scanned, and where the time was spent.

  • Sep 23, 2024

    Full-text search in PostgreSQL: no extra service required.

    PostgreSQL's built-in full-text search uses tsvector and tsquery to support ranked, stemmed, stop-word-filtered search without adding Elasticsearch or another service.

  • Sep 19, 2024

    JSONB columns: flexible schema without breaking your relational model.

    PostgreSQL's JSONB type stores structured JSON with binary indexing and full operator support. It adds flexibility for variable attributes without requiring a document database.

  • Sep 16, 2024

    Window functions in PostgreSQL: running totals without a subquery.

    Window functions compute values across rows related to the current row without collapsing them into groups. They're the clean solution to running totals, rankings, and row comparisons.

  • Sep 12, 2024

    INNER vs LEFT JOIN: the one you reach for 90% of the time and why.

    INNER JOIN returns only matching rows. LEFT JOIN returns all rows from the left table. Choosing wrong silently drops data or inflates result sets — here's how to think about it.

  • Sep 9, 2024

    PostgreSQL indexes: B-tree, partial, composite and which queries need each.

    Not every index type is right for every query. PostgreSQL offers B-tree, partial, and composite indexes with different cost profiles. Here's how to match index type to query pattern.

  • Sep 5, 2024

    Relational modeling: when to normalize and when to stop.

    Normalization removes redundancy but adds joins. The practical question is which normal form your schema should target and when denormalization is the right engineering tradeoff.

  • Sep 2, 2024

    Soft deletes: why you almost never want to actually delete data.

    Hard deletes are irreversible and break foreign key references. The soft delete pattern marks records as deleted while keeping them in the database, enabling recovery and audit trails.

  • Aug 29, 2024

    Atlas Search: full-text search without adding Elasticsearch to your stack.

    MongoDB Atlas Search provides Lucene-powered full-text search natively in MongoDB, eliminating the need for a separate Elasticsearch cluster for most search use cases.

  • Aug 26, 2024

    Schema versioning in MongoDB: migrations without downtime.

    MongoDB's flexible schema doesn't eliminate the need for migrations — it changes how you do them. Here's the lazy migration pattern that updates documents without a big-bang script.

  • Aug 22, 2024

    Mongoose populate vs $lookup: same result, very different performance.

    Mongoose's populate() runs multiple queries in application code. $lookup joins in the database. Understanding the difference prevents N+1 query problems at scale.

  • Aug 19, 2024

    MongoDB transactions: what they cost and when they're worth it.

    MongoDB supports multi-document ACID transactions since version 4.0, but they carry overhead. Understand when you genuinely need them and when document modeling eliminates the need.

  • Aug 15, 2024

    The aggregation pipeline: $match, $group, $project with a real example.

    MongoDB's aggregation pipeline processes documents through stages. Walk through a real analytics query using $match, $group, and $project to understand how data flows between stages.

  • Aug 12, 2024

    MongoDB without indexes is a full collection scan every time.

    Without the right indexes, every query MongoDB runs reads every document in the collection. Here's how indexes work, how to create them, and how to verify they're being used.

  • Aug 8, 2024

    Mongoose validators: catching bad data before it reaches the database.

    Mongoose schema validation runs before writes and can be customized beyond built-in types. Here's how built-in, custom, and async validators work and when to use each.

  • Aug 5, 2024

    Embed vs reference in MongoDB: the decision that's hard to undo.

    MongoDB gives you the choice to embed related data or reference it. The wrong choice causes either performance problems or query complexity that's expensive to reverse later.

  • Aug 1, 2024

    Secrets in env variables: why .env is not enough and what to do instead.

    Environment variables are better than hardcoding secrets, but .env files have real risks. Here's the threat model and the patterns that actually protect secrets in production.

  • Jul 29, 2024

    XSS in React: the one dangerous prop and the headers that block the rest.

    React escapes output by default, but one escape hatch can reintroduce XSS. Understand dangerouslySetInnerHTML, when it's legitimate, and the HTTP headers that provide defense in depth.

  • Jul 25, 2024

    Parameterized queries are the only SQL injection fix that works. No exceptions.

    SQL injection persists because developers reach for string sanitization instead of parameterized queries. Here's why sanitization fails and how parameters work at the driver level.

  • Jul 22, 2024

    CSRF is not just a checkbox. Here's the attack and why tokens stop it.

    Walk through a real CSRF attack against a cookie-based session, then understand exactly why the synchronizer token pattern defeats it at the HTTP level.

  • Jul 18, 2024

    Google sign-in with OAuth 2.0: what happens in those 6 redirects.

    Step through the complete OAuth 2.0 authorization code flow that powers Google sign-in, explaining each redirect and what's being exchanged at each step.

  • Jul 15, 2024

    RBAC: the middleware pattern that scales from 2 roles to 20.

    Role-based access control implemented as Express middleware — a clean pattern that keeps authorization logic out of route handlers and scales without becoming unmanageable.

  • Jul 11, 2024

    bcrypt's cost factor: what changing that number actually does.

    The cost factor in bcrypt is not arbitrary — it controls exactly how long hashing takes and why that slowness is the entire point of the algorithm.

  • Jul 8, 2024

    Refresh tokens: the rotation pattern that lets you kick stolen sessions.

    Refresh token rotation solves the core problem with stateless JWTs: you can detect and invalidate stolen tokens without a server-side session store.

  • Jul 4, 2024

    Signing a token is not encrypting it. The difference matters.

    Signing proves integrity and authenticity. Encryption provides confidentiality. Confusing the two leads to real security vulnerabilities in authentication systems.

  • Jul 1, 2024

    A JWT is three base64 strings. Here's what's actually inside yours.

    Decode a real JWT and understand what each of the three parts contains, why they're base64url encoded, and what you can and cannot trust.

  • May 20, 2024

    Helmet adds 11 security headers in one line. Here's what each does.

    Helmet is a collection of Express middleware that sets HTTP security headers. Here's what each header actually does and why you want it enabled.

  • May 16, 2024

    CORS: the config that works and the one that silently breaks everything.

    CORS errors happen in the browser, not the server, which makes them confusing to debug. Here's how CORS actually works and the Express config that gets it right.

  • May 13, 2024

    Validate the request before it reaches your handler.

    Putting validation logic inside route handlers pollutes business logic and lets bad input reach your database. Here's how to intercept it earlier with middleware.

OY ozgur yildiz
GitHub LinkedIn Email RSS
© 2026 ozgur yildiz. all rights reserved.