fix: configure sessions to be strictly same-site

This commit is contained in:
Gregor Kleen 2020-03-16 09:05:42 +01:00
parent 0a2a578547
commit a7e64bce7b
4 changed files with 24 additions and 7 deletions

View File

@ -5,7 +5,7 @@
static-dir: "_env:STATIC_DIR:static" static-dir: "_env:STATIC_DIR:static"
well-known-dir: "_env:WELL_KNOWN_DIR:well-known" well-known-dir: "_env:WELL_KNOWN_DIR:well-known"
well-known-link-file: "html_code.html" well-known-link-file: html_code.html
webpack-manifest: "_env:WEBPACK_MANIFEST:config/webpack.yml" webpack-manifest: "_env:WEBPACK_MANIFEST:config/webpack.yml"
host: "_env:HOST:*4" # any IPv4 host host: "_env:HOST:*4" # any IPv4 host
@ -70,7 +70,7 @@ allow-deprecated: "_env:ALLOW_DEPRECATED:false"
server-session-acid-fallback: "_env:SERVER_SESSION_ACID_FALLBACK:false" server-session-acid-fallback: "_env:SERVER_SESSION_ACID_FALLBACK:false"
auth-pw-hash: auth-pw-hash:
algorithm: "pbkdf2" algorithm: pbkdf2
strength: 14 strength: 14
# Optional values with the following production defaults. # Optional values with the following production defaults.
@ -111,7 +111,7 @@ smtp:
port: "_env:SMTPPORT:25" port: "_env:SMTPPORT:25"
ssl: "_env:SMTPSSL:starttls" ssl: "_env:SMTPSSL:starttls"
auth: auth:
type: "login" type: login
user: "_env:SMTPUSER:" user: "_env:SMTPUSER:"
pass: "_env:SMTPPASS:" pass: "_env:SMTPPASS:"
pool: pool:
@ -137,7 +137,7 @@ session-memcached:
expiration: "_env:SESSION_MEMCACHED_EXPIRATION:28807" expiration: "_env:SESSION_MEMCACHED_EXPIRATION:28807"
server-sessions: server-sessions:
cookie-name: "_SESSION" cookie-name: _SESSION
idle-timeout: 28807 idle-timeout: 28807
absolute-timeout: 604801 absolute-timeout: 604801
timeout-resolution: 601 timeout-resolution: 601
@ -146,6 +146,7 @@ server-sessions:
secure-cookies: "_env:SERVER_SESSION_COOKIES_SECURE:true" secure-cookies: "_env:SERVER_SESSION_COOKIES_SECURE:true"
session-token-expiration: 28807 session-token-expiration: 28807
session-token-encoding: HS256 session-token-encoding: HS256
session-samesite: strict
user-defaults: user-defaults:
max-favourites: 12 max-favourites: 12

View File

@ -4,8 +4,8 @@ database:
log-settings: log-settings:
detailed: true detailed: true
all: true all: true
minimum-level: "debug" minimum-level: debug
destination: "test.log" destination: test.log
auth-dummy-login: true auth-dummy-login: true
server-session-acid-fallback: true server-session-acid-fallback: true

View File

@ -1469,7 +1469,7 @@ instance Yesod UniWorX where
Nothing -> getApprootText guessApproot app req Nothing -> getApprootText guessApproot app req
Just root -> root Just root -> root
makeSessionBackend app@UniWorX{ appSettings' = AppSettings{..}, ..} = case appSessionStore of makeSessionBackend app@UniWorX{ appSettings' = AppSettings{..}, ..} = sameSite $ case appSessionStore of
SessionStorageMemcachedSql sqlStore SessionStorageMemcachedSql sqlStore
-> mkBackend =<< stateSettings <$> ServerSession.createState sqlStore -> mkBackend =<< stateSettings <$> ServerSession.createState sqlStore
SessionStorageAcid acidStore SessionStorageAcid acidStore
@ -1494,6 +1494,13 @@ instance Yesod UniWorX where
mkBackend = JwtSession.backend cfg (JwtSession.siteApproot app) mkBackend = JwtSession.backend cfg (JwtSession.siteApproot app)
stateSettings :: forall sto. ServerSession.State sto -> ServerSession.State sto stateSettings :: forall sto. ServerSession.State sto -> ServerSession.State sto
stateSettings = applyServerSessionSettings appServerSessionConfig stateSettings = applyServerSessionSettings appServerSessionConfig
sameSite
| Just SameSiteStrict <- appSessionSameSite
= strictSameSiteSessions
| Just SameSiteLax <- appSessionSameSite
= laxSameSiteSessions
| otherwise
= id
maximumContentLength app _ = app ^. _appMaximumContentLength maximumContentLength app _ = app ^. _appMaximumContentLength

View File

@ -98,6 +98,7 @@ data AppSettings = AppSettings
, appSessionMemcachedConf :: Maybe MemcachedConf , appSessionMemcachedConf :: Maybe MemcachedConf
, appSessionTokenExpiration :: Maybe NominalDiffTime , appSessionTokenExpiration :: Maybe NominalDiffTime
, appSessionTokenEncoding :: JwtEncoding , appSessionTokenEncoding :: JwtEncoding
, appSessionSameSite :: Maybe SameSite
, appMailFrom :: Address , appMailFrom :: Address
, appMailObjectDomain :: Text , appMailObjectDomain :: Text
@ -158,6 +159,10 @@ data AppSettings = AppSettings
, appRibbon :: Maybe Text , appRibbon :: Maybe Text
} deriving Show } deriving Show
data SameSite = SameSiteStrict | SameSiteLax
deriving stock (Eq, Ord, Read, Show, Enum, Bounded, Generic, Typeable)
deriving anyclass (Universe, Finite)
newtype ServerSessionSettings newtype ServerSessionSettings
= ServerSessionSettings { applyServerSessionSettings :: forall a. ServerSession.State a -> ServerSession.State a } = ServerSessionSettings { applyServerSessionSettings :: forall a. ServerSession.State a -> ServerSession.State a }
@ -272,6 +277,9 @@ data SmtpAuthConf = SmtpAuthConf
, smtpAuthPassword :: HaskellNet.Password , smtpAuthPassword :: HaskellNet.Password
} deriving (Show) } deriving (Show)
nullaryPathPiece ''SameSite $ camelToPathPiece' 2
pathPieceJSON ''SameSite
deriveJSON defaultOptions deriveJSON defaultOptions
{ constructorTagModifier = camelToPathPiece' 2 { constructorTagModifier = camelToPathPiece' 2
, fieldLabelModifier = camelToPathPiece' 2 , fieldLabelModifier = camelToPathPiece' 2
@ -491,6 +499,7 @@ instance FromJSON AppSettings where
appServerSessionConfig <- o .: "server-sessions" appServerSessionConfig <- o .: "server-sessions"
appSessionTokenExpiration <- o .:? "session-token-expiration" appSessionTokenExpiration <- o .:? "session-token-expiration"
appSessionTokenEncoding <- o .: "session-token-encoding" appSessionTokenEncoding <- o .: "session-token-encoding"
appSessionSameSite <- o .:? "session-samesite"
return AppSettings{..} return AppSettings{..}