Skip to content

Commit

Permalink
Merge a456964 into 7c7e8ef
Browse files Browse the repository at this point in the history
  • Loading branch information
jezdez committed Oct 5, 2018
2 parents 7c7e8ef + a456964 commit b581c81
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 32 deletions.
4 changes: 3 additions & 1 deletion flask_talisman/talisman.py
Expand Up @@ -106,7 +106,7 @@ def init_app(
and requires a "report-uri" parameter with a backend to receive
the POST data
content_security_policy_nonce_in: A list of csp sections to include
a per-request none value in
a per-request nonce value in
referrer_policy: A string describing the referrer policy for the
response.
session_cookie_secure: Forces the session cookie to only be sent
Expand Down Expand Up @@ -274,6 +274,8 @@ def _set_feature_headers(self, headers, options):
headers['Feature-Policy'] = policy

def _set_frame_options_headers(self, headers, options):
if not options['frame_options']:
return
headers['X-Frame-Options'] = options['frame_options']

if options['frame_options'] == ALLOW_FROM:
Expand Down
64 changes: 33 additions & 31 deletions flask_talisman/talisman_test.py
Expand Up @@ -89,12 +89,12 @@ def testHstsOptions(self):

# No HSTS headers for non-ssl requests
response = self.client.get('/')
self.assertFalse('Strict-Transport-Security' in response.headers)
self.assertNotIn('Strict-Transport-Security', response.headers)

# Secure request with HSTS off
self.talisman.strict_transport_security = False
response = self.client.get('/', environ_overrides=HTTPS_ENVIRON)
self.assertFalse('Strict-Transport-Security' in response.headers)
self.assertNotIn('Strict-Transport-Security', response.headers)

# HSTS back on
self.talisman.strict_transport_security = True
Expand All @@ -103,20 +103,18 @@ def testHstsOptions(self):
response = self.client.get('/', headers={
'X-Forwarded-Proto': 'https'
})
self.assertTrue('Strict-Transport-Security' in response.headers)
self.assertIn('Strict-Transport-Security', response.headers)

# No subdomains
self.talisman.strict_transport_security_include_subdomains = False
response = self.client.get('/', environ_overrides=HTTPS_ENVIRON)
self.assertFalse(
'includeSubDomains' in
response.headers['Strict-Transport-Security'])
self.assertNotIn(
'includeSubDomains', response.headers['Strict-Transport-Security'])

# Preload
self.talisman.strict_transport_security_preload = True
response = self.client.get('/', environ_overrides=HTTPS_ENVIRON)
self.assertTrue(
'preload' in response.headers['Strict-Transport-Security'])
self.assertIn('preload', response.headers['Strict-Transport-Security'])

def testFrameOptions(self):
self.talisman.frame_options = DENY
Expand All @@ -129,21 +127,25 @@ def testFrameOptions(self):
self.assertEqual(
response.headers['X-Frame-Options'], 'ALLOW-FROM example.com')

self.talisman.frame_options = None
response = self.client.get('/', environ_overrides=HTTPS_ENVIRON)
self.assertNotIn('X-Frame-Options', response.headers)

def testContentSecurityPolicyOptions(self):
self.talisman.content_security_policy['image-src'] = '*'
response = self.client.get('/', environ_overrides=HTTPS_ENVIRON)
csp = response.headers['Content-Security-Policy']
self.assertTrue('default-src \'self\'' in csp)
self.assertTrue('image-src *' in csp)
self.assertIn('default-src \'self\'', csp)
self.assertIn('image-src *', csp)

self.talisman.content_security_policy['image-src'] = [
'\'self\'',
'example.com'
]
response = self.client.get('/', environ_overrides=HTTPS_ENVIRON)
csp = response.headers['Content-Security-Policy']
self.assertTrue('default-src \'self\'' in csp)
self.assertTrue('image-src \'self\' example.com' in csp)
self.assertIn('default-src \'self\'', csp)
self.assertIn('image-src \'self\' example.com', csp)

# string policy
self.talisman.content_security_policy = 'default-src example.com'
Expand All @@ -154,7 +156,7 @@ def testContentSecurityPolicyOptions(self):
# no policy
self.talisman.content_security_policy = False
response = self.client.get('/', environ_overrides=HTTPS_ENVIRON)
self.assertFalse('Content-Security-Policy' in response.headers)
self.assertNotIn('Content-Security-Policy', response.headers)

# string policy at initialization
app = flask.Flask(__name__)
Expand All @@ -171,26 +173,26 @@ def testContentSecurityPolicyOptionsReport(self):
self.talisman.content_security_policy_report_uri = \
'https://example.com'
response = self.client.get('/', environ_overrides=HTTPS_ENVIRON)
self.assertTrue(
'Content-Security-Policy-Report-Only' in response.headers)
self.assertTrue(
'X-Content-Security-Policy-Report-Only' in response.headers)
self.assertTrue(
'report-uri'
in response.headers['Content-Security-Policy-Report-Only'])
self.assertFalse('Content-Security-Policy' in response.headers)
self.assertFalse('X-Content-Security-Policy' in response.headers)
self.assertIn('Content-Security-Policy-Report-Only', response.headers)
self.assertIn(
'X-Content-Security-Policy-Report-Only', response.headers)
self.assertIn(
'report-uri',
response.headers['Content-Security-Policy-Report-Only']
)
self.assertNotIn('Content-Security-Policy', response.headers)
self.assertNotIn('X-Content-Security-Policy', response.headers)

override_report_uri = 'https://report-uri.io/'
self.talisman.content_security_policy = {
'report-uri': override_report_uri,
}
response = self.client.get('/', environ_overrides=HTTPS_ENVIRON)
self.assertTrue(
'Content-Security-Policy-Report-Only' in response.headers)
self.assertTrue(
override_report_uri
in response.headers['Content-Security-Policy-Report-Only']
self.assertIn(
'Content-Security-Policy-Report-Only', response.headers)
self.assertIn(
override_report_uri,
response.headers['Content-Security-Policy-Report-Only']
)

# exception on missing report-uri when report-only
Expand Down Expand Up @@ -223,7 +225,7 @@ def nocsp():
return 'Hello, world'

response = self.client.get('/nocsp', environ_overrides=HTTPS_ENVIRON)
self.assertFalse('Content-Security-Policy' in response.headers)
self.assertNotIn('Content-Security-Policy', response.headers)
self.assertEqual(response.headers['X-Frame-Options'], 'SAMEORIGIN')

def testDecoratorForceHttps(self):
Expand All @@ -238,7 +240,7 @@ def noforcehttps():
def testForceFileSave(self):
self.talisman.force_file_save = True
response = self.client.get('/', environ_overrides=HTTPS_ENVIRON)
self.assertTrue('X-Download-Options' in response.headers)
self.assertIn('X-Download-Options', response.headers)
self.assertEqual(response.headers['X-Download-Options'], 'noopen')

def testBadEndpoint(self):
Expand All @@ -252,12 +254,12 @@ def testFeaturePolicy(self):
self.talisman.feature_policy['geolocation'] = '\'none\''
response = self.client.get('/', environ_overrides=HTTPS_ENVIRON)
feature_policy = response.headers['Feature-Policy']
self.assertTrue('geolocation \'none\'' in feature_policy)
self.assertIn('geolocation \'none\'', feature_policy)

self.talisman.feature_policy['fullscreen'] = '\'self\' example.com'
response = self.client.get('/', environ_overrides=HTTPS_ENVIRON)
feature_policy = response.headers['Feature-Policy']
self.assertTrue('fullscreen \'self\' example.com' in feature_policy)
self.assertIn('fullscreen \'self\' example.com', feature_policy)

# string policy at initialization
app = flask.Flask(__name__)
Expand Down

0 comments on commit b581c81

Please sign in to comment.