Laravel Cookie Null Domain Configuration

Low Risk Configuration Weakness
laravelphpcookiesdomainconfigurationsubdomain-security

What it is

The Laravel application sets cookies with a null or unspecified domain, which can lead to unintended cookie sharing across subdomains or security issues in multi-domain environments. This configuration may allow cookies to be sent to unintended hosts or fail to properly restrict cookie scope.

// Vulnerable: Null or unspecified cookie domain public function setSessionCookie(Request $request) { $sessionData = $request->session()->all(); // Problematic: No domain specified return response('Session set')->cookie( 'app_session', encrypt($sessionData), 60, // minutes '/', // path null // domain - problematic! ); } // Another example with potential subdomain issues public function setPreferences(Request $request) { $preferences = $request->input('preferences'); // Problematic: Empty domain may cause subdomain issues Cookie::queue( 'user_prefs', json_encode($preferences), 60 * 24, // 1 day '/', '' // Empty domain ); } // config/session.php (problematic configuration) return [ 'domain' => env('SESSION_DOMAIN', null), // May be null 'cookie' => env('SESSION_COOKIE', 'laravel_session'), ];
// Secure: Properly configured cookie domains public function setSessionCookie(Request $request) { $sessionData = $request->session()->all(); // Secure: Explicit domain configuration $domain = $this->getCookieDomain(); return response('Session set')->cookie( 'app_session', encrypt($sessionData), 60, // minutes '/', // path $domain, // properly set domain true, // secure true, // httpOnly false, 'Strict' // sameSite ); } // Helper method for domain determination private function getCookieDomain() { $domain = config('session.domain'); if (empty($domain)) { // Fallback to current domain for single-domain apps $domain = request()->getHost(); // For multi-subdomain apps, use base domain if (config('app.multi_subdomain')) { $domain = '.' . $this->getBaseDomain($domain); } } return $domain; } private function getBaseDomain($host) { // Extract base domain (e.g., 'example.com' from 'api.example.com') $parts = explode('.', $host); if (count($parts) >= 2) { return implode('.', array_slice($parts, -2)); } return $host; } // Environment-specific domain configuration public function setPreferencesSecure(Request $request) { $preferences = $request->input('preferences'); // Validate preferences $validator = Validator::make($preferences, [ 'theme' => 'in:light,dark,auto', 'language' => 'in:en,es,fr,de', 'timezone' => 'timezone' ]); if ($validator->fails()) { return response()->json(['errors' => $validator->errors()], 400); } $domain = config('session.domain'); // Secure: Proper domain configuration Cookie::queue( 'user_prefs', json_encode($preferences), 60 * 24, // 1 day '/', $domain, // Explicitly configured domain true, // secure true, // httpOnly false, 'Strict' ); return response()->json(['status' => 'preferences_saved']); } // config/session.php (secure configuration) return [ 'driver' => env('SESSION_DRIVER', 'file'), 'lifetime' => env('SESSION_LIFETIME', 120), 'expire_on_close' => false, 'encrypt' => false, 'files' => storage_path('framework/sessions'), 'connection' => env('SESSION_CONNECTION', null), 'table' => 'sessions', 'store' => env('SESSION_STORE', null), 'lottery' => [2, 100], 'cookie' => env('SESSION_COOKIE', 'laravel_session'), 'path' => '/', 'domain' => env('SESSION_DOMAIN', '.example.com'), // Explicit domain 'secure' => env('SESSION_SECURE_COOKIE', true), 'http_only' => true, 'same_site' => 'strict', ]; // Service for cookie domain management class CookieDomainService { public function getDomainForEnvironment() { $env = config('app.env'); switch ($env) { case 'production': return '.example.com'; case 'staging': return '.staging.example.com'; case 'local': case 'testing': return null; // Allow localhost default: return config('session.domain'); } } public function isValidDomain($domain) { // Validate domain format if (empty($domain)) { return true; // null is valid for localhost } // Check if domain is properly formatted return filter_var('http://' . ltrim($domain, '.'), FILTER_VALIDATE_URL) !== false; } public function getSubdomainPolicy() { return [ 'api' => ['allow' => true, 'secure_only' => true], 'admin' => ['allow' => true, 'secure_only' => true], 'cdn' => ['allow' => false, 'secure_only' => false], ]; } }

💡 Why This Fix Works

See fix suggestions for detailed explanation.

Why it happens

Laravel applications set cookies with null or empty domain parameter, relying on default browser behavior that varies across implementations and may not match security requirements. When domain is null in response()->cookie('name', $value, 60, '/', null), browsers default to exact host matching without subdomain sharing, which seems secure but creates issues in multi-subdomain architectures. The Cookie::queue() method similarly accepts null domain: Cookie::queue('pref', $data, 60, '/', null) resulting in cookies bound to specific subdomain. This configuration appears in config/session.php as 'domain' => env('SESSION_DOMAIN', null) using environment variable that may be unset, defaulting to null. The problem manifests when applications expect cookie sharing across subdomains: authentication on www.example.com not recognized on api.example.com, shopping cart on shop.example.com lost when navigating to checkout.example.com, and session established on example.com inaccessible from www.example.com or vice versa depending on which domain user accessed first. Browser interpretation differences compound issues: some browsers treat null domain as current host exactly, others apply subdomain rules inconsistently, and third-party cookie policies affect null domain behavior differently than explicit domains. The opposite problem occurs when null domain inadvertently shares cookies too broadly: in shared hosting environments, cookies might leak to unintended domains, localhost development cookies potentially accessible to malicious local sites, and IP-based access (http://192.168.1.100) creates cookies without clear domain scope. Security implications include session fixation attacks when cookie domain scope is unclear, authentication bypass through subdomain manipulation when domain policy is ambiguous, and CSRF vulnerabilities when cookies sent to unintended origins. Debugging challenges arise because null domain behavior isn't visible in browser developer tools (shows as empty or the exact host), cookie sharing issues appear intermittently across different browsers, and reproduction requires testing with actual domain/subdomain infrastructure not just localhost.

Root causes

Using Null or Empty Domain in Cookie Configuration

Laravel applications set cookies with null or empty domain parameter, relying on default browser behavior that varies across implementations and may not match security requirements. When domain is null in response()->cookie('name', $value, 60, '/', null), browsers default to exact host matching without subdomain sharing, which seems secure but creates issues in multi-subdomain architectures. The Cookie::queue() method similarly accepts null domain: Cookie::queue('pref', $data, 60, '/', null) resulting in cookies bound to specific subdomain. This configuration appears in config/session.php as 'domain' => env('SESSION_DOMAIN', null) using environment variable that may be unset, defaulting to null. The problem manifests when applications expect cookie sharing across subdomains: authentication on www.example.com not recognized on api.example.com, shopping cart on shop.example.com lost when navigating to checkout.example.com, and session established on example.com inaccessible from www.example.com or vice versa depending on which domain user accessed first. Browser interpretation differences compound issues: some browsers treat null domain as current host exactly, others apply subdomain rules inconsistently, and third-party cookie policies affect null domain behavior differently than explicit domains. The opposite problem occurs when null domain inadvertently shares cookies too broadly: in shared hosting environments, cookies might leak to unintended domains, localhost development cookies potentially accessible to malicious local sites, and IP-based access (http://192.168.1.100) creates cookies without clear domain scope. Security implications include session fixation attacks when cookie domain scope is unclear, authentication bypass through subdomain manipulation when domain policy is ambiguous, and CSRF vulnerabilities when cookies sent to unintended origins. Debugging challenges arise because null domain behavior isn't visible in browser developer tools (shows as empty or the exact host), cookie sharing issues appear intermittently across different browsers, and reproduction requires testing with actual domain/subdomain infrastructure not just localhost.

Missing Domain Specification in Multi-Subdomain Applications

Applications serving content across multiple subdomains (www, api, admin, cdn) fail to configure cookie domain appropriately for sharing authentication and session data. Common architecture patterns requiring domain configuration include microservices: api.example.com, admin.example.com, dashboard.example.com each needing shared authentication, content delivery: main application on www.example.com, static assets on cdn.example.com, administrative interfaces: admin.example.com requiring elevated privileges but shared sessions with www.example.com, and regional subdomains: us.example.com, eu.example.com, asia.example.com sharing user preferences. Without explicit domain configuration, cookies created on one subdomain remain isolated: user logs into www.example.com but API requests from api.example.com lack authentication cookie, single sign-on across subdomains fails because session cookie not shared, and cross-subdomain AJAX requests fail authentication despite valid session. Developers implement workarounds rather than proper domain configuration: duplicating authentication across subdomains creating separate sessions, passing authentication tokens in URLs or headers instead of cookies, or using JWT stored in localStorage sacrificing HttpOnly protection. These workarounds create security issues: multiple independent sessions to synchronize across subdomains, authentication credentials exposed in URLs appearing in logs/referrers, and tokens accessible to JavaScript enabling XSS attacks. The root cause is not setting cookie domain to '.example.com' (note leading dot) which enables sharing across all subdomains. Legacy applications migrating to microservices particularly affected: monolithic application on www.example.com splitting into subdomain-based services, existing cookie infrastructure not updated for new architecture, and gradual migration creates mixed cookie scopes. Enterprise applications with complex subdomain structures face challenges: many subdomains requiring different cookie policies (cdn shouldn't receive authentication cookies), dynamic subdomains (user1.example.com, user2.example.com in SaaS) needing per-tenant cookies, and regulatory requirements isolating cookies between regions (eu.example.com vs us.example.com). Testing gaps contribute to problem: local development on localhost doesn't require subdomain cookie configuration, staging environments using single domain don't expose subdomain issues, and production subdomain problems only discovered after deployment.

Inadequate Understanding of Cookie Domain Behavior

Development teams lack comprehensive understanding of cookie domain attribute behavior including leading dot syntax, subdomain matching rules, and browser security policies. Key misunderstandings include leading dot meaning: '.example.com' (with dot) shares cookies across all subdomains, 'example.com' (without dot) in cookie domain attribute behaves differently across browsers (RFC specification says it should match example.com exactly, but browsers historically added implicit leading dot), and developers unsure which syntax to use. Subdomain matching confusion: cookies with domain='.example.com' are sent to www.example.com, api.example.com, any.sub.example.com, and even example.com itself, but cookies with domain='sub.example.com' only sent to sub.example.com and its subdomains (nested.sub.example.com), not to parent example.com or sibling domains. Public suffix list (PSL) complexity: browsers use PSL to prevent cookies set on '.co.uk' (public suffix) from being shared across all .co.uk sites, so domain='.example.co.uk' works but domain='.co.uk' is blocked, requiring developers understand public suffixes for internationalized domains (.co.jp, .com.au, etc.). Port and protocol are not part of domain matching: cookies set on http://example.com:8080 share with http://example.com:3000 and https://example.com if domain configured correctly, but developers expect port isolation. Null/undefined domain behavior varies: omitting domain parameter behaves differently in different Laravel versions, browser implementation differences in handling null domain, and frameworks applying different defaults when domain is null. Security policy interactions: SameSite cookie attribute interacts with domain attribute affecting cross-subdomain requests, Secure flag behavior differs for domain vs subdomain cookies, and third-party cookie blocking affects subdomain cookies in some browsers. Developers also misunderstand domain validation: browsers validate domain matches current host (can't set cookie for different domain), can only set cookies for current domain and its parents up to public suffix, and attempted domain spoofing fails silently rather than throwing errors. Local development creates false understanding: localhost, 127.0.0.1, and .local domains have special handling different from production domains, making development behavior unreliable guide for production. Documentation gaps compound confusion: Laravel documentation shows examples with null domain without explaining implications, cookie() method parameter order not intuitive (domain comes before secure flags), and environment variable patterns (SESSION_DOMAIN) not well explained.

Copy-Pasting Cookie Code Without Domain Considerations

Developers copy cookie-setting code from Stack Overflow, tutorials, existing projects, or documentation without considering domain requirements specific to their application architecture. Code reuse patterns introduce issues: authentication code from single-domain tutorial applied to multi-subdomain architecture, cookie examples from localhost development (where domain is irrelevant) deployed to production subdomains, and boilerplate Laravel packages using null domain inappropriately. Stack Overflow answers prioritize working code over secure/correct configuration: accepted answers showing response()->cookie('name', $value, 60) omitting domain parameter entirely, code snippets demonstrating functionality with Cookie::queue('name', $value, 60, '/', '') using empty string domain, and quick fixes suggesting null domain to "just make it work" without explaining consequences. Documentation examples balance brevity and completeness: official Laravel docs show cookie() with all parameters but use null domain as placeholder example, framework tutorials focus on basic usage omitting domain discussion, and quickstart guides skip environment-specific configuration. Migration from other frameworks introduces inappropriate patterns: converting from framework with different cookie domain defaults, migrating from flat architecture to microservices keeping original cookie code, and updating legacy code with new cookie requirements but copying old domain settings. Team dynamics perpetuate poor patterns: junior developers copy senior code without understanding domain implications, code review approves cookie code if HttpOnly/Secure flags present without checking domain configuration, and pair programming sessions focus on functionality rather than cookie domain correctness. IDE features contribute to problem: auto-completion suggests previous cookie() calls including their null domains, code snippets and live templates have placeholder null values developers forget to customize, and refactoring tools maintain existing domain values when updating cookie code. The fix requires: explicit domain configuration in all cookie-setting code with comments explaining why specific domain chosen, code review checklists including domain configuration verification, secure coding templates with environment-appropriate domain defaults and comments explaining customization, and developer education on cookie domain implications for application architecture.

Missing Environment-Specific Domain Configuration

Applications use same cookie domain configuration across development, staging, and production environments despite different domain requirements, or lack environment-specific configuration entirely. Development environments on localhost: using null domain works locally but doesn't match production subdomain requirements, developers don't test cookie behavior with actual domain/subdomain structure, and local Docker container networks use different domain schemes than production. Staging environment mismatches: staging.example.com structure doesn't mirror production www.example.com/api.example.com subdomain layout, testing on single staging domain doesn't expose multi-subdomain cookie issues, and staging environment using different domain syntax (.staging.example.com vs individual staging-api.example.com, staging-www.example.com subdomains). Production deployment uses hardcoded domain: applications deployed to different domains (example.com, example.net, partner-company.com) all using same hardcoded '.example.com' domain configuration, white-label applications serving multiple customer domains with single cookie domain configuration, and multi-region deployments (example.com, example.co.uk, example.jp) requiring region-specific cookie domains. Environment variables not properly configured: SESSION_DOMAIN undefined in environment causing null fallback, .env.example contains placeholder .example.com not replaced during deployment, and environment-specific .env files not created for staging/production. Configuration management issues: infrastructure-as-code templates (Terraform, CloudFormation) have incorrect domain parameters, container orchestration (Kubernetes ConfigMaps) missing SESSION_DOMAIN environment variable, and deployment scripts don't validate cookie domain configuration. The problem manifests as environment-specific bugs: cookies work in development but fail in production, staging tests pass but production deployment breaks cookie functionality, and different environments have inconsistent authentication behavior. Testing gaps allow issues to persist: unit tests mock cookies without testing domain attributes, integration tests on single domain don't test subdomain behavior, and end-to-end tests don't verify cross-subdomain functionality. Solutions require: environment-specific configuration management with explicit domain values for each environment, validation scripts checking SESSION_DOMAIN is appropriately set for environment, infrastructure automation ensuring cookie domain matches deployment domain architecture, and comprehensive testing including subdomain cookie verification.

Fixes

1

Explicitly Set Cookie Domain Based on Application Requirements

Configure cookie domain explicitly matching application architecture rather than relying on null/default values, determining appropriate domain scope based on subdomain sharing requirements. For single-domain applications: set domain to exact domain without subdomains: response()->cookie('name', $value, 60, '/', 'example.com') for www-only access, or use null domain if truly single-hostname application: response()->cookie('name', $value, 60, '/', null) for localhost or specific host. For multi-subdomain applications: use leading dot syntax enabling subdomain sharing: response()->cookie('name', $value, 60, '/', '.example.com') allowing www, api, admin, cdn subdomains to share cookies, store in configuration: 'domain' => '.example.com' in config/session.php, and validate domain format includes leading dot for subdomain sharing. Determine subdomain scope: identify which subdomains need cookie access (www, api, admin sharing authentication cookies), exclude subdomains that shouldn't receive cookies (cdn doesn't need authentication cookies, static.example.com shouldn't receive session cookies), and document decision rationale: why specific domain scope chosen. Implement in cookie creation: use configuration value in all cookie calls: Cookie::queue('auth', $token, 60, '/', config('session.domain'), true, true, false, 'Strict'), create helper function: function appCookie($name, $value, $minutes) { return cookie($name, $value, $minutes, '/', config('session.domain'), true, true, false, 'Strict'); }, and ensure consistency across application: all authentication cookies use same domain policy. Handle edge cases: internationalized domains (IDN): ensure domain configuration handles Unicode domains correctly, wildcard certificates: match domain configuration to SSL certificate coverage, and IP addresses: local development or IP-based access requiring null domain. Validate domain configuration: check domain matches deployment environment: cannot set cookies for different domain than serving host, verify leading dot syntax correct: '.example.com' not '..example.com' or 'example.com.' (trailing dot), and test subdomain access: cookies actually shared across intended subdomains. Document configuration: comment in config/session.php explaining domain choice, document in deployment guides which domain to configure for each environment, and maintain architecture diagrams showing subdomain structure and cookie sharing requirements. Review regularly: audit domain configuration when adding new subdomains, update cookie domain policy when architecture changes (new microservices, subdomain reorganization), and verify continued appropriateness of domain scope for security and functionality requirements.

2

Use Environment Variables for Domain Configuration

Externalize cookie domain configuration through environment variables enabling different domain settings per environment without code changes. Define environment variable in config/session.php: 'domain' => env('SESSION_DOMAIN', null) using SESSION_DOMAIN from environment, provide sensible default: env('SESSION_DOMAIN', null) for local development or env('SESSION_DOMAIN', '.example.com') for production-like default, and document in .env.example: SESSION_DOMAIN=.example.com as template showing expected format. Configure per environment: local .env: SESSION_DOMAIN=null (or omit for null default) allowing localhost development, staging .env.staging: SESSION_DOMAIN=.staging.example.com for staging subdomain isolation, production .env.production: SESSION_DOMAIN=.example.com for production subdomain sharing. Handle multiple deployment targets: use different SESSION_DOMAIN per customer in white-label deployments, configure region-specific domains: us.example.com vs eu.example.com vs asia.example.com, and support multiple brands: SESSION_DOMAIN=.brand1.com vs SESSION_DOMAIN=.brand2.com. Validate environment variable: create artisan command checking configuration: php artisan config:check validating SESSION_DOMAIN format, implement application bootstrap validation: if (!$this->isValidDomain(config('session.domain'))) { throw new ConfigurationException(); }, and fail fast on invalid configuration: prevent application start if domain misconfigured. Use in cookie creation: retrieve from config, not environment directly: cookie($name, $value, $minutes, '/', config('session.domain'), ...) maintaining configuration abstraction, never hardcode domains: avoid Cookie::queue($name, $value, 60, '/', '.example.com') putting domain in code, and centralize domain logic: helper functions or service classes retrieving domain from config. Infrastructure-as-code integration: Terraform variables: variable "session_domain" { default = ".example.com" } passing to application configuration, Kubernetes ConfigMaps: SESSION_DOMAIN: ".example.com" in ConfigMap, CloudFormation parameters: SessionDomain parameter passed to environment, and Docker Compose: SESSION_DOMAIN=.example.com in environment section. Testing with environment variables: override in tests: putenv('SESSION_DOMAIN=.test.example.com'); for test-specific domain, use testing configuration: config/session.testing.php with test-appropriate domain, and verify environment-specific behavior: tests for local/staging/production domain variations. Security considerations: protect environment files: .env should not be committed to version control, store sensitive environment config: use secrets management (AWS Secrets Manager, HashiCorp Vault) for production, and audit environment changes: track who modified SESSION_DOMAIN and when. Documentation: README includes environment variable requirements listing SESSION_DOMAIN, deployment guides specify correct values for each environment, and .env.example contains all required variables with example values and comments explaining format.

3

Implement Proper Subdomain Cookie Policies

Define and enforce cookie policies determining which subdomains should share cookies and which should maintain isolation based on security and functionality requirements. Categorize subdomains by purpose: public-facing (www, blog, shop): share authentication and user preferences, API/services (api, services, webhooks): may share authentication but not UI preferences, administrative (admin, dashboard, management): separate authentication for privilege separation, static content (cdn, static, assets): no cookies needed, exclude from cookie domain, and development/testing (staging, dev, qa): environment-specific cookie policies. Create policy documentation: which cookies shared across subdomains (session, authentication, user preferences), which cookies subdomain-specific (admin session separate from www session), and security rationale for each policy (why admin cookies isolated, why cdn excluded). Implement policy in code: authentication cookies use shared domain for SSO: Cookie::queue('session', $session, 60, '/', '.example.com') for www/api/shop, admin cookies use admin-specific domain: Cookie::queue('admin_session', $token, 15, '/', 'admin.example.com') isolating admin, and preference cookies may use broader domain: Cookie::queue('theme', 'dark', 43200, '/', '.example.com') for user experience consistency. Use different cookie names per subdomain when isolation needed: www_session for www subdomain, api_session for api subdomain, admin_session for admin subdomain preventing cross-subdomain session use even if domains overlap. Implement middleware enforcing policy: validate cookies only used on appropriate subdomains, log violations when cookies sent to wrong subdomains, and reject authentication from unexpected subdomains (admin cookie shouldn't work on www). Configure CORS policies matching cookie policies: CORS allowed origins should align with shared cookie domains, credentials: true in CORS only for cookie-sharing subdomains, and verify preflight requests handle cross-subdomain cookies correctly. Security considerations: privilege separation: administrative subdomains use separate cookies with stricter policies, session isolation: user sessions on different subdomains kept separate when appropriate, and token differentiation: API tokens different from web session tokens. Testing subdomain policies: verify cookies shared where expected: authentication works across www/api/shop, confirm isolation where required: admin cookies don't work on www, and test edge cases: nested subdomains (api.v2.example.com), international domains, IP-based access. Monitor and audit: log cookie usage by subdomain identifying policy violations, alert on anomalies (cookies on unexpected subdomains), and review policies quarterly ensuring continued appropriateness. Documentation: maintain subdomain architecture diagram showing cookie sharing, document policy rationale in configuration files with comments, and provide examples of correct cookie creation for each subdomain type.

4

Configure Domain Restrictions for Sensitive Cookies

Apply stricter domain restrictions to sensitive cookies (authentication tokens, session IDs, admin privileges) compared to general cookies (preferences, UI state) for defense-in-depth security. Classify cookie sensitivity: critical (session tokens, authentication, MFA state, admin privileges): strictest domain restrictions, sensitive (user preferences containing PII, shopping cart with items/prices): moderate domain restrictions, low sensitivity (UI theme, language preference, dismissed notifications): permissive domain restrictions. Configure critical cookie domains: authentication cookies with exact domain: Cookie::queue('auth_token', $token, 120, '/', request()->getHost(), true, true, false, 'Strict') binding to exact hostname, admin cookies to admin subdomain only: response()->cookie('admin_session', $session, 30, '/', 'admin.example.com', true, true, false, 'Strict') preventing use on other subdomains, and MFA state cookies non-shared: separate MFA cookies per subdomain requiring re-verification. Implement domain-based security tiers: Tier 1 (highest security): admin, payment, sensitive operations with exact hostname cookies, Tier 2 (standard security): regular user sessions with subdomain sharing ('.example.com'), Tier 3 (convenience): UI preferences with broad sharing. Create security policy service: class CookieSecurityPolicy { public function getDomainForCookieType($type) { switch($type) { case 'admin': return 'admin.example.com'; case 'auth': return '.example.com'; case 'preference': return '.example.com'; default: return config('session.domain'); } } } centralizing domain policy by cookie type. Separate authentication domains per privilege level: regular users: '.example.com' shared across public subdomains, privileged users: separate cookie when accessing admin areas, and super admin: strictest domain restriction to specific admin host. Implement progressive restriction: initial login uses broader domain, sensitive operations create operation-specific cookies with stricter domains, and step-up authentication issues new cookies with limited scope. Handle domain changes securely: when user escalates privileges, create new cookie with restricted domain rather than reusing existing, when downgrading, invalidate higher-privilege cookies, and logout invalidates all cookies across all domains. Testing domain restrictions: verify sensitive cookies not sent to wrong subdomains, test privilege escalation creates appropriate new cookies, and confirm domain restrictions prevent cross-subdomain replay attacks. Monitor restricted cookies: log when restricted cookies attempted on wrong domains, alert on potential cookie hijacking attempts across domains, and audit privileged cookie usage across subdomain boundaries. Document restrictions: maintain matrix showing cookie types and their domain policies, explain security rationale for each restriction in documentation, and provide code examples showing correct domain configuration for each sensitivity level.

5

Test Cookie Behavior Across Different Subdomains

Implement comprehensive testing verifying cookie behavior across subdomain boundaries, ensuring authentication sharing works where intended and isolation works where required. Setup test environment: configure local development with subdomain simulation: /etc/hosts entries mapping subdomains to localhost (127.0.0.1 www.local.test, 127.0.0.1 api.local.test), use local DNS server (dnsmasq) for wildcard subdomain resolution, or employ testing services providing real subdomain URLs for local development. Manual testing procedures: test authentication flow: login on www subdomain, verify session on api subdomain, confirm logout from any subdomain invalidates all cookies, test cookie isolation: admin cookies on admin subdomain not accessible from www, verify CDN subdomain doesn't receive authentication cookies, and preference cookies shared appropriately. Automated browser testing: Laravel Dusk tests with subdomain navigation: $browser->visit('https://www.example.test/login')->loginAs($user)->visit('https://api.example.test/user')->assertAuthenticated(), assert cookies present on correct domains: $browser->assertCookieValue('session', $expected), and verify cross-subdomain AJAX requests include cookies. Integration tests for cookie domain: test session sharing: $this->actingAs($user)->get('https://www.example.test/profile')->assertOk()->get('https://api.example.test/user')->assertOk(), verify cookie domain attribute: $response->assertCookie('session')->assertCookieDomain('.example.test'), and test subdomain isolation: cookies from admin.example.test not sent to www.example.test. Unit tests for domain configuration: test domain resolution: assertEquals('.example.com', $cookieService->getDomainForEnvironment('production')), validate domain format: assertTrue($validator->isValidDomain('.example.com')), and test leading dot handling: assertStringStartsWith('.', $domain). Test across browsers: Chrome, Firefox, Safari handle null domain differently, verify subdomain cookie sharing works consistently, and test third-party cookie policies impact on subdomain cookies. Security testing: attempt cross-subdomain cookie injection: verify cannot set cookies for other subdomains, test subdomain enumeration: ensure cookie policy doesn't leak subdomain information, and verify CSRF protection works with subdomain cookies. Performance testing: measure cookie size with domain attribute included, test cookie transmission overhead across subdomain requests, and verify cookie cleanup across all subdomains on logout. Continuous integration: include subdomain cookie tests in CI pipeline requiring network configuration, use containerized testing with network bridges simulating subdomains, and fail builds on cookie policy violations. Production monitoring: implement logging of cookie behavior in production, track cookies sent to unexpected subdomains, alert on domain configuration mismatches, and collect metrics on cross-subdomain authentication success rates. Document test cases: maintain test matrix covering all subdomain combinations, document expected cookie behavior for each scenario, and provide reproducible test procedures for manual verification.

6

Document Cookie Domain Policies for the Development Team

Create comprehensive documentation explaining cookie domain policies, configuration requirements, and implementation patterns ensuring team understanding and consistent application. Create policy document: define organizational cookie domain standards, explain when to use null domain vs explicit domain vs subdomain wildcard, document security rationale behind domain policies, and provide decision tree: if multi-subdomain, use '.domain.com'; if single subdomain, use 'sub.domain.com'; if localhost, use null. Architecture documentation: maintain subdomain map showing which services on which subdomains, document cookie sharing requirements between subdomains, explain why certain subdomains excluded from cookie domain (CDN, static assets), and diagram authentication flow across subdomains. Configuration guide: step-by-step instructions for setting SESSION_DOMAIN, environment-specific configuration examples for local/staging/production, troubleshooting guide for common domain configuration issues (cookies not shared, cookies too broadly shared), and validation checklist verifying domain configuration correctness. Code examples and patterns: reference implementations showing correct domain configuration: function createAuthCookie($token) { return cookie('auth', $token, 120, '/', config('session.domain'), true, true, false, 'Strict'); }, anti-patterns to avoid with explanations why they're problematic, and helper functions/classes for cookie domain management. Developer onboarding: include cookie domain policies in onboarding documentation, require review of subdomain architecture during new developer orientation, and provide hands-on exercises testing cookies across subdomains. Code review guidelines: checklist item for domain configuration in all cookie-related code, reviewers verify appropriate domain for cookie sensitivity level, and require explanation in PR description when changing cookie domain configuration. Security training: explain attack vectors related to incorrect cookie domain (session hijacking, CSRF), demonstrate cookie domain behavior in different scenarios, and provide security testing procedures for cookie domain verification. Runbook documentation: operational procedures for changing cookie domain in production, rollback procedures if domain change causes issues, and monitoring alerts related to cookie domain misconfigurations. Maintain change log: track changes to cookie domain policies with rationale, document incidents related to cookie domain issues and resolutions, and review documentation quarterly ensuring accuracy and completeness. Make documentation accessible: internal wiki or knowledge base with search functionality, link from code comments to detailed documentation, and integrate into development environment (README, IDE bookmarks). Provide tools: domain configuration validation script: php artisan cookie:validate-domain, helper commands showing current domain configuration: php artisan config:show session.domain, and development environment setup script configuring correct domains automatically. Encourage feedback: provide mechanism for developers to suggest documentation improvements, regularly solicit feedback on documentation clarity and usefulness, and update documentation based on recurring questions or confusion patterns.

Detect This Vulnerability in Your Code

Sourcery automatically identifies laravel cookie null domain configuration and many other security issues in your codebase.