Skip to content

Commit

Permalink
fix: Support rendering non-icon favicons
Browse files Browse the repository at this point in the history
  • Loading branch information
Rafiot committed Feb 20, 2024
1 parent dcbec2e commit 104129b
Show file tree
Hide file tree
Showing 7 changed files with 30 additions and 7 deletions.
2 changes: 1 addition & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ urllib3 = [
{version = "^2.0.7", python = ">=3.10"}
]
pypdns = "^2.2.2"
python-magic = "^0.4.27"

[tool.poetry.group.dev.dependencies]
mypy = "^1.8.0"
Expand Down
10 changes: 8 additions & 2 deletions website/web/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import time

import filetype # type: ignore[import-untyped]
import magic

from datetime import date, datetime, timedelta, timezone
from importlib.metadata import version
Expand Down Expand Up @@ -838,18 +839,20 @@ def mark_as_legitimate(tree_uuid: str) -> Response:
def tree_favicons(tree_uuid: str) -> str:
favicons = []
favicons_zip = lookyloo.get_potential_favicons(tree_uuid, all_favicons=True, for_datauri=False)
f = magic.Magic(mime=True)
with ZipFile(favicons_zip, 'r') as myzip:
for name in myzip.namelist():
if not name.endswith('.ico'):
continue
favicon = myzip.read(name)
if not favicon:
continue
mimetype = f.from_buffer(favicon)
favicon_sha512 = hashlib.sha512(favicon).hexdigest()
frequency = lookyloo.indexing.favicon_frequency(favicon_sha512)
number_captures = lookyloo.indexing.favicon_number_captures(favicon_sha512)
b64_favicon = base64.b64encode(favicon).decode()
favicons.append((favicon_sha512, frequency, number_captures, b64_favicon))
favicons.append((favicon_sha512, frequency, number_captures, mimetype, b64_favicon))
return render_template('tree_favicons.html', tree_uuid=tree_uuid, favicons=favicons)


Expand Down Expand Up @@ -1243,11 +1246,14 @@ def hhh_detail(hhh: str) -> str:
def favicon_detail(favicon_sha512: str) -> str:
captures, favicon = lookyloo.get_favicon_investigator(favicon_sha512.strip())
if favicon:
f = magic.Magic(mime=True)
mimetype = f.from_buffer(favicon)
b64_favicon = base64.b64encode(favicon).decode()
else:
b64_favicon = ''
mimetype = ''
return render_template('favicon_details.html', favicon_sha512=favicon_sha512,
captures=captures, b64_favicon=b64_favicon)
captures=captures, mimetype=mimetype, b64_favicon=b64_favicon)


@app.route('/body_hashes/<string:body_hash>', methods=['GET'])
Expand Down
2 changes: 1 addition & 1 deletion website/web/sri.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"favicon.ico": "KOmrfwRbOQqhhwSeBkNpMRAxSVMmmLg+2kRMg9iSv7OWjE9spJc7x4MKB4AE/hi0knaV7UBVctAU6XZ7AC72ZA==",
"font.png": "RwoQkj9dT9SLUL2F7cAA16Nat9t2hDb58eQlHF9ThUar829p0INUXG+5XuDaFOC8SsmCZK5vw2f+YAQ6mLC1Qw==",
"generic.css": "Sh/BcxFMLYYaLdCluVt9efGvJ9CF5d+YJ7lkL2M24PRGu8VZHI9lJiUlFObIocjQgwss3Ve2U5cUAE5WiAdpQQ==",
"generic.js": "UmFl4fHmB/UjMdUuYdFy9BfzQlJTyeImNHCFyBO4SdLxBCwCGxkF3NQvel1PKqW8JTnoPlPpq/n9d+vCfPeegA==",
"generic.js": "h2tLqpn8r1mZ/5FqiBDK6Er6mY5MdRuyir2mS9piT8VUUco2daxdKWSkiEtIsH2Ok+/W+NJb95A1ob5J/6sW4A==",
"html.png": "T7pZrb8MMDsA/JV/51hu+TOglTqlxySuEVY0rpDjTuAEyhzk2v+W4kYrj7vX+Tp3n2d2lvVD08PwhCG62Yfbzg==",
"ifr.png": "rI5YJypmz1QcULRf9UaOYSqV4tPUSxUdLAycoYzCwywt4Pw4eWzBg9SUr769VyIimoiIyJR+aNuoIA4p5WO2fQ==",
"img.png": "bknBlmIfSb9qv9/lSaJ2idn2a8bDyvJ2pATj4oOpehRlCdXlWYOyb2jN3wV1QGHFoqyxNqOv5MfCpI0tbqkicg==",
Expand Down
15 changes: 15 additions & 0 deletions website/web/static/generic.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,18 @@ function checkAllBoxes(name) {
checkboxs[i].checked = !checkboxs[i].checked;
}
}

// Parameters:
// contentType: The content type of your file.
// its like application/pdf or application/msword or image/jpeg or
// image/png and so on
// base64Data: Its your actual base64 data
// fileName: Its the file name of the file which will be downloaded.
// Source: https://stackoverflow.com/questions/14011021/how-to-download-a-base64-encoded-image
function downloadBase64File(contentType, base64Data, fileName) {
const linkSource = `data:${contentType};base64,${base64Data}`;
const downloadLink = document.createElement("a");
downloadLink.href = linkSource;
downloadLink.download = fileName;
downloadLink.click();
}
2 changes: 1 addition & 1 deletion website/web/templates/favicon_details.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
</script>

<center>
<img src="data:image/ico;base64,{{ b64_favicon }}" style="width:64px;height:64px;"/>
<img src="data:{{mimetype}};base64,{{ b64_favicon }}" style="width:64px;height:64px;"/>
</center>
<table id="faviconDetailsTable" class="table table-striped" style="width:100%">
<thead>
Expand Down
5 changes: 3 additions & 2 deletions website/web/templates/tree_favicons.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@
</tr>
</thead>
<tbody>
{% for favicon_sha512, freq, number_captures, b64_favicon in favicons %}
{% for favicon_sha512, freq, number_captures, mimetype, b64_favicon in favicons %}
<tr>
<td>
<a href="#faviconDetailsModal" data-remote="{{ url_for('favicon_detail', favicon_sha512=favicon_sha512) }}"
data-bs-toggle="modal" data-bs-target="#faviconDetailsModal" role="button">
<img src="data:image/ico;base64,{{ b64_favicon }}" style="width:32px;height:32px;"/>
<img src="data:{{mimetype}};base64,{{ b64_favicon }}" style="width:32px;height:32px;"/>
</a>
<button type="button" class="btn btn-light" onclick="downloadBase64File('{{mimetype}}', '{{b64_favicon}}', 'favicon.ico')">Download favicon</button>
</td>
<td>{{ freq }}</td>
<td>{{ number_captures }}</td>
Expand Down

0 comments on commit 104129b

Please sign in to comment.