# script-src 'self' 'unsafe-inline' https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.min.js https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/js/bootstrap.min.js; # style-src 'unsafe-inline' https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/ sh.update({ 'CSP': { 'default-src': [ 'self', ], 'connect-src': [ 'self', ], 'script-src': [ 'self', 'https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js', 'https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js', ], 'style-src': [ 'self', 'https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/', ], 'img-src': [ 'self', ], 'font-src': [ 'self', 'fonts.googleapis.com', 'fonts.gstatic.com', ] } }) sh.update({'HSTS': {
sh.update( { 'CSP': { 'default-src': [ 'self', ], 'script-src': [ 'self', 'data:', 'ajax.googleapis.com', 'fonts.googleapis.com', 'https://*.googletagmanager.com', 'https://tagmanager.google.com', 'https://*.google-analytics.com', 'https://cdn.sso.mozilla.com', 'https://cdn.sso.allizom.org', 'https://dhjrqi6qcwjfu.cloudfront.net' ], 'style-src': [ 'self', 'ajax.googleapis.com', 'fonts.googleapis.com', 'https://cdn.sso.mozilla.com', 'https://cdn.sso.allizom.org', 'https://dhjrqi6qcwjfu.cloudfront.net' ], 'img-src': [ 'self', 'https://mozillians.org', 'https://media.mozillians.org', 'https://cdn.mozillians.org', 'https://cdn.sso.mozilla.com', 'https://cdn.sso.allizom.org', 'https://*.google-analytics.com', 'https://*.gravatar.com', 'https://cdn.sso.mozilla.com', 'https://cdn.sso.allizom.org', 'https://dhjrqi6qcwjfu.cloudfront.net' ], 'font-src': [ 'self', 'fonts.googleapis.com', 'fonts.gstatic.com', 'https://cdn.sso.mozilla.com', 'https://cdn.sso.allizom.org', 'https://dhjrqi6qcwjfu.cloudfront.net' ] } } )
vanity_router = vanity.Router(app=app).setup() # Add secure Headers to satify observatory checks sh = Secure_Headers() sh.update({ 'CSP': { 'default-src': [ 'self', ], 'script-src': [ 'self', 'data:', 'ajax.googleapis.com', 'fonts.googleapis.com', 'https://*.googletagmanager.com', 'https://tagmanager.google.com', 'https://*.google-analytics.com' ], 'style-src': [ 'self', 'ajax.googleapis.com', 'fonts.googleapis.com', ], 'img-src': ['self', 'https://mozillians.org', 'https://*.google-analytics.com'], 'font-src': [ 'self', 'fonts.googleapis.com', 'fonts.gstatic.com', ] } }) sh.update({ 'HSTS': { 'max-age': 15768000,
sh.update( { 'CSP': { 'default-src': [ 'self', ], 'connect-src': [ 'self', ], 'script-src': [ 'self', 'https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js', 'https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js', ], 'style-src': [ 'self', 'https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/', ], 'img-src': [ 'self', ], 'font-src': [ 'self', 'fonts.googleapis.com', 'fonts.gstatic.com', ] } } )
class TestAppUseCase(TestHeaders): """ test header creation in flask app """ def setUp(self): self.app = Flask(__name__) self.sh = Secure_Headers() def test_defaults(self): """ test header wrapper with default headers """ @self.app.route('/') @self.sh.wrapper() def index(): return "hi" with self.app.test_client() as c: result = c.get('/') self.assertEquals(result.headers.get('X-XSS-Protection'),'1; mode=block') self.assertEquals(result.headers.get('Strict-Transport-Security'),'includeSubDomains; max-age=31536000') self.assertEquals(result.headers.get('Public-Key-Pins'),'includeSubDomains; report-uri=/hpkp_report; max-age=5184000') self.assertEquals(result.headers.get('X-Content-Type-Options'),'nosniff') self.assertEquals(result.headers.get('X-Permitted-Cross-Domain-Policies'),'none') self.assertEquals(result.headers.get('X-Download-Options'),'noopen') self.assertEquals(result.headers.get('X-Frame-Options'),'sameorigin') self.assertHeaderEquals(result.headers.get('Content-Security-Policy'),"report-uri /csp_report; default-src 'self'") def test_update_function(self): """ test config update function """ self.sh.update( { 'X_Permitted_Cross_Domain_Policies':{'value':'all'}, 'CSP':{'script-src':['self','code.jquery.com']}, 'HPKP':{'pins':[{'sha256':'test123'},{'sha256':'test2256'}]} } ) @self.app.route('/') @self.sh.wrapper() def index(): return "hi" with self.app.test_client() as c: result = c.get('/') self.assertEquals(result.headers.get('X-Permitted-Cross-Domain-Policies'),'all') self.assertEquals(result.headers.get('Content-Security-Policy'),"script-src 'self' code.jquery.com; report-uri /csp_report; default-src 'self'") self.assertEquals(result.headers.get('Public-Key-Pins'),"pin-sha256=test123; pin-sha256=test2256; includeSubDomains; report-uri=/hpkp_report; max-age=5184000") def test_rewrite_function(self): """ test config rewrite function """ self.sh.rewrite( { 'CSP':{'default-src':['none']}, 'HPKP':{'pins':[{'sha256':'test123'}]} } ) @self.app.route('/') @self.sh.wrapper() def index(): return "hi" with self.app.test_client() as c: result = c.get('/') self.assertEquals(result.headers.get('Content-Security-Policy'),"default-src 'none'") self.assertEquals(result.headers.get('Public-Key-Pins'),"pin-sha256=test123") def test_wrapper_update_function(self): """ test updating policies from wrapper """ self.sh.rewrite( { 'CSP':{'default-src':['none']}, 'HPKP':{'pins':[{'sha256':'test123'}]} } ) @self.app.route('/') @self.sh.wrapper( { 'CSP':{'script-src':['self','code.jquery.com']}, 'X_Permitted_Cross_Domain_Policies':{'value':'none'}, 'X-XSS-Protection':{'value':1,'mode':False}, 'HPKP':{'pins':[{'sha256':'test2256'}]}, } ) def index(): return "hi" with self.app.test_client() as c: result = c.get('/') self.assertEquals(result.headers.get('X-Permitted-Cross-Domain-Policies'),'none') self.assertHeaderEquals(result.headers.get('Content-Security-Policy'),"script-src 'self' code.jquery.com; default-src 'none'") self.assertEquals(result.headers.get('X-XSS-Protection'),'1') self.assertEquals(result.headers.get('Public-Key-Pins'),"pin-sha256=test2256; pin-sha256=test123") @self.app.route('/test') @self.sh.wrapper({'CSP':{'script-src':['nonce-1234']}}) def test(): return "hi" with self.app.test_client() as c: result = c.get('/test') self.assertHeaderEquals(result.headers.get('Content-Security-Policy'),"script-src 'self' code.jquery.com 'nonce-1234'; default-src 'none'") def test_passing_none_value_rewrite(self): """ test removing header from update/rewrite """ self.sh.rewrite({'CSP':None,'X_XSS_Protection':None}) @self.app.route('/') @self.sh.wrapper() def index(): return "hi" with self.app.test_client() as c: result = c.get('/') self.assertEquals(result.headers.get('X-Permitted-Cross-Domain-Policies'),'none') self.assertEquals(result.headers.get('CSP'),None) self.assertEquals(result.headers.get('X-XSS-Protection'),None) def test_passing_none_value_wrapper(self): """ test removing policy from wrapper """ @self.app.route('/') @self.sh.wrapper({'CSP':None,'X-XSS-Protection':None}) def index(): return "hi" with self.app.test_client() as c: result = c.get('/') self.assertEquals(result.headers.get('X-Permitted-Cross-Domain-Policies'),'none') self.assertEquals(result.headers.get('CSP'),None) self.assertEquals(result.headers.get('X-XSS-Protection'),None)
class TestAppUseCase(unittest.TestCase): """ test header creation in flask app """ def setUp(self): self.app = Flask(__name__) self.sh = Secure_Headers() def test_defaults(self): """ test header wrapper with default headers """ @self.app.route('/') @self.sh.wrapper() def index(): return "hi" with self.app.test_client() as c: result = c.get('/') self.assertEquals(result.headers.get('X-XSS-Protection'),'1; mode=block') self.assertEquals(result.headers.get('Strict-Transport-Security'),'includeSubDomains; max-age=31536000') self.assertEquals(result.headers.get('Public-Key-Pins'),'includeSubDomains; report-uri=/hpkp_report; max-age=5184000') self.assertEquals(result.headers.get('X-Content-Type-Options'),'nosniff') self.assertEquals(result.headers.get('X-Permitted-Cross-Domain-Policies'),'none') self.assertEquals(result.headers.get('X-Download-Options'),'noopen') self.assertEquals(result.headers.get('X-Frame-Options'),'sameorigin') self.assertEquals(result.headers.get('Content-Security-Policy'),"report-uri /csp_report; default-src 'self'") def test_update_function(self): """ test config update function """ self.sh.update( { 'X_Permitted_Cross_Domain_Policies':{'value':'all'}, 'CSP':{'script-src':['self','code.jquery.com']}, 'HPKP':{'pins':[{'sha256':'test123'},{'sha256':'test2256'}]} } ) @self.app.route('/') @self.sh.wrapper() def index(): return "hi" with self.app.test_client() as c: result = c.get('/') self.assertEquals(result.headers.get('X-Permitted-Cross-Domain-Policies'),'all') self.assertEquals(result.headers.get('Content-Security-Policy'),"script-src 'self' code.jquery.com; report-uri /csp_report; default-src 'self'") self.assertEquals(result.headers.get('Public-Key-Pins'),"pin-sha256=test123; pin-sha256=test2256; includeSubDomains; report-uri=/hpkp_report; max-age=5184000") def test_rewrite_function(self): """ test config rewrite function """ self.sh.rewrite( { 'CSP':{'default-src':['none']}, 'HPKP':{'pins':[{'sha256':'test123'}]} } ) @self.app.route('/') @self.sh.wrapper() def index(): return "hi" with self.app.test_client() as c: result = c.get('/') self.assertEquals(result.headers.get('Content-Security-Policy'),"default-src 'none'") self.assertEquals(result.headers.get('Public-Key-Pins'),"pin-sha256=test123") def test_wrapper_update_function(self): """ test updating policies from wrapper """ self.sh.rewrite( { 'CSP':{'default-src':['none']}, 'HPKP':{'pins':[{'sha256':'test123'}]} } ) @self.app.route('/') @self.sh.wrapper( { 'CSP':{'script-src':['self','code.jquery.com']}, 'X_Permitted_Cross_Domain_Policies':{'value':'none'}, 'X-XSS-Protection':{'value':1,'mode':False}, 'HPKP':{'pins':[{'sha256':'test2256'}]}, } ) def index(): return "hi" with self.app.test_client() as c: result = c.get('/') self.assertEquals(result.headers.get('X-Permitted-Cross-Domain-Policies'),'none') self.assertEquals(result.headers.get('Content-Security-Policy'),"script-src 'self' code.jquery.com; default-src 'none'") self.assertEquals(result.headers.get('X-XSS-Protection'),'1') self.assertEquals(result.headers.get('Public-Key-Pins'),"pin-sha256=test2256; pin-sha256=test123") @self.app.route('/test') @self.sh.wrapper({'CSP':{'script-src':['nonce-1234']}}) def test(): return "hi" with self.app.test_client() as c: result = c.get('/test') self.assertEquals(result.headers.get('Content-Security-Policy'),"script-src 'self' code.jquery.com 'nonce-1234'; default-src 'none'") def test_passing_none_value_rewrite(self): """ test removing header from update/rewrite """ self.sh.rewrite({'CSP':None,'X_XSS_Protection':None}) @self.app.route('/') @self.sh.wrapper() def index(): return "hi" with self.app.test_client() as c: result = c.get('/') self.assertEquals(result.headers.get('X-Permitted-Cross-Domain-Policies'),'none') self.assertEquals(result.headers.get('CSP'),None) self.assertEquals(result.headers.get('X-XSS-Protection'),None) def test_passing_none_value_wrapper(self): """ test removing policy from wrapper """ @self.app.route('/') @self.sh.wrapper({'CSP':None,'X-XSS-Protection':None}) def index(): return "hi" with self.app.test_client() as c: result = c.get('/') self.assertEquals(result.headers.get('X-Permitted-Cross-Domain-Policies'),'none') self.assertEquals(result.headers.get('CSP'),None) self.assertEquals(result.headers.get('X-XSS-Protection'),None)
from flask import Blueprint, render_template, flash, request, abort, make_response from sqliteFunctions import sqliteAdminFunctions, rules import sqlite3 import json import types from flask_secure_headers.core import Secure_Headers from functools import wraps import os.path # decorators sh = Secure_Headers() sh.update({'CSP':{'default-src':['localhost'],'script-src':['self','code.jquery.com','sha256-0U0JKOeLnVrPAm22MQQtlb5cufdXFDzRS9l-petvH6U=']}}) def defaultDecorator(f): @wraps(f) def decorated_function(*args, **kwargs): return make_response(f(*args, **kwargs)) return decorated_function def sqliteAdminBlueprint(dbPath,bpName='sqliteAdmin',tables=[],title='sqlite Admin',h1='sqlite Admin',baseLayout='base.html',extraRules=[],decorator=defaultDecorator): """ create routes for admin """ sqlite = Blueprint(bpName, __name__,template_folder='templates',static_folder='static') @sqlite.route('/',methods=['GET']) @decorator @sh.wrapper() def index(): db = sqlite3.connect(dbPath) sf = sqliteAdminFunctions(db,tables=tables,extraRules=extraRules) res = sf.tableList(tables)