JustAppSec

Secure Defaults in Modern Frameworks

How Rails, Next.js, Django, and Spring protect you — and where they don't.

0:00

Modern frameworks do a lot of security work for you — but only if you understand what they protect against and where the gaps are. This lesson maps the secure defaults in Rails, Django, Next.js, Spring Boot, and Express, and highlights where each framework leaves you on your own.

The framework contract

When you choose a framework, you are entering an implicit security contract: "use the framework as intended and we will protect you from common vulnerability classes." Break from the framework's patterns — raw queries, manual HTML construction, custom session handling — and you lose those protections.

Cross-site scripting (XSS)

FrameworkDefault behaviourGap
React / Next.jsJSX auto-escapes all interpolated valuesdangerouslySetInnerHTML bypasses encoding; href and src do not validate URL schemes
Vue / NuxtTemplate interpolation {{ }} auto-escapesv-html directive renders raw HTML
AngularSanitises DOM bindings automaticallybypassSecurityTrustHtml() disables sanitisation
DjangoTemplate engine auto-escapes by default`
Rails (ERB)<%= %> auto-escapesraw() and html_safe bypass encoding
Spring (Thymeleaf)th:text auto-escapesth:utext renders unescaped HTML

Takeaway: Every framework provides an escape hatch for raw HTML. Know what it is. Use it only with sanitised content.

SQL injection

FrameworkDefault behaviourGap
Django ORMParameterised queriesraw(), extra(), and string formatting in RawSQL()
Rails ActiveRecordParameterised queriesfind_by_sql with string interpolation, where("name = '#{name}'")
SQLAlchemyParameterised queries via ORMtext() with string formatting, engine.execute() with raw SQL
SequelizeParameterised queriessequelize.query() with replacements improperly used
PrismaParameterised by design$queryRaw and $executeRaw with template literals (use Prisma.sql tagged template instead)
Spring Data JPAParameterised queries via JPQL@Query with string concatenation, native queries without parameters

Takeaway: ORMs protect you when you use their query builders. Raw query methods bypass protections. When raw SQL is necessary, always parameterise.

CSRF protection

FrameworkDefault behaviourGap
DjangoCSRF middleware enabled by default; tokens required for POST/PUT/DELETEMust include {% csrf_token %} in forms; API views using @csrf_exempt are unprotected
RailsCSRF protection enabled by default with protect_from_forgeryAPI-only controllers often skip CSRF; token must be included in AJAX requests
Next.js / ExpressNo built-in CSRF protectionYou must add it yourself (use SameSite=Lax cookies as baseline; add CSRF tokens for sensitive actions)
Spring BootSpring Security includes CSRF by defaultOften disabled for REST APIs; must be paired with SameSite cookies

Takeaway: Django and Rails have CSRF protection out of the box. Node.js frameworks generally do not. SameSite=Lax cookies provide baseline protection in modern browsers, but tokens are still needed for sensitive state-changing operations in older configurations.

Authentication and session management

FrameworkDefault behaviourGap
DjangoBuilt-in auth system, sessions in database, CSRF tokensPassword hashing uses PBKDF2 by default (Argon2 available, not default)
RailsDevise gem (common but not built-in), signed cookie sessionsCookie sessions expose session data client-side (signed, not encrypted, by default in older versions)
Next.jsNo built-in authNextAuth.js / Auth.js is the common choice; configuration is your responsibility
Spring BootSpring Security provides comprehensive authComplex configuration; easy to misconfigure role hierarchies
ExpressNo built-in authPassport.js is common; session config, cookie flags, and storage are all manual

Takeaway: Django provides the most complete out-of-the-box authentication. Node.js and Express require you to assemble auth from components, which means more opportunities for misconfiguration.

Security headers

Most frameworks do not set security headers by default. You need to add them yourself:

Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: strict-origin-when-cross-origin
Content-Security-Policy: default-src 'self'
Permissions-Policy: camera=(), microphone=(), geolocation=()

Some frameworks and middleware help:

  • DjangoSecurityMiddleware sets HSTS, X-Content-Type-Options, and others when configured
  • Rails — sets X-Frame-Options, X-Content-Type-Options, and X-XSS-Protection by default
  • Helmet.js (Express/Node.js) — middleware that sets a sensible set of security headers
  • Spring Security — sets several security headers by default when enabled

File uploads

No major framework provides safe file upload handling by default. You are responsible for:

  • Validating file content (not just the extension or MIME type)
  • Sanitising filenames
  • Storing files outside the web root
  • Setting correct content types when serving

This is consistently a gap across all frameworks.

Default credentials and debug modes

RiskFrameworks affected
Debug mode in productionDjango (DEBUG=True), Rails (config.consider_all_requests_local), Next.js (error overlay), Spring Boot (Actuator endpoints)
Default secret keysDjango (SECRET_KEY in settings.py template), Rails (secret_key_base), Express (session secret)
Admin panelsDjango Admin is enabled by default in new projects; Spring Boot Actuator exposes management endpoints

Takeaway: Always change default secret keys before deploying. Never run debug mode in production. Restrict or disable admin panels and management endpoints in production.

The framework checklist

When starting a new project with any framework, verify:

  1. Is output encoding enabled by default? Where are the escape hatches?
  2. Does the ORM parameterise queries? What are the raw query methods?
  3. Is CSRF protection built in? Is it enabled for your use case?
  4. What security headers are set? What is missing?
  5. What is the default session storage and cookie configuration?
  6. Are there any default credentials, secret keys, or debug settings that must be changed?
  7. How does the framework handle file uploads?

Summary

Frameworks provide significant security benefits — but only when used as intended. Auto-encoding, parameterised queries, and CSRF tokens protect you from the top vulnerability classes, but every framework has escape hatches. Know what your framework does by default, where the gaps are, and what you need to add yourself. The most dangerous assumption is that the framework handles everything.


This training content is AI-assisted and reviewed by our team, but issues may be missed and best practices evolve rapidly. Send corrections to [email protected].