security

CORS configuration for Rails APIs

Cross-Origin Resource Sharing (CORS) allows browsers to make requests from React apps hosted on different domains than the Rails API. The rack-cors gem configures CORS middleware with fine-grained control over origins, methods, and headers. In develop

Safer HTML Sanitization Pipeline

User content needs defense in depth: markdown rendering + sanitization + link attribute hygiene. Keep the allowed tags list explicit and test it. Don’t trust upstream renderers to be safe by default.

Template rendering with html/template and strict escaping

Even in API-heavy systems, I occasionally render HTML emails or a lightweight admin page. I always use html/template (not text/template) so content is escaped by default, which prevents accidental XSS when variables contain user input. I also keep tem

Webhook signature verification

When receiving webhooks from external services, signature verification ensures the payload comes from the claimed sender and hasn't been tampered with. Services like Stripe and GitHub include an HMAC signature in headers computed from the request body

Pre-signed S3 upload from the browser

Large file uploads don’t belong on app servers. My default is: the server issues a short-lived pre-signed URL, the browser uploads directly to S3, then the server stores the object key. That keeps latency low and costs predictable. Before signing, I v

Docker image optimization and security scanning

Optimized Docker images reduce build time, storage, and attack surface. Alpine-based images start at 5MB versus 100MB+ for Debian. Multi-stage builds separate build tools from runtime—final image contains only production artifacts. Layer ordering matt

Encrypted SharedPreferences for secure storage

EncryptedSharedPreferences secures simple key-value data using Android Keystore. I create instances with EncryptedSharedPreferences.create() specifying encryption schemes. The master key uses MasterKeys or MasterKey.Builder for automatic key generatio

Turbo Streams: partial page auth failure handling

When a session expires, Turbo requests can start returning 401/302 and the UI gets confusing. Handle unauthorized turbo requests explicitly: return a stream that updates a “session expired” banner or triggers a redirect.

Password hashing with Argon2

Bcrypt is fine, but Argon2 is the modern default with better resistance to GPU attacks. I store the full hash string (it includes parameters + salt) and keep verification in one utility so the rest of the app doesn’t grow its own auth helpers. The imp

Rate limiting by IP + user (Express)

A single abusive client can ruin your latency budget for everyone else, so I rate limit early rather than trying to ‘detect abuse’ after the outage starts. I combine an IP bucket with a user bucket: IP protects unauthenticated endpoints, user protects

Audit logging for sensitive operations

Audit logs provide accountability and forensic capabilities for sensitive operations like permission changes, data deletion, or financial transactions. I store audit events in a dedicated table with who performed the action, what changed, when it occu

JWT authentication with refresh tokens

Stateless authentication with JWT tokens simplifies horizontal scaling but introduces security concerns around token lifetime and revocation. I use short-lived access tokens (15 minutes) combined with longer-lived refresh tokens stored in an encrypted