Change command, update readme and validate chosen algorithm

Gonçalo Valério 1 year ago
parent 0d8f365fda
commit ed10d7c909
Signed by: dethos
GPG Key ID: DF557F2BDCC2445E

@ -1,25 +1,100 @@
A small tool and library to generate the hashes of inline content that needs to be whitelisted when serving an HTML document
with a `Content-Security-Policy <>`_ (as the name indicates,
using ``unsafe-inline`` is not recommended.)
You provide the HTML content (directly or through a file path or URL) then ``inlinehashes`` will parse the document and provide
you with a list of elements that need to be explicitly added to the CSP header/tag.
The tool can be specially useful for scenarios where you use/include external software solutions in your website or application
(such as a 3rd party CMS), since it will allow you to detect changes after updates and edit you CSP accordingly.
*Quick note: Always verify the content you are whitelisting and be careful when fetching live website data, since any XSS
code will be included in the results.*
**At the moment this package is still in a very early stage, so it still doesn't detect all possible items and the current API
might change with future releases.**
Inline content that is currently detected:
* ``<script></script>`` tags
* ``<style></style>`` tags
Using pip you just need to ``pip install inlinehashes``
The package can be used through 2 different ways, either by using the CLI interface or programmatically in your python project.
Bellow you can find a quick summary of the available functionality.
CLI app
This is the available functionality:
.. code::
usage: inlinehashes [-h] [-a {sha256,sha384,sha512}] [-f] [-o OUTPUT] source
positional arguments:
source URL or local HTML file to check
optional arguments:
-h, --help show this help message and exit
-a {sha256,sha384,sha512}, --alg {sha256,sha384,sha512}
Hash algorithm to use (default: sha256)
-f, --full Include full content in the output
-o OUTPUT, --output OUTPUT
Store output in a file.
Here is an example of the output:
.. code::
$inlinehashes -a sha384
"content": "\n html {\n height: 100%;\n }\n ",
"hash": "sha384-Ku20lQH5qbr4EDPzXD2rf25rEHJNswNYRUNMPjYl7jCe0eHJYDe0gFdQpnKkFUTv"
Here is the same example, but using the python shell:
.. code:: python
>>> import requests
>>> import inlinehashes
>>> content = requests.get("").text
>>> inlines = inlinehashes.parse(content)
>>> inlines
html {
height: 100%;
>>> first = inlines[0]
>>> first.short_content
'\n html {\n height: 100%;\n }\n '
>>> first.sha256
>>> first.sha384
>>> first.sha512
>>> first.content
'\n html {\n height: 100%;\n }\n body {\n background-image: url("data:image/png;base64,iVBORw0KGgoAAAANS..."

@ -35,10 +35,17 @@ def run_cli() -> None:
parser = argparse.ArgumentParser()
parser.add_argument("source", help="URL or local HTML file to check")
"-a", "--alg", help="Hash algorithm to use (default: sha256)", default="sha256"
help="Hash algorithm to use (default: sha256)",
choices=["sha256", "sha384", "sha512"],
"-f", "--full", help="Include full content in the output", action="store_true"
help="Include full content in the output",
parser.add_argument("-o", "--output", help="Store output in a file.")
args = parser.parse_args()

@ -55,6 +55,12 @@ class Inline:
h_b64 = base64.b64encode(h.digest()).decode("utf8")
return f"sha512-{h_b64}"
def __repr__(self) -> str:
return f"Inline(content='{self.content}')"
def __str__(self) -> str:
return f"Inline(content='{self.short_content}...')"
def parse(content: str, target: str = "all") -> List[Inline]:
"""Parses an HTML document and extracts."""

@ -29,7 +29,7 @@ black = "^22.1.0"
mypy = "^0.940"
cli = ""
inlinehashes = ""
requires = ["poetry-core>=1.0.0"]