# Copyright (C) Lightbend Inc. play.modules { enabled += "play.filters.csrf.CSRFModule" enabled += "play.filters.cors.CORSModule" enabled += "play.filters.csp.CSPModule" enabled += "play.filters.headers.SecurityHeadersModule" enabled += "play.filters.hosts.AllowedHostsModule" enabled += "play.filters.gzip.GzipFilterModule" enabled += "play.filters.https.RedirectHttpsModule" } play.filters { # Default list of enabled filters, configured by play.api.http.EnabledFilters enabled += play.filters.csrf.CSRFFilter enabled += play.filters.headers.SecurityHeadersFilter enabled += play.filters.hosts.AllowedHostsFilter # CSRF config csrf { # Token configuration token { # The token name name = "csrfToken" # Whether tokens should be signed or not sign = true } # Cookie configuration cookie { # If non null, the CSRF token will be placed in a cookie with this name name = null # Whether the cookie should be set to secure secure = ${play.http.session.secure} # Whether the cookie should have the HTTP only flag set httpOnly = false # The value of the SameSite attribute of the cookie. Set to null for no SameSite attribute. # Possible values are "lax" and "strict". If misconfigured it's set to null. sameSite = ${play.http.session.sameSite} } # How much of the body should be buffered when looking for the token in the request body body.bufferSize = ${play.http.parser.maxMemoryBuffer} # Bypass the CSRF check if this origin is trusted by the CORS filter bypassCorsTrustedOrigins = true # Header configuration header { # The name of the header to accept CSRF tokens from. name = "Csrf-Token" # Defines headers that must be present to perform the CSRF check. If any of these headers are present, the CSRF # check will be performed. # # By default, we only perform the CSRF check if there are Cookies or an Authorization header. # Generally, CSRF attacks use a user's browser to execute requests on the client's behalf. If the user does not # have an active session, there is no danger of this happening. # # Setting this to null or an empty object will protect all requests. protectHeaders { Cookie = "*" Authorization = "*" } # Defines headers that can be used to bypass the CSRF check if any are present. A value of "*" simply # checks for the presence of the header. A string value checks for a match on that string. bypassHeaders {} } # Method lists method { # If non empty, then requests will be checked if the method is not in this list. whiteList = ["GET", "HEAD", "OPTIONS"] # The black list is only used if the white list is empty. # Only check methods in this list. blackList = [] } # Content type lists # If both white lists and black lists are empty, then all content types are checked. contentType { # If non empty, then requests will be checked if the content type is not in this list. whiteList = [] # The black list is only used if the white list is empty. # Only check content types in this list. blackList = [] } routeModifiers { # If non empty, then requests will be checked if the route does not have this modifier. This is how we enable the # nocsrf modifier, but you may choose to use a different modifier (such as "api") if you plan to check the # modifier in your code for other purposes. whiteList = ["nocsrf"] # If non empty, then requests will be checked if the route contains this modifier # The black list is used only if the white list is empty blackList = [] } # The error handler. # Used by Play's built in DI support to locate and bind a request handler. Must be one of the following: # - A FQCN that implements play.filters.csrf.CSRF.ErrorHandler (Scala). # - A FQCN that implements play.filters.csrf.CSRFErrorHandler (Java). # - provided, indicates that the application has bound an instance of play.filters.csrf.CSRF.ErrorHandler through some # other mechanism. # If null, will attempt to load a class called CSRFErrorHandler in the root package, otherwise if that's # not found, will default to play.filters.csrf.CSRF.CSRFHttpErrorHandler, which delegates to the configured # HttpRequestHandler. errorHandler = null } # Security headers filter configuration headers { # The X-Frame-Options header. If null, the header is not set. frameOptions = "DENY" # The X-XSS-Protection header. If null, the header is not set. xssProtection = "1; mode=block" # The X-Content-Type-Options header. If null, the header is not set. contentTypeOptions = "nosniff" # The X-Permitted-Cross-Domain-Policies header. If null, the header is not set. permittedCrossDomainPolicies = "master-only" # DEPRECATED: Content Security Policy. If null, the header is not set. # This config property is set to null deliberately as the CSPFilter replaces it. contentSecurityPolicy = null # The Referrer-Policy header. If null, the header is not set. referrerPolicy = "origin-when-cross-origin, strict-origin-when-cross-origin" # If true, allow an action to use .withHeaders to replace one or more of the above headers allowActionSpecificHeaders = false } # Content Security Policy filter configuration # Please see https://playframework.com/documentation/latest/CspFilter for more details. csp { # If true, the CSP output uses Content-Security-Policy-Report-Only header instead. reportOnly = false routeModifiers { # If non empty, then requests will be checked if the route does not have this modifier. whiteList = ["nocsp"] # If non empty, then requests will be checked if the route contains this modifier # The black list is used only if the white list is empty blackList = [] } # #csp-nonce # Specify a nonce to be used in CSP security header # https://www.w3.org/TR/CSP3/#security-nonces # # Nonces are used in script and style elements to protect against XSS attacks. nonce { # Use nonce value (generated and passed in through request attribute) enabled = true # Pattern to use to replace with nonce pattern = "%CSP_NONCE_PATTERN%" # Add the nonce to "X-Content-Security-Policy-Nonce" header. This is useful for debugging. header = false } # #csp-nonce # Specify hashes that are used internally in the content security policy. # The format of these hashes are as follows: # # { # algorithm = sha256 # hash = "RpniQm4B6bHP0cNtv7w1p6pVcgpm5B/eu1DNEYyMFXc=" # pattern = "%CSP_MYSCRIPT_HASH%" # } # # and should be used inline the same way as the nonce pattern, i.e. # # script-src = "%CSP_MYSCRIPT_HASH% 'strict-dynamic' ..." hashes = [] # #csp-directives # The directives here are set to the Google Strict CSP policy by default # https://csp.withgoogle.com/docs/strict-csp.html directives { # base-uri defaults to 'none' according to https://csp.withgoogle.com/docs/strict-csp.html # https://www.w3.org/TR/CSP3/#directive-base-uri base-uri = "'none'" # object-src defaults to 'none' according to https://csp.withgoogle.com/docs/strict-csp.html # https://www.w3.org/TR/CSP3/#directive-object-src object-src = "'none'" # script-src defaults according to https://csp.withgoogle.com/docs/strict-csp.html # https://www.w3.org/TR/CSP3/#directive-script-src script-src = ${play.filters.csp.nonce.pattern} "'unsafe-inline' 'unsafe-eval' 'strict-dynamic' https: http:" } # #csp-directives } # Allowed hosts filter configuration hosts { # A list of valid hosts (e.g. "example.com") or suffixes of valid hosts (e.g. ".example.com") # Note that ".example.com" will match example.com and any subdomain of example.com, with or without a trailing dot. # "." matches all domains, and "" matches an empty or nonexistent host. allowed = ["localhost", ".local", "127.0.0.1"] routeModifiers { # If non empty, then requests will be checked if the route does not have this modifier. This is how we enable the # anyhost modifier, but you may choose to use a different modifier (such as "api") if you plan to check the # modifier in your code for other purposes. whiteList = ["anyhost"] # If non empty, then requests will be checked if the route contains this modifier # The black list is used only if the white list is empty blackList = [] } } # CORS filter configuration cors { # The path prefixes to filter. pathPrefixes = ["/"] # The allowed origins. If null, all origins are allowed. allowedOrigins = null # The allowed HTTP methods. If null, all methods are allowed allowedHttpMethods = null # The allowed HTTP headers. If null, all headers are allowed. allowedHttpHeaders = null # The exposed headers exposedHeaders = [] # Whether to support credentials supportsCredentials = true # The maximum amount of time the CORS meta data should be cached by the client preflightMaxAge = 1 hour # Whether to serve forbidden origins as non-CORS requests serveForbiddenOrigins = false } # GZip filter configuration gzip { # The maximum amount of data to send to the Gzip compressor in one go. Use `0` or `2147483647` to disable the buffering. # # In general, it is recommended to turn off the buffer and prevent generation of overlong chunks at the source. bufferSize = 8k # The maximum amount of content to buffer for gzipping in order to calculate the content length before falling back # to chunked encoding. chunkedThreshold = 100k contentType { # If non empty, then a response will only be compressed if its content type is in this list. whiteList = [] # The black list is only used if the white list is empty. # Compress all responses except the ones whose content type is in this list. blackList = [] } # The compression level to use, integer, -1 to 9, inclusive. See java.util.zip.Deflater. compressionLevel = -1 # The byte threshold for the response body size which controls if a response should be gzipped (e.g. 1k). # If the body size cannot be determined, then it is assumed the response is over the threshold. # Set to 0 if you want to compress all responses, no matter how large the response body size is. threshold = 0 } # Configuration for redirection to HTTPS and Strict-Transport-Security https { # A boolean defining whether the redirect to HTTPS is enabled. # A value of null means enabled only in Prod mode, but disabled in Dev/Test. redirectEnabled = null # The Strict-Transport-Security header is used to signal to browsers to always use https. # This header is added whenever a request is secure and redirectEnabled is true. # Set to null to disable the header. strictTransportSecurity = "max-age=31536000; includeSubDomains" # Configures the redirect status code used if the request is not secure. # By default, uses HTTP status code 308, which is a permanent redirect that does # not change the HTTP method according to [RFC 7238](https://tools.ietf.org/html/rfc7538). redirectStatusCode = 308 # A boolean defining whether to only redirect if a x-forwarded-proto header is set to http. # This is a defacto standard that will be used by various proxys or load balancers to determine # if a redirect should happen. # [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto) xForwardedProtoEnabled = false # No redirect happens if path is in this list. # Query params don't matter, meaning if the list contains "/foo" the request "/foo?abc=xyz" will be excluded too. # Paths in this list are encoded, if you want to exclude "/foöbär" you have to add "/fo%C3%B6b%C3%A4r" to the list. excludePaths = [] # The HTTPS port to use in the Redirect's Location URL. # e.g. port = 9443 results in https://playframework.com:9443/some/url port = null port = ${?play.server.https.port} # default to same HTTPS port as play server } }