Skip to content

Instantly share code, notes, and snippets.

@vincd
Created March 12, 2022 17:16
Show Gist options
  • Save vincd/25c762d947a49a41ebb1dbad82a17a84 to your computer and use it in GitHub Desktop.
Save vincd/25c762d947a49a41ebb1dbad82a17a84 to your computer and use it in GitHub Desktop.
Security Header example server : https//unbonhacker.com/posts/security-headers/
"""
```bash
pip install flask
python server.py
```
The serveur use http://127.0.0.1:8000 and http://localhost:8000 as two differents
origins. So remember to test with this two URLs.
"""
from flask import Flask, Response, request
app = Flask(__name__)
PORT = 8000
REFERRER_POLICY = [
'no-referrer',
'no-referrer-when-downgrade',
'origin',
'origin-when-cross-origin',
'same-origin',
'strict-origin',
'strict-origin-when-cross-origin',
'unsafe-url'
]
# Shortcut to create a Flask response
def render(body, headers):
return Response(f'<!DOCTYPE html><html><body>{body}</body></html>', headers=headers)
@app.route('/')
def index():
body = '<h1>HTTP Security Headers Demonstration</h1><ul>'
# body += '<li><a href="/Strict-Transport-Security">Strict-Transport-Security</a></li>'
body += '<li><a href="/X-Frame-Options">X-Frame-Options</a></li>'
body += '<li><a href="/Cross-Origin-Resource-Sharing">Cross-Origin-Resource-Sharing</a></li>'
body += '<li><a href="/Content-Security-Policy">Content-Security-Policy</a></li>'
body += '<li><a href="/X-Content-Type-Options">X-Content-Type-Options</a></li>'
body += '<li><a href="/Referrer-Policy">Referrer-Policy</a></li>'
# body += '<li><a href="/X-XSS-Protection">X-XSS-Protection</a></li>'
body += '<li><a href="/Set-Cookie">Set-Cookie</a></li>'
# body += '<li><a href="/Cross-Origin-Opener-Policy">Cross-Origin-Opener-Policy</a></li>'
body += '</ul>'
return render(body, {})
@app.route('/Strict-Transport-Security')
def StrictTransportSecurity():
return render('<h1>Strict-Transport-Security</h1>', {})
@app.route('/X-Frame-Options')
def XFrameOptions():
body = '<h1>X-Frame-Options</h1>'
headers = {}
frame = request.args.get('frame', '')
if frame != '':
body += f'<p>Page with origin http://localhost:{PORT} and header "{frame}"</p>'
body += '<form><select name="frame">'
body += '<option value="deny">Deny frame</option>'
body += '<option value="sameorigin">Allow from same origin</option>'
body += '<option value="no-header">No header</option>'
body += '</select><button>Go</button></form>'
else:
body += f'<p>This page include an other page included. Use <a href="http://127.0.0.1:{PORT}/X-Frame-Options">127.0.0.1</a> or <a href="http://localhost:{PORT}/X-Frame-Options">localhost</a> as 2 diffrents origins!</p>'
body += '<form><button>RELOAD FRAME</button></form>'
body += f'<iframe src="http://localhost:{PORT}/X-Frame-Options?frame=no-header"></iframe>'
if frame == 'deny':
headers['X-Frame-Options'] = 'DENY'
elif frame == 'sameorigin':
headers['X-Frame-Options'] = 'SAMEORIGIN'
return render(body, headers)
@app.route("/scripts/bad_cors.js")
def script_bad_cors():
headers = {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*"
}
return Response('{"msg": "This ressource comes from an other origin!"}', headers=headers)
@app.route("/scripts/good_cors.js")
def script_good_cors():
headers = {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": f"http://localhost:{PORT}"
}
return Response('{"msg": "This ressource comes from an other origin!"}', headers=headers)
@app.route('/Cross-Origin-Resource-Sharing')
def CrossOriginResourceSharing():
body = '<h1>Cross-Origin-Resource-Sharing</h1>'
cors = request.args.get('cors', '')
url = f'http://localhost:{PORT}/scripts/bad_cors.js' if cors == 'allow' else f'http://localhost:{PORT}/scripts/good_cors.js'
body += '<form><select name="cors">'
body += '<option value="allow">Allow from other site</option>'
body += '<option value="deny">Deny from other site</option>'
body += '</select><button>Go</button></form>'
body += f'<script>fetch("{url}").then(r => r.json()).then(data => alert(data.msg));</script>'
return render(body, {})
@app.route("/scripts/csp.js")
def script_csp():
return f'alert("This script is from a file")'
@app.route('/Content-Security-Policy')
def ContentSecurityPolicy():
body = '<h1>Content-Security-Policy</h1>'
headers = {}
csp = request.args.get('csp', '')
body += '<form><select name="csp">'
body += '<option value="none">script-src: none</option>'
body += '<option value="self">script-src: \'self\'</option>'
body += '<option value="unsafe-inline">script-src: unsafe-inline</option>'
body += '<option value="nothing">No header</option>'
body += '</select><button>Go</button></form><script>alert("This script is inline");</script><script src="/scripts/csp.js"></script>'
if csp == 'none':
headers['Content-Security-Policy'] = 'script-src none;'
elif csp == 'self':
headers['Content-Security-Policy'] = 'script-src \'self\';'
elif csp == 'unsafe-inline':
headers['Content-Security-Policy'] = 'script-src \'unsafe-inline\';'
return render(body, headers)
@app.route('/scripts/plain_text.js')
def scripts_plain_text():
headers = {}
ctopt = request.args.get('ctopt')
if ctopt == 'nosniff':
headers['X-Content-Type-Options'] = 'nosniff'
return Response('alert("Script executed with Content-Type: plain/text")', headers=headers)
@app.route('/X-Content-Type-Options')
def XContentTypeOptions():
body = '<h1>X-Content-Type-Options</h1>'
headers = {}
ctopt = request.args.get('ctopt')
body += '<form><select name="ctopt">'
body += '<option value="nosniff">X-Content-Type-Options: nosniff</option>'
body += '<option value="">No header X-Content-Type-Options</option>'
body += f'</select><button>Go</button></form><script src="/scripts/plain_text.js?ctopt={ctopt}"></script>'
return render(body, headers)
@app.route("/scripts/referrer.js")
def script_referrer():
referrer = request.headers.get('Referer', '')
return f'alert("Referer header value: \\"{referrer}\\"")'
@app.route('/Referrer-Policy')
def ReferrerPolicy():
ref = request.args.get('referrer')
if not ref in REFERRER_POLICY:
ref = ''
body = '<h1>Referrer-Policy</h1><form><select name="referrer">'
for r in REFERRER_POLICY:
body += f'<option value="{r}">{r}</option>'
body += '</select><button>Go</button></form><script src="/scripts/referrer.js"></script>'
headers = {}
if ref != '':
headers["Referrer-Policy"] = ref
return render(body, headers)
@app.route('/X-XSS-Protection')
def XXSSProtection():
return render('<h1>X-XSS-Protection</h1>', {})
@app.route("/scripts/cookies.js")
def script_cookies():
cookies = request.headers['cookie']
return f'alert("Cookies from headers: {cookies}"); alert("Cookies from Javascript:" + document.cookie)'
@app.route('/Set-Cookie')
def SetCookie():
body = '<h1>Set-Cookie</h1><form><select name="cookie">'
body += '<option value="httponly">Cookie with HttpOnly</option>'
body += '<option value="no-httponly">Cookie without HttpOnly</option>'
body += '<option value="remove">Remove cookie</option>'
body += '</select><button>Go</button></form><script src="/scripts/cookies.js"></script>'
cookie = request.args.get('cookie', '')
headers = {}
if cookie == 'httponly':
headers['Set-Cookie'] = 'TestCookie=TestWithHttpOnly; path=/; httpOnly; SameSite=Lax'
elif cookie == 'no-httponly':
headers['Set-Cookie'] = 'TestCookie=TestWithHttpOnly; path=/; SameSite=Lax'
elif cookie == 'remove':
headers['Set-Cookie'] = 'TestCookie=Delete; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Lax'
return render(body, headers)
if __name__ == "__main__":
app.run(
host="127.0.0.1",
port=PORT,
debug=True
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment