new: SRI validation on resources

pull/219/head
Raphaël Vinot 2021-06-16 17:36:01 -07:00
parent 4a8db1fc6e
commit c89689374e
19 changed files with 110 additions and 73 deletions

View File

@ -30,3 +30,11 @@ jobs:
- name: Test with nosetests - name: Test with nosetests
run: | run: |
poetry run mypy . poetry run mypy .
- name: Make sure SRIs are up-to-date
run: |
poetry run tools/generate_sri.py
if $?; then
echo "SRIs not up-to-date, you must run tools/generate_sri.py"
exit 1
fi

View File

@ -26,7 +26,9 @@ from lookyloo.helpers import (get_homedir, update_user_agents, get_user_agents,
get_taxonomies, load_cookies, CaptureStatus) get_taxonomies, load_cookies, CaptureStatus)
from lookyloo.lookyloo import Lookyloo, Indexing from lookyloo.lookyloo import Lookyloo, Indexing
from lookyloo.exceptions import NoValidHarFile, MissingUUID from lookyloo.exceptions import NoValidHarFile, MissingUUID
from .proxied import ReverseProxied from .proxied import ReverseProxied
from .helpers import sri_load
app: Flask = Flask(__name__) app: Flask = Flask(__name__)
app.wsgi_app = ReverseProxied(app.wsgi_app) # type: ignore app.wsgi_app = ReverseProxied(app.wsgi_app) # type: ignore
@ -192,6 +194,14 @@ def month_name(month: int):
app.jinja_env.globals.update(month_name=month_name) app.jinja_env.globals.update(month_name=month_name)
def get_sri(directory: str, filename: str) -> str:
sha512 = sri_load()[directory][filename]
return f'sha512-{sha512}'
app.jinja_env.globals.update(get_sri=get_sri)
# ##### Generic/configuration methods ##### # ##### Generic/configuration methods #####
def src_request_ip(request) -> str: def src_request_ip(request) -> str:

14
website/web/helpers.py Normal file
View File

@ -0,0 +1,14 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import json
from functools import lru_cache
from typing import Dict
from lookyloo.helpers import get_homedir
@lru_cache(64)
def sri_load() -> Dict[str, Dict[str, str]]:
with (get_homedir() / 'website' / 'web' / 'sri.txt').open() as f:
return json.load(f)

45
website/web/sri.txt Normal file
View File

@ -0,0 +1,45 @@
{
"static": {
"exe.png": "pWwo9nBLtEss/UJ173zHa6/RpySUyz/XMdNhWc6aRIvwwHMO6a+fLmu2K6TbvO3Jbg4VYL2Af4yhHPyhH3ZeTw==",
"datatables.min.css": "d5IZxd9tksyYd6/G+5l9twTq5Mfu3mpQBG1Pdp0092vmClzUiGB00yI3Vqz4o3ib3lHpXlu0MgJts5QBo52PVA==",
"json.png": "nE6ROpXE5iovHyd5oh8cnA4ozTa5bZjn1A6b+10b1Hb59O1NcMdcrv8Rqge3CAtSqJDKnrYbMChCT1j48yMwQw==",
"img.png": "bknBlmIfSb9qv9/lSaJ2idn2a8bDyvJ2pATj4oOpehRlCdXlWYOyb2jN3wV1QGHFoqyxNqOv5MfCpI0tbqkicg==",
"ifr.png": "rI5YJypmz1QcULRf9UaOYSqV4tPUSxUdLAycoYzCwywt4Pw4eWzBg9SUr769VyIimoiIyJR+aNuoIA4p5WO2fQ==",
"cookie_read.png": "mdXCeuNFPvshSwIXAJLoR1xFjXb+K2Mgu47Q1fnUAO8j1N2c/uJuE8sGuBHHbS8HOyr/CbOC6Uf3zsm9KvAs8Q==",
"d3.v5.min.js": "FHsFVKQ/T1KWJDGSbrUhTJyS1ph3eRrxI228ND0EGaEp6v4a/vGwPWd3Dtd/+9cI7ccofZvl/wulICEurHN1pg==",
"tree.js": "JeCMrFdQDrSYAXaJZE/tCOnfusbQI68rzFhyo0ojBCHt2FAs/DDBdYwCpkFNZ7J+n05NpfbegrrKVqd06PCNXA==",
"video.png": "gJtmkfr8I1Kw43pYEKjg6CAjgmhl1vIBKBQ3ZkxCu3wvxQm+6kf93iLrrFiY2WuiXzxEn2Leu52GJzmVN5id0g==",
"stats.css": "/kY943FwWBTne4IIyf7iBROSfbGd82TeBicEXqKkRwawMVRIvM/Pk5MRa7okUyGIxaDjFQGmV/U1vy+PhN6Jbw==",
"generic.js": "c/p+6Dk2kcwd9T9kf/IfoCX/ZU+VbtlUGYBo3qNSzwoUYC1soWwdIwM5rFxwxz9a1tORc/Wu0EFCPRw4ZwbqkQ==",
"html.png": "T7pZrb8MMDsA/JV/51hu+TOglTqlxySuEVY0rpDjTuAEyhzk2v+W4kYrj7vX+Tp3n2d2lvVD08PwhCG62Yfbzg==",
"down_left.jpg": "UwHkJaZGayY1LewuFM3bJHQCUPG1vYyrVeiGG5mCM9MD9FtAhdbD4hBY3JZNDWv93CXeEAbxL1kqEeHTKnyquQ==",
"insecure.svg": "iyoot+eMuRI7SITBdjslYS2WWFntz9VGi0doPoZBi/ZGPGDhm/Sd8SaJPiNCSKht/6dYPqgb90LQJ6a4YrhcFA==",
"font.png": "RwoQkj9dT9SLUL2F7cAA16Nat9t2hDb58eQlHF9ThUar829p0INUXG+5XuDaFOC8SsmCZK5vw2f+YAQ6mLC1Qw==",
"favicon.ico": "KOmrfwRbOQqhhwSeBkNpMRAxSVMmmLg+2kRMg9iSv7OWjE9spJc7x4MKB4AE/hi0knaV7UBVctAU6XZ7AC72ZA==",
"cookie_received.png": "EqL5fRFwjjXkSp242nacVFy7N8f1QAGJv4OIVDKQkDJQvq2MphwUnfLZUQvN3NMayHS/VTGQbgdQVjcOSQ2blA==",
"lookyloo.jpeg": "i6wBj8CsIM5YAQLEMQfhs3CNOSKkErF8AMqqM6ZygSwCyQgv9CU8xt94veMZhM/ufBWoz7kAXmR+yywmxsTxug==",
"down.jpg": "LHRHJ5yCaSjNcDfEoChGIfh7K5HrMYbaGn7EOlxgZ8GoLIwb0nFBkpoOMG9gMHA/pBX2skkXMukvKJC6P6FBGg==",
"index.css": "2hAsQwCClHQ7b6VthbKYIkUPam4Ef6wbSxa3+nK0UuqCHezvPMr3aqpz16gD0lyYop55VEd/dhzZJLA4WMAplQ==",
"up.jpg": "d1ljZJ9f5JekyM6RLFFH2Ua44j6neiQBdUIXOenRTjGppQr3JaeglpQIH6BjPCJL177+TH52U3UIRNS5YAyKIg==",
"bomb.svg": "Tro3+kCLzfBNBve2gPnsmXsl+tHUQVrFz77zfrWwnAuTraehZaoAfVJgGOYdG8zceXdGLEKzXVi3GdtEXw0sYQ==",
"css.png": "XDfV8fW5XRQlHT20rZn3d6LdIp2Dzk+mnZlicBv61iJGFMENLSM4SDgRcGb+x927AlI3lb6qv2C6tJAR2nDl5g==",
"empty.svg": "6tfMLNzDFV9P6t1rC2tDRQtOGzrxi/VtIBc8aV0jo4i3u+dn1fIe3/fySBFA6z13n+XjISF5bTRUNBsN3LWinQ==",
"datatables.min.js": "xlRU11IaDXTzgBMqyvSzQB3dqBbHatQaSVOUoPkxxNbc39qGxldo4nuAoK+Q5eO7Ldo/3XzuUTqhY9DudM3H6g==",
"cookie_in_url.png": "hs/oNPnrR2DkDX9Yp6Daug/QqpWJHemJE6lXpxNafjgOYooezp3DpbqKqADT7QcfcTxxUfe1iPDZJlHOrNMAcw==",
"suspicious.svg": "hUHBJBoQFgMkxgQDdQxRNIuBxKoT7Pllsm6KanBxy0ejZPpr1EAtyLn1zZuWKUY6EMpsHIiKMJmuN6OXgYgh6g==",
"capture.js": "XhWkFmPwm29Iyf034SS/OXZo+ulN2xo6S6AzdHh+hCBnmygO8dUzX1gsrW91utgxgsmHKjTzXPJCXsylNLw4uQ==",
"tree.css": "ma+WfBfjVZpKH9KDg+LayyBac2r95VgqG4jll75Xc1e0zwBXe2/ZxI6Y9AeGCNK5YvtcFNd6oH3c+2KxV8iT0A==",
"redirect.png": "PAjzlPV97rEFvH55mG1ZC9wRl98be3yMeX/nENuFkJcds6/AXgSR2ig/QyPULgobSnNgiYieLVWY/oqsgeywrQ==",
"secure.svg": "H8ni7t0d60nCJDVGuZpuxC+RBy/ipAjWT627D12HlZGg6LUmjSwPTQTUekm3UJupEP7TUkhXyq6WHc5gy7QBjg==",
"stats_graph.js": "0OEouA6NAxLG2wMd7D2vtGoMrXKna7My98Euc6ecyfdO4/6mIJS87vzISOS4zSZ8u4ehpa+p7E0nWhsXXE7H/Q==",
"wtf.png": "5iUj4m5G3tJN3wQvR1jD/hF4OKFrboVeuFejd+6ZUvdll3zjkLeewJQ+zptO9ckzktsMPC2+bKM3zM3CXXWoCw==",
"d3.v6.min.js": "0XfwGD1nxplHpehcSVI7lY+m/5L37PNHDt+DOc7aLFckwPXjnjeA1oeNbru7YeI4VLs9i+ADnnHEhP69C9CqTA==",
"javascript.png": "sQcLDBrB+fEEt3PPoOwFh0g/RVkhDNrhuBMo0WMzf9IKNnZusYx+J59k8HGkAHFGDbytDwe6Tq6LIVgg/B6nqw==",
"check.svg": "CRqUAM/yXxgJwpfg3TeoKD+CIqQj62lxqS3zeCmdPaV3dKftk4jk5Mqc1TGxL7i61X1sgV0/f+KJLEOKTw01ww==",
"error_screenshot.png": "IkUKnQ47PYYreukA7Byvx+5ACkcCvqk+jYD0GZoQznsD9qDPWrKAMZxlIku7G3Re19vehIlYawep/THcV/ruTA==",
"up_right.jpg": "OMmz+n+MxR34P8/fn5t4DkqKqdJRzQbXQ7fAi2lhkZIJGhVs2vIyY1f2hpYoBxDAX1OcYsSE2lqIR2vXNDGZsA==",
"bomb.xcf": "hDMWxjEZyOB+3SnXYiY03qhce8zu91XRKsbJptq/vsr5MLmNUtYvAdCuVcx8hxtMsyf6M061eDGggIJEZSeYkQ==",
"loader.gif": "ZZKD5vLSKBWKeUpa2KI9qheUJ49iTI/UULmVU/AX28fBfH00K3lLc2v5pVJZ4qXG1BbB13LTXzRKKU35H2XfNg==",
"generic.css": "y5crC022oxKIDs2Z2l3HSIwzmPtXNYd6N8ofJYgu1OsSAADO3qoZ1OZVrsdwn1e9wHK4Mvh6GpKoe+GcDzOmSQ=="
}
}

View File

@ -6,7 +6,6 @@
{% block scripts %} {% block scripts %}
{{ super() }} {{ super() }}
<script src='{{ url_for('static', filename='datatables.min.js') }}'></script>
<script type="text/javascript"> <script type="text/javascript">
$('#table').DataTable( { $('#table').DataTable( {
"order": [[ 1, "desc" ]], "order": [[ 1, "desc" ]],
@ -24,12 +23,6 @@
{% endblock %} {% endblock %}
{% block styles %}
{{ super() }}
<link rel="stylesheet" href="{{ url_for('static', filename='datatables.min.css') }}">
{% endblock %}
{% block content %} {% block content %}
<center> <center>
<h4>{{ body_hash }}</h4> <h4>{{ body_hash }}</h4>

View File

@ -6,7 +6,6 @@
{% block scripts %} {% block scripts %}
{{ super() }} {{ super() }}
<script src='{{ url_for('static', filename='datatables.min.js') }}'></script>
<script type="text/javascript"> <script type="text/javascript">
$('#table').DataTable( { $('#table').DataTable( {
"order": [[ 0, "desc" ]], "order": [[ 0, "desc" ]],
@ -17,11 +16,6 @@
</script> </script>
{% endblock %} {% endblock %}
{% block styles %}
{{ super() }}
<link rel="stylesheet" href="{{ url_for('static', filename='datatables.min.css') }}">
{% endblock %}
{% block content %} {% block content %}
<center> <center>

View File

@ -150,5 +150,7 @@
{% block scripts %} {% block scripts %}
{{ super() }} {{ super() }}
<script src='{{ url_for('static', filename='capture.js') }}'></script> <script src='{{ url_for('static', filename='capture.js') }}'
integrity="{{get_sri('static', 'capture.js')}}"
crossorigin="anonymous"></script>
{% endblock %} {% endblock %}

View File

@ -6,7 +6,6 @@
{% block scripts %} {% block scripts %}
{{ super() }} {{ super() }}
<script src='{{ url_for('static', filename='datatables.min.js') }}'></script>
<script type="text/javascript"> <script type="text/javascript">
$('#table').DataTable( { $('#table').DataTable( {
"order": [[ 1, "desc" ]], "order": [[ 1, "desc" ]],
@ -16,12 +15,6 @@
{% endblock %} {% endblock %}
{% block styles %}
{{ super() }}
<link rel="stylesheet" href="{{ url_for('static', filename='datatables.min.css') }}">
{% endblock %}
{% block content %} {% block content %}
<div class="table-responsive"> <div class="table-responsive">
<table id="table" class="table" style="width:96%"> <table id="table" class="table" style="width:96%">

View File

@ -6,7 +6,6 @@
{% block scripts %} {% block scripts %}
{{ super() }} {{ super() }}
<script src='{{ url_for('static', filename='datatables.min.js') }}'></script>
<script type="text/javascript"> <script type="text/javascript">
$('#table').DataTable( { $('#table').DataTable( {
"order": [[ 1, "desc" ]], "order": [[ 1, "desc" ]],
@ -22,12 +21,6 @@
{% endblock %} {% endblock %}
{% block styles %}
{{ super() }}
<link rel="stylesheet" href="{{ url_for('static', filename='datatables.min.css') }}">
{% endblock %}
{% block content %} {% block content %}
<center> <center>
<h2>{{ cookie_name }}</h2> <h2>{{ cookie_name }}</h2>

View File

@ -6,7 +6,6 @@
{% block scripts %} {% block scripts %}
{{ super() }} {{ super() }}
<script src='{{ url_for('static', filename='datatables.min.js') }}'></script>
<script type="text/javascript"> <script type="text/javascript">
$('#table').DataTable( { $('#table').DataTable( {
"order": [[ 1, "desc" ]], "order": [[ 1, "desc" ]],
@ -16,12 +15,6 @@
{% endblock %} {% endblock %}
{% block styles %}
{{ super() }}
<link rel="stylesheet" href="{{ url_for('static', filename='datatables.min.css') }}">
{% endblock %}
{% block content %} {% block content %}
<div class="table-responsive"> <div class="table-responsive">
<table id="table" class="table" style="width:96%"> <table id="table" class="table" style="width:96%">

View File

@ -6,7 +6,6 @@
{% block scripts %} {% block scripts %}
{{ super() }} {{ super() }}
<script src='{{ url_for('static', filename='datatables.min.js') }}'></script>
<script type="text/javascript"> <script type="text/javascript">
$('#table').DataTable( { $('#table').DataTable( {
"order": [[ 0, "desc" ]], "order": [[ 0, "desc" ]],
@ -26,15 +25,8 @@
window.opener.openTreeInNewTab(treeUUID); window.opener.openTreeInNewTab(treeUUID);
}; };
</script> </script>
{% endblock %} {% endblock %}
{% block styles %}
{{ super() }}
<link rel="stylesheet" href="{{ url_for('static', filename='datatables.min.css') }}">
{% endblock %}
{% block content %} {% block content %}
<center> <center>
<h4>{{ url }}</h4> <h4>{{ url }}</h4>

View File

@ -11,15 +11,11 @@
{% block title %}Details for {{ hostnode.name }} {% endblock %} {% block title %}Details for {{ hostnode.name }} {% endblock %}
{% block styles %}
{{ super() }}
<link rel="stylesheet" href="{{ url_for('static', filename='datatables.min.css') }}">
{% endblock %}
{% block scripts %} {% block scripts %}
{{ super() }} {{ super() }}
<script src='{{ url_for('static', filename='datatables.min.js') }}'></script> <script src='{{ url_for('static', filename='generic.js') }}'
<script src='{{ url_for('static', filename='generic.js') }}'></script> integrity="{{get_sri('static', 'generic.js')}}"
crossorigin="anonymous"></script>
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(() => { $(document).ready(() => {
$('table.table').DataTable( { $('table.table').DataTable( {

View File

@ -25,7 +25,6 @@
{% block scripts %} {% block scripts %}
{{ super() }} {{ super() }}
<script src='{{ url_for('static', filename='datatables.min.js') }}'></script>
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function () { $(document).ready(function () {
$('#table').DataTable( { $('#table').DataTable( {
@ -51,8 +50,9 @@ $(document).ready(function () {
{% block styles %} {% block styles %}
{{ super() }} {{ super() }}
<link rel="stylesheet" href="{{ url_for('static', filename='datatables.min.css') }}"> <link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}"
<link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}"> integrity="{{get_sri('static', 'index.css')}}"
crossorigin="anonymous">
{% endblock %} {% endblock %}

View File

@ -5,12 +5,19 @@
<!-- Required meta tags --> <!-- Required meta tags -->
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}"> <link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}"
integrity="{{get_sri('static', 'favicon.ico')}}"
crossorigin="anonymous">
{% block styles %} {% block styles %}
<!-- Bootstrap CSS --> <!-- Bootstrap CSS -->
{{ bootstrap.load_css() }} {{ bootstrap.load_css() }}
<link rel="stylesheet" href="{{ url_for('static', filename='generic.css') }}"> <link rel="stylesheet" href="{{ url_for('static', filename='generic.css') }}"
integrity="{{get_sri('static', 'generic.css')}}"
crossorigin="anonymous">
<link rel="stylesheet" href="{{ url_for('static', filename='datatables.min.css') }}"
integrity="{{get_sri('static', 'datatables.min.css')}}"
crossorigin="anonymous">
{% endblock %} {% endblock %}
<title>{% block title %}{% endblock%}</title> <title>{% block title %}{% endblock%}</title>
@ -28,6 +35,9 @@
{% block scripts %} {% block scripts %}
<!-- Optional JavaScript --> <!-- Optional JavaScript -->
{{ bootstrap.load_js() }} {{ bootstrap.load_js() }}
<script src='{{ url_for('static', filename='datatables.min.js') }}'
integrity="{{get_sri('static', 'datatables.min.js')}}"
crossorigin="anonymous"></script>
{% endblock %} {% endblock %}
</body> </body>
</html> </html>

View File

@ -9,7 +9,6 @@
{% block scripts %} {% block scripts %}
{{ super() }} {{ super() }}
<script src='{{ url_for('static', filename='datatables.min.js') }}'></script>
<script type="text/javascript"> <script type="text/javascript">
$('#table').DataTable( { $('#table').DataTable( {
"order": [[ 2, "desc" ]], "order": [[ 2, "desc" ]],
@ -26,12 +25,6 @@
{% endblock %} {% endblock %}
{% block styles %}
{{ super() }}
<link rel="stylesheet" href="{{ url_for('static', filename='datatables.min.css') }}">
{% endblock %}
{% block content %} {% block content %}
<div class="table-responsive"> <div class="table-responsive">
<table id="table" class="table" style="width:96%"> <table id="table" class="table" style="width:96%">

View File

@ -61,5 +61,7 @@
{% block scripts %} {% block scripts %}
{{ super() }} {{ super() }}
<script src='{{ url_for('static', filename='capture.js') }}'></script> <script src='{{ url_for('static', filename='capture.js') }}'
integrity="{{get_sri('static', 'capture.js')}}"
crossorigin="anonymous"></script>
{% endblock %} {% endblock %}

View File

@ -79,5 +79,7 @@
{% block styles %} {% block styles %}
{{ super() }} {{ super() }}
<link rel="stylesheet" href="{{ url_for('static', filename='stats.css') }}"> <link rel="stylesheet" href="{{ url_for('static', filename='stats.css') }}"
integrity="{{get_sri('static', 'stats.css')}}"
crossorigin="anonymous">
{% endblock %} {% endblock %}

View File

@ -27,8 +27,12 @@
{% block scripts %} {% block scripts %}
{{ super() }} {{ super() }}
<script src='{{ url_for('static', filename='d3.v6.min.js') }}'></script> <script src='{{ url_for('static', filename='d3.v6.min.js') }}'
<script src='{{ url_for('static', filename='tree.js') }}'></script> integrity="{{get_sri('static', 'd3.v6.min.js')}}"
crossorigin="anonymous"></script>
<script src='{{ url_for('static', filename='tree.js') }}'
integrity="{{get_sri('static', 'tree.js')}}"
crossorigin="anonymous"></script>
<script> <script>
$('#modulesModal').on('show.bs.modal', function(e) { $('#modulesModal').on('show.bs.modal', function(e) {

View File

@ -6,7 +6,6 @@
{% block scripts %} {% block scripts %}
{{ super() }} {{ super() }}
<script src='{{ url_for('static', filename='datatables.min.js') }}'></script>
<script type="text/javascript"> <script type="text/javascript">
$('#table').DataTable( { $('#table').DataTable( {
"order": [[ 0, "desc" ]], "order": [[ 0, "desc" ]],
@ -29,12 +28,6 @@
{% endblock %} {% endblock %}
{% block styles %}
{{ super() }}
<link rel="stylesheet" href="{{ url_for('static', filename='datatables.min.css') }}">
{% endblock %}
{% block content %} {% block content %}
<center> <center>
<h4>{{ url }}</h4> <h4>{{ url }}</h4>