Skip to content

Commit

Permalink
Move X-Frame-Options into SecurityRules.
Browse files Browse the repository at this point in the history
We add a FrameRestrictions sealed trait to represent the
available frame restrictions, and make it Optional. The default
is FrameRestrictions.SameOrigin, so as to line up with the
previous Lift default of only allowing inclusion in frames from
the same origin.
  • Loading branch information
Shadowfiend committed Jan 31, 2015
1 parent 5496653 commit 6d9a55a
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 13 deletions.
1 change: 0 additions & 1 deletion web/webkit/src/main/scala/net/liftweb/http/LiftRules.scala
Expand Up @@ -1654,7 +1654,6 @@ class LiftRules() extends Factory with FormVendor with LazyLoggable {
*/
val supplementalHeaders: FactoryMaker[List[(String, String)]] = new FactoryMaker(() => {
("X-Lift-Version", liftVersion) ::
("X-Frame-Options", "SAMEORIGIN") ::
securityRules().headers
}) {}

Expand Down
59 changes: 47 additions & 12 deletions web/webkit/src/main/scala/net/liftweb/http/SecurityRules.scala
Expand Up @@ -372,37 +372,72 @@ object ContentSecurityPolicyViolation extends LazyLoggable {
}
}

/**
* Defines restrictions on allowing served pages to be embedded in frames.
*/
sealed trait FrameRestrictions {
def headers: List[(String,String)]

/**
* Returns the headers implied by these frame restrictions.
*
* Because of how frame restrictions are handled, if enforcement in dev mode
* is turned off, no headers are generated in dev mode.
*/
def headers(enforceInDevMode: Boolean = false): List[(String,String)] = {
if (! enforceInDevMode && Props.devMode) {
Nil
} else {
headers
}
}
}
object FrameRestrictions {
/**
* Allows other pages from the same origin as the one being served to embed
* this page in a frame.
*/
case object SameOrigin extends FrameRestrictions {
val headers = List("X-Frame-Options" -> "SAMEORIGIN")
}
/**
* Does not allow embedding the page being served in a frame at all.
*/
case object Deny extends FrameRestrictions {
val headers = List("X-Frame-Options" -> "DENY")
}
}

/**
* Specifies security rules for a Lift application. By default, HTTPS is not
* required and `Content-Security-Policy` is restricted to the current domain
* for everything except images, which are accepted from any domain.
*
* You can use `[[SecurityRules.secure]]` to enable more restrictive, but
* also more secure, defaults.
*
* @param enforceInDevMode If true, security policies and HTTPS rules are
* enforced in dev mode in addition to staging/pilot/production/etc.
* @param logInDevMode If true, dev mode violations of security policies are
* logged by default. Note that if you override
* [[`LiftRules.contentSecurityPolicyViolationReport`]] or otherwise
* change the default Lift policy violation handling behavior, it will
* be up to you to handle this property as desired.
*/
final case class SecurityRules(
https: Option[HttpsRules] = None,
content: Option[ContentSecurityPolicy] = Some(ContentSecurityPolicy()),
/**
* If true, security policies and HTTPS rules are enforced in dev mode in
* addition to staging/pilot/production/etc.
*/
frameRestrictions: Option[FrameRestrictions] = Some(FrameRestrictions.SameOrigin),
enforceInDevMode: Boolean = false,
/**
* If true, dev mode violations of security policies are logged by
* default. Note that if you override
* [[`LiftRules.contentSecurityPolicyViolationReport`]] or otherwise change
* the default Lift policy violation handling behavior, it will be up to you
* to handle this property as desired.
*/
logInDevMode: Boolean = true
) {
/**
* Returns the headers implied by this set of security rules.
*/
lazy val headers: List[(String, String)] = {
https.toList.flatMap(_.headers(enforceInDevMode)) :::
content.toList.flatMap(_.headers(enforceInDevMode))
content.toList.flatMap(_.headers(enforceInDevMode)) :::
frameRestrictions.toList.flatMap(_.headers(enforceInDevMode))
}
}
object SecurityRules {
Expand Down

0 comments on commit 6d9a55a

Please sign in to comment.