✅ Works: Accessing via http://localhost:8080 - CSRF cookies created correctly
❌ Fails: Accessing via http://192.168.1.100:8080 - CSRF cookies NOT created
The WTF_CSRF_SSL_STRICT=true setting (default) blocks cookie creation for HTTP connections to non-localhost addresses. This is a security feature that prevents CSRF tokens from being sent over insecure connections.
Linux/Mac:
bash scripts/fix_csrf_ip_access.shWindows:
scripts\fix_csrf_ip_access.batThe script will:
- Update your
.envfile with correct settings - Restart the application
- Verify the configuration
Edit your .env file and add/update:
WTF_CSRF_SSL_STRICT=false
SESSION_COOKIE_SECURE=false
CSRF_COOKIE_SECURE=falseThen restart:
docker-compose restart app| Setting | Value | Purpose |
|---|---|---|
WTF_CSRF_SSL_STRICT |
false |
Allows CSRF tokens over HTTP (needed for IP access) |
SESSION_COOKIE_SECURE |
false |
Allows session cookies over HTTP |
CSRF_COOKIE_SECURE |
false |
Allows CSRF cookies over HTTP |
docker-compose exec app env | grep -E "(WTF_CSRF|SESSION_COOKIE|CSRF_COOKIE)"Expected output:
WTF_CSRF_SSL_STRICT=false
SESSION_COOKIE_SECURE=false
CSRF_COOKIE_SECURE=false
- Open your browser
- Navigate to
http://YOUR_IP:8080 - Open DevTools (F12)
- Go to Application → Cookies
- Verify these cookies exist:
session- Your session cookieXSRF-TOKEN- The CSRF token
# Via localhost (should work)
curl -v http://localhost:8080/auth/csrf-token
# Via IP (should now also work)
curl -v http://192.168.1.100:8080/auth/csrf-tokenLook for Set-Cookie headers in both responses.
These settings are suitable for:
- ✅ Development environments
- ✅ Testing on local networks
- ✅ Private/trusted networks (VPN, home network)
NOT suitable for:
- ❌ Public internet access without HTTPS
- ❌ Production environments with sensitive data
- ❌ Untrusted networks
For production deployments, always use HTTPS and set:
WTF_CSRF_SSL_STRICT=true
SESSION_COOKIE_SECURE=true
CSRF_COOKIE_SECURE=trueAdd to your hosts file instead of using IP:
Linux/Mac (/etc/hosts):
192.168.1.100 timetracker.local
Windows (C:\Windows\System32\drivers\etc\hosts):
192.168.1.100 timetracker.local
Then access via: http://timetracker.local:8080
For production-like testing with HTTPS:
- Generate self-signed certificate:
openssl req -x509 -newkey rsa:4096 -nodes \
-keyout key.pem -out cert.pem -days 365 \
-subj "/CN=192.168.1.100"- Update docker-compose to use HTTPS
- Set all security flags to
true
-
Verify settings are loaded:
docker-compose exec app env | grep WTF_CSRF_SSL_STRICT
-
Check logs:
docker-compose logs app | grep -i csrf -
Try a fresh restart:
docker-compose down docker-compose up -d
-
Clear browser cookies:
- DevTools → Application → Cookies → Delete all for this site
-
Test in incognito/private window:
- Rules out browser extension issues
- Chrome/Edge: Usually most permissive
- Firefox: Stricter cookie policies
- Safari: Strictest, especially with tracking prevention
Try disabling enhanced tracking protection or privacy features temporarily for testing.
- Detailed Guide: docs/CSRF_IP_ACCESS_GUIDE.md
- General CSRF Troubleshooting: CSRF_TROUBLESHOOTING.md
- CSRF Configuration: docs/CSRF_CONFIGURATION.md
The Fix: Set WTF_CSRF_SSL_STRICT=false for HTTP access via IP addresses.
Why It Works: This allows Flask-WTF to create and validate CSRF cookies over HTTP connections to non-localhost addresses.
When to Use: Development, testing, and trusted private networks only. Always use HTTPS with strict settings in production.
Quick Command Reference:
# Apply fix (automated)
bash scripts/fix_csrf_ip_access.sh
# Verify configuration
docker-compose exec app env | grep -E "WTF_CSRF|SESSION_COOKIE|CSRF_COOKIE"
# Restart application
docker-compose restart app
# Check logs
docker-compose logs app | tail -50Last Updated: October 2024
Applies To: TimeTracker v1.0+