// Vulnerable: Cookies without Secure flag
public function authenticateUser(Request $request) {
$credentials = $request->only('email', 'password');
if (Auth::attempt($credentials)) {
$token = $request->user()->createToken('auth')->plainTextToken;
// Dangerous: Cookie can be sent over HTTP
return response('Authentication successful')->cookie(
'auth_token',
$token,
60 * 24, // 24 hours
'/',
null,
false, // Secure flag disabled - DANGEROUS!
true // httpOnly
);
}
}
// Another vulnerable pattern
public function storeSessionData(Request $request) {
$sessionData = $request->session()->all();
// Dangerous: Missing secure flag
Cookie::queue(
'app_session',
encrypt(json_encode($sessionData)),
120, // 2 hours
'/',
null,
false // Insecure transmission allowed
);
}
// config/session.php (vulnerable configuration)
return [
'secure' => false, // Dangerous in production
'http_only' => true,
'same_site' => 'lax',
];
// Secure: Proper Secure flag implementation
public function authenticateUser(Request $request) {
$credentials = $request->only('email', 'password');
if (Auth::attempt($credentials)) {
$user = $request->user();
$token = $user->createToken('auth')->plainTextToken;
// Secure: Enforce HTTPS transmission
return response('Authentication successful')->cookie(
'auth_token',
$token,
60 * 24, // 24 hours
'/',
config('session.domain'),
true, // Secure flag - HTTPS only
true, // httpOnly
false,
'Strict' // sameSite
);
}
return response('Invalid credentials', 401);
}
// Environment-aware secure cookie setting
public function storeSessionData(Request $request) {
$sessionData = $request->session()->all();
// Secure: Environment-aware security
$isProduction = app()->environment('production');
$isSecure = $isProduction || config('session.secure', false);
Cookie::queue(
'app_session',
encrypt(json_encode($sessionData)),
120, // 2 hours
'/',
config('session.domain'),
$isSecure, // Secure in production
true, // httpOnly
false,
'Strict' // sameSite
);
return response()->json(['status' => 'session_stored']);
}
// Service for secure cookie management
class SecureCookieService {
public function createSecureCookie($name, $value, $minutes = 60, $options = []) {
$defaultOptions = [
'path' => '/',
'domain' => config('session.domain'),
'secure' => $this->shouldUseSecureFlag(),
'httpOnly' => true,
'sameSite' => 'Strict'
];
$options = array_merge($defaultOptions, $options);
return Cookie::make(
$name,
$value,
$minutes,
$options['path'],
$options['domain'],
$options['secure'],
$options['httpOnly'],
false,
$options['sameSite']
);
}
private function shouldUseSecureFlag() {
// Always use secure flag in production
if (app()->environment('production')) {
return true;
}
// Use secure flag if HTTPS is available
if (request()->isSecure()) {
return true;
}
// Check configuration
return config('session.secure', false);
}
public function validateCookieSecurity($cookieName) {
$cookie = Cookie::get($cookieName);
if (!$cookie) {
return ['valid' => false, 'reason' => 'Cookie not found'];
}
$issues = [];
// Check if served over HTTPS when Secure flag is set
if (!request()->isSecure() && config('session.secure')) {
$issues[] = 'Secure cookie served over HTTP';
}
// Validate in production
if (app()->environment('production') && !config('session.secure')) {
$issues[] = 'Secure flag disabled in production';
}
return [
'valid' => empty($issues),
'issues' => $issues
];
}
}
// Middleware to enforce HTTPS and secure cookies
class EnforceSecureCookiesMiddleware {
public function handle($request, Closure $next) {
// Redirect HTTP to HTTPS in production
if (app()->environment('production') && !$request->isSecure()) {
return redirect()->secure($request->getRequestUri(), 301);
}
$response = $next($request);
// Validate all outgoing cookies
foreach ($response->headers->getCookies() as $cookie) {
$this->validateOutgoingCookie($cookie, $request);
}
return $response;
}
private function validateOutgoingCookie($cookie, $request) {
$name = $cookie->getName();
// Log security issues
if (!$cookie->isSecure() && $request->isSecure()) {
Log::warning('Insecure cookie sent over HTTPS', ['cookie' => $name]);
}
if (app()->environment('production') && !$cookie->isSecure()) {
Log::error('Cookie without Secure flag in production', ['cookie' => $name]);
}
}
}
// 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', null),
'secure' => env('SESSION_SECURE_COOKIE', app()->environment('production')),
'http_only' => true,
'same_site' => 'strict',
];