evadex 0.1.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- evadex-0.1.4/LICENSE +21 -0
- evadex-0.1.4/PKG-INFO +444 -0
- evadex-0.1.4/README.md +405 -0
- evadex-0.1.4/pyproject.toml +60 -0
- evadex-0.1.4/setup.cfg +4 -0
- evadex-0.1.4/src/evadex/__init__.py +5 -0
- evadex-0.1.4/src/evadex/__main__.py +3 -0
- evadex-0.1.4/src/evadex/adapters/__init__.py +0 -0
- evadex-0.1.4/src/evadex/adapters/base.py +49 -0
- evadex-0.1.4/src/evadex/adapters/dlpscan/__init__.py +0 -0
- evadex-0.1.4/src/evadex/adapters/dlpscan/adapter.py +69 -0
- evadex-0.1.4/src/evadex/adapters/dlpscan/client.py +74 -0
- evadex-0.1.4/src/evadex/adapters/dlpscan/file_builder.py +112 -0
- evadex-0.1.4/src/evadex/adapters/dlpscan_cli/__init__.py +0 -0
- evadex-0.1.4/src/evadex/adapters/dlpscan_cli/adapter.py +59 -0
- evadex-0.1.4/src/evadex/cli/__init__.py +0 -0
- evadex-0.1.4/src/evadex/cli/app.py +15 -0
- evadex-0.1.4/src/evadex/cli/commands/__init__.py +0 -0
- evadex-0.1.4/src/evadex/cli/commands/scan.py +134 -0
- evadex-0.1.4/src/evadex/core/__init__.py +0 -0
- evadex-0.1.4/src/evadex/core/engine.py +79 -0
- evadex-0.1.4/src/evadex/core/registry.py +46 -0
- evadex-0.1.4/src/evadex/core/result.py +99 -0
- evadex-0.1.4/src/evadex/payloads/__init__.py +0 -0
- evadex-0.1.4/src/evadex/payloads/builtins.py +91 -0
- evadex-0.1.4/src/evadex/reporters/__init__.py +0 -0
- evadex-0.1.4/src/evadex/reporters/base.py +12 -0
- evadex-0.1.4/src/evadex/reporters/html_reporter.py +135 -0
- evadex-0.1.4/src/evadex/reporters/json_reporter.py +32 -0
- evadex-0.1.4/src/evadex/variants/__init__.py +0 -0
- evadex-0.1.4/src/evadex/variants/base.py +20 -0
- evadex-0.1.4/src/evadex/variants/delimiter.py +55 -0
- evadex-0.1.4/src/evadex/variants/encoding.py +154 -0
- evadex-0.1.4/src/evadex/variants/leetspeak.py +36 -0
- evadex-0.1.4/src/evadex/variants/regional_digits.py +71 -0
- evadex-0.1.4/src/evadex/variants/splitting.py +55 -0
- evadex-0.1.4/src/evadex/variants/structural.py +35 -0
- evadex-0.1.4/src/evadex/variants/unicode_encoding.py +104 -0
- evadex-0.1.4/src/evadex.egg-info/PKG-INFO +444 -0
- evadex-0.1.4/src/evadex.egg-info/SOURCES.txt +42 -0
- evadex-0.1.4/src/evadex.egg-info/dependency_links.txt +1 -0
- evadex-0.1.4/src/evadex.egg-info/entry_points.txt +2 -0
- evadex-0.1.4/src/evadex.egg-info/requires.txt +12 -0
- evadex-0.1.4/src/evadex.egg-info/top_level.txt +1 -0
evadex-0.1.4/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 evadex contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
evadex-0.1.4/PKG-INFO
ADDED
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: evadex
|
|
3
|
+
Version: 0.1.4
|
|
4
|
+
Summary: Comprehensive DLP evasion test suite — scanner-agnostic, file-aware
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
Project-URL: Homepage, https://github.com/tbustenk/evadex
|
|
7
|
+
Project-URL: Repository, https://github.com/tbustenk/evadex
|
|
8
|
+
Project-URL: Bug Tracker, https://github.com/tbustenk/evadex/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/tbustenk/evadex/blob/main/CHANGELOG.md
|
|
10
|
+
Keywords: dlp,security,evasion,testing,compliance,pci-dss,scanner
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Information Technology
|
|
14
|
+
Classifier: Intended Audience :: System Administrators
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Security
|
|
22
|
+
Classifier: Topic :: System :: Systems Administration
|
|
23
|
+
Classifier: Typing :: Typed
|
|
24
|
+
Requires-Python: >=3.10
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
Requires-Dist: click>=8.1
|
|
28
|
+
Requires-Dist: httpx>=0.27
|
|
29
|
+
Requires-Dist: python-docx>=1.1
|
|
30
|
+
Requires-Dist: fpdf2>=2.7.9
|
|
31
|
+
Requires-Dist: openpyxl>=3.1
|
|
32
|
+
Requires-Dist: jinja2>=3.1
|
|
33
|
+
Requires-Dist: rich>=13.0
|
|
34
|
+
Provides-Extra: dev
|
|
35
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
36
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
|
|
37
|
+
Requires-Dist: respx>=0.21; extra == "dev"
|
|
38
|
+
Dynamic: license-file
|
|
39
|
+
|
|
40
|
+
# evadex
|
|
41
|
+
|
|
42
|
+
A scanner-agnostic DLP evasion test suite. evadex generates hundreds of obfuscated variants of known-sensitive values and submits them to your DLP scanner to find what slips through — including through file extraction pipelines (DOCX, PDF, XLSX), not just plain-text API calls.
|
|
43
|
+
|
|
44
|
+
Built and tested with [dlpscan](https://github.com/oxide11/dlpscan); works with any scanner via its adapter interface. Detection rates vary by scanner, configuration, and ruleset — run evadex against your own deployment to see your results.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## What it does
|
|
49
|
+
|
|
50
|
+
evadex takes a sensitive value (a credit card number, SSN, AWS key, etc.), runs it through every evasion technique it knows — unicode tricks, delimiter manipulation, encoding variants, regional digit scripts, homoglyphs, and more — and records which variants your scanner catches and which it misses.
|
|
51
|
+
|
|
52
|
+
**Evasion categories:**
|
|
53
|
+
|
|
54
|
+
| Generator | Techniques |
|
|
55
|
+
|---|---|
|
|
56
|
+
| `unicode_encoding` | Zero-width chars, fullwidth digits, homoglyphs, NFD/NFC/NFKC/NFKD normalization, HTML entities (decimal + hex), URL encoding (full, digits-only, mixed) |
|
|
57
|
+
| `delimiter` | Space, hyphen, dot, slash, tab, newline, mixed, doubled, none |
|
|
58
|
+
| `splitting` | Mid-value line break, HTML/CSS comment injection, prefix/suffix noise, JSON field split, whitespace padding, XML wrapping |
|
|
59
|
+
| `leetspeak` | Minimal, moderate, and aggressive substitution tiers |
|
|
60
|
+
| `regional_digits` | Arabic-Indic, Extended Arabic-Indic, Devanagari, Bengali, Thai, Myanmar, Khmer, Mongolian, NKo, Tibetan — plus mixed-script variants |
|
|
61
|
+
| `structural` | Left/right padding (spaces + zeros), noise embedding, partial values, case variation, repeated value |
|
|
62
|
+
| `encoding` | Base64 (standard, URL-safe, no-padding, MIME line-breaks, partial, double), ROT13, full/group reversal, double URL encoding, mixed NFD/NFC/NFKD normalization |
|
|
63
|
+
|
|
64
|
+
**Submission strategies** (for dlpscan-cli adapter):
|
|
65
|
+
|
|
66
|
+
Each variant is tested four ways by default: as plain text, embedded in a DOCX, embedded in a PDF, and embedded in an XLSX. This exercises your scanner's file extraction pipeline, not just its regex layer.
|
|
67
|
+
|
|
68
|
+
**Built-in test payloads:**
|
|
69
|
+
|
|
70
|
+
Payloads are classified as **structured** or **heuristic** — see [Structured vs heuristic categories](#structured-vs-heuristic-categories) below.
|
|
71
|
+
|
|
72
|
+
| Label | Value | Category type |
|
|
73
|
+
|---|---|---|
|
|
74
|
+
| Visa 16-digit | `4532015112830366` | structured |
|
|
75
|
+
| Amex 15-digit | `378282246310005` | structured |
|
|
76
|
+
| Mastercard 16-digit | `5105105105105100` | structured |
|
|
77
|
+
| US SSN | `123-45-6789` | structured |
|
|
78
|
+
| Canada SIN | `046 454 286` | structured |
|
|
79
|
+
| UK IBAN | `GB82WEST12345698765432` | structured |
|
|
80
|
+
| Email address | `test.user@example.com` | structured |
|
|
81
|
+
| US phone number | `+1-555-867-5309` | structured |
|
|
82
|
+
| AWS Access Key ID | `AKIAIOSFODNN7EXAMPLE` | heuristic |
|
|
83
|
+
| Sample JWT | *(compact JWT string)* | heuristic |
|
|
84
|
+
|
|
85
|
+
Heuristic payloads are excluded from the default scan. Use `--include-heuristic` to include them.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Structured vs heuristic categories
|
|
90
|
+
|
|
91
|
+
evadex classifies its built-in payload categories into two groups:
|
|
92
|
+
|
|
93
|
+
**Structured** — formats with well-defined, mathematically or syntactically validatable patterns. DLP scanners typically enforce these patterns precisely (e.g., Luhn check on credit cards, fixed-length digit groups for SSN/SIN, checksum-verified IBAN). Evasion results in this group reflect meaningful signal: a variant that evades detection is a real gap in coverage.
|
|
94
|
+
|
|
95
|
+
Categories: `credit_card`, `ssn`, `sin`, `iban`, `email`, `phone`
|
|
96
|
+
|
|
97
|
+
**Heuristic** — formats where detection relies on fixed prefixes, high-entropy pattern matching, or loosely defined structure. DLP rules for these categories vary widely between scanners and configurations, and a "fail" result may simply reflect that the scanner never had a strong rule for that specific format variant — not that a real exfiltration path was found.
|
|
98
|
+
|
|
99
|
+
Categories: `aws_key`, `jwt`
|
|
100
|
+
|
|
101
|
+
Heuristic categories are excluded from the default scan to avoid misleading results. Include them with:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
evadex scan --tool dlpscan-cli --include-heuristic
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
A warning is printed to stderr whenever `--include-heuristic` is active reminding you to interpret those results with caution.
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Installation
|
|
112
|
+
|
|
113
|
+
Requires Python 3.10+.
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
pip install evadex
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Or install from source:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
git clone https://github.com/tbustenk/evadex
|
|
123
|
+
cd evadex
|
|
124
|
+
pip install -e ".[dev]"
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Quick start
|
|
130
|
+
|
|
131
|
+
Run the full built-in suite against dlpscan (text strategy):
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
evadex scan --tool dlpscan-cli --strategy text
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Test a single value:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
evadex scan --tool dlpscan-cli --input "4532015112830366" --strategy text
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Test with all file strategies (slower — exercises DOCX/PDF/XLSX extraction):
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
evadex scan --tool dlpscan-cli --input "4532015112830366"
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Generate an HTML report:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
evadex scan --tool dlpscan-cli --strategy text --format html -o report.html
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Example output
|
|
158
|
+
|
|
159
|
+
### Terminal summary
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
Running evadex scan against dlpscan-cli at http://localhost:8080...
|
|
163
|
+
Done. 590 tests — N detected, N evaded
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Detection rates depend on your scanner, its version, and how it's configured.
|
|
167
|
+
|
|
168
|
+
### JSON output (`--format json`, default)
|
|
169
|
+
|
|
170
|
+
```json
|
|
171
|
+
{
|
|
172
|
+
"meta": {
|
|
173
|
+
"timestamp": "2026-04-01T22:01:36.172424+00:00",
|
|
174
|
+
"total": 590,
|
|
175
|
+
"pass": 0,
|
|
176
|
+
"fail": 0,
|
|
177
|
+
"error": 0,
|
|
178
|
+
"pass_rate": 0.0,
|
|
179
|
+
"summary_by_category": {
|
|
180
|
+
"credit_card": { "pass": 0, "fail": 0, "error": 0 },
|
|
181
|
+
"ssn": { "pass": 0, "fail": 0, "error": 0 },
|
|
182
|
+
"sin": { "pass": 0, "fail": 0, "error": 0 },
|
|
183
|
+
"iban": { "pass": 0, "fail": 0, "error": 0 },
|
|
184
|
+
"aws_key": { "pass": 0, "fail": 0, "error": 0 },
|
|
185
|
+
"jwt": { "pass": 0, "fail": 0, "error": 0 },
|
|
186
|
+
"email": { "pass": 0, "fail": 0, "error": 0 },
|
|
187
|
+
"phone": { "pass": 0, "fail": 0, "error": 0 }
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
"results": [
|
|
191
|
+
{
|
|
192
|
+
"payload": {
|
|
193
|
+
"value": "5105105105105100",
|
|
194
|
+
"category": "credit_card",
|
|
195
|
+
"category_type": "structured",
|
|
196
|
+
"label": "Mastercard 16-digit"
|
|
197
|
+
},
|
|
198
|
+
"variant": {
|
|
199
|
+
"value": "5105105105105100",
|
|
200
|
+
"generator": "delimiter",
|
|
201
|
+
"technique": "no_delimiter",
|
|
202
|
+
"transform_name": "All delimiters removed",
|
|
203
|
+
"strategy": "text"
|
|
204
|
+
},
|
|
205
|
+
"detected": true,
|
|
206
|
+
"severity": "pass",
|
|
207
|
+
"duration_ms": 371.01,
|
|
208
|
+
"error": null
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
"payload": {
|
|
212
|
+
"value": "046 454 286",
|
|
213
|
+
"category": "sin",
|
|
214
|
+
"category_type": "structured",
|
|
215
|
+
"label": "Canada SIN"
|
|
216
|
+
},
|
|
217
|
+
"variant": {
|
|
218
|
+
"value": "Ο4б 4Ƽ4 ΚȢб",
|
|
219
|
+
"generator": "unicode_encoding",
|
|
220
|
+
"technique": "homoglyph_substitution",
|
|
221
|
+
"transform_name": "Visually similar Cyrillic/Greek characters substituted",
|
|
222
|
+
"strategy": "text"
|
|
223
|
+
},
|
|
224
|
+
"detected": false,
|
|
225
|
+
"severity": "fail",
|
|
226
|
+
"duration_ms": 378.57,
|
|
227
|
+
"error": null
|
|
228
|
+
}
|
|
229
|
+
]
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
**Severity values:**
|
|
234
|
+
|
|
235
|
+
| Value | Meaning |
|
|
236
|
+
|---|---|
|
|
237
|
+
| `pass` | Scanner detected the variant (good) |
|
|
238
|
+
| `fail` | Scanner missed the variant — evasion succeeded |
|
|
239
|
+
| `error` | Adapter error (network, timeout, etc.) |
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## CLI reference
|
|
244
|
+
|
|
245
|
+
```
|
|
246
|
+
evadex scan [OPTIONS]
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
| Flag | Default | Description |
|
|
250
|
+
|---|---|---|
|
|
251
|
+
| `--tool`, `-t` | `dlpscan-cli` | Adapter name to use |
|
|
252
|
+
| `--input`, `-i` | *(all built-ins)* | Single value to test. If omitted, runs all 8 structured built-in payloads (add `--include-heuristic` for all 10). Category is auto-detected (Luhn check, regex patterns for SSN/IBAN/AWS/JWT/email/phone). |
|
|
253
|
+
| `--format`, `-f` | `json` | Output format: `json` or `html` |
|
|
254
|
+
| `--output`, `-o` | stdout | Write report to file instead of stdout |
|
|
255
|
+
| `--strategy` | all four | Submission strategy: `text`, `docx`, `pdf`, `xlsx`. Repeat the flag for multiple. Omit to run all four. |
|
|
256
|
+
| `--concurrency` | `5` | Max concurrent requests |
|
|
257
|
+
| `--timeout` | `30.0` | Request timeout in seconds |
|
|
258
|
+
| `--url` | `http://localhost:8080` | Base URL (for HTTP-based adapters) |
|
|
259
|
+
| `--api-key` | *(env: `EVADEX_API_KEY`)* | API key passed as `Authorization: Bearer` |
|
|
260
|
+
| `--category` | *(all structured)* | Filter built-in payloads by category. Repeat for multiple. Values: `credit_card`, `ssn`, `sin`, `iban`, `aws_key`, `jwt`, `email`, `phone` |
|
|
261
|
+
| `--variant-group` | *(all)* | Limit to specific generator(s). Repeat for multiple. Values: `unicode_encoding`, `delimiter`, `splitting`, `leetspeak`, `regional_digits`, `structural`, `encoding` |
|
|
262
|
+
| `--include-heuristic` | off | Also run heuristic categories (`jwt`, `aws_key`). A warning is printed when enabled — see [Structured vs heuristic categories](#structured-vs-heuristic-categories). |
|
|
263
|
+
|
|
264
|
+
### Examples
|
|
265
|
+
|
|
266
|
+
```bash
|
|
267
|
+
# Only test credit card payloads
|
|
268
|
+
evadex scan --tool dlpscan-cli --strategy text --category credit_card
|
|
269
|
+
|
|
270
|
+
# Only run unicode evasion techniques
|
|
271
|
+
evadex scan --tool dlpscan-cli --strategy text --variant-group unicode_encoding
|
|
272
|
+
|
|
273
|
+
# Only run unicode + delimiter techniques on SSN and IBAN
|
|
274
|
+
evadex scan --tool dlpscan-cli --strategy text \
|
|
275
|
+
--category ssn --category iban \
|
|
276
|
+
--variant-group unicode_encoding --variant-group delimiter
|
|
277
|
+
|
|
278
|
+
# Test a custom value (category auto-detected)
|
|
279
|
+
evadex scan --tool dlpscan-cli --input "AKIAIOSFODNN7EXAMPLE" --strategy text
|
|
280
|
+
|
|
281
|
+
# File strategy only — test DOCX extraction pipeline
|
|
282
|
+
evadex scan --tool dlpscan-cli --input "4532015112830366" --strategy docx
|
|
283
|
+
|
|
284
|
+
# Save HTML report
|
|
285
|
+
evadex scan --tool dlpscan-cli --strategy text --format html -o report.html
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## Adapters
|
|
291
|
+
|
|
292
|
+
### Built-in: `dlpscan-cli`
|
|
293
|
+
|
|
294
|
+
Invokes the [dlpscan](https://github.com/oxide11/dlpscan) CLI directly as a subprocess. evadex was built and tested with dlpscan as the reference scanner. Requires `dlpscan` to be installed and on `PATH`.
|
|
295
|
+
|
|
296
|
+
```bash
|
|
297
|
+
evadex scan --tool dlpscan-cli
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
For file strategies, evadex builds the document in memory and writes it to a temp file, runs `dlpscan <file> -f json`, then deletes the temp file. File extraction support in dlpscan requires `pip install dlpscan[office]`.
|
|
301
|
+
|
|
302
|
+
### Built-in: `dlpscan`
|
|
303
|
+
|
|
304
|
+
Generic HTTP adapter for any DLP tool that exposes a REST API. Sends plain text to `POST /scan` with a `{"content": "..."}` body, and file uploads to `POST /scan/file` as multipart form data. Expects a JSON response with a `detected` boolean (configurable via the `response_detected_key` extra config option).
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
evadex scan --tool dlpscan --url http://my-dlpscan-server:8080 --api-key my-key
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### Adding a custom adapter
|
|
311
|
+
|
|
312
|
+
1. Create a file anywhere in your project, e.g. `my_adapter.py`.
|
|
313
|
+
|
|
314
|
+
2. Subclass `BaseAdapter` and implement `submit()`:
|
|
315
|
+
|
|
316
|
+
```python
|
|
317
|
+
from evadex.adapters.base import BaseAdapter
|
|
318
|
+
from evadex.core.registry import register_adapter
|
|
319
|
+
from evadex.core.result import Payload, Variant, ScanResult
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
@register_adapter("my-tool")
|
|
323
|
+
class MyToolAdapter(BaseAdapter):
|
|
324
|
+
name = "my-tool"
|
|
325
|
+
|
|
326
|
+
async def submit(self, payload: Payload, variant: Variant) -> ScanResult:
|
|
327
|
+
# Send variant.value to your scanner however it expects it.
|
|
328
|
+
# variant.strategy is "text", "docx", "pdf", or "xlsx".
|
|
329
|
+
# Return a ScanResult with detected=True/False.
|
|
330
|
+
response = await call_my_scanner(variant.value)
|
|
331
|
+
detected = response.get("found", False)
|
|
332
|
+
return ScanResult(
|
|
333
|
+
payload=payload,
|
|
334
|
+
variant=variant,
|
|
335
|
+
detected=detected,
|
|
336
|
+
raw_response=response,
|
|
337
|
+
)
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
3. Import your adapter before invoking evadex (so the `@register_adapter` decorator fires), then use it:
|
|
341
|
+
|
|
342
|
+
```bash
|
|
343
|
+
python -c "import my_adapter" && evadex scan --tool my-tool
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
Or wire it up properly as a package with an entry point in `pyproject.toml`:
|
|
347
|
+
|
|
348
|
+
```toml
|
|
349
|
+
[project.entry-points."evadex.adapters"]
|
|
350
|
+
my-tool = "my_package.my_adapter"
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
**Optional hooks:**
|
|
354
|
+
|
|
355
|
+
```python
|
|
356
|
+
async def setup(self):
|
|
357
|
+
# Called once before the batch — open connections, authenticate, etc.
|
|
358
|
+
self._session = await open_session()
|
|
359
|
+
|
|
360
|
+
async def teardown(self):
|
|
361
|
+
# Called once after the batch — clean up connections.
|
|
362
|
+
await self._session.close()
|
|
363
|
+
|
|
364
|
+
async def health_check(self) -> bool:
|
|
365
|
+
# Optional — verify the scanner is reachable.
|
|
366
|
+
return await ping_scanner()
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
**File strategies:** `variant.strategy` tells you which format evadex wants to use. If your scanner only supports one method, ignore strategies you don't need and handle the rest:
|
|
370
|
+
|
|
371
|
+
```python
|
|
372
|
+
from evadex.adapters.dlpscan.file_builder import FileBuilder
|
|
373
|
+
|
|
374
|
+
async def submit(self, payload, variant):
|
|
375
|
+
if variant.strategy == "text":
|
|
376
|
+
raw = await self._scan_text(variant.value)
|
|
377
|
+
else:
|
|
378
|
+
data, mime = FileBuilder.build(variant.value, variant.strategy)
|
|
379
|
+
raw = await self._scan_file(data, mime)
|
|
380
|
+
...
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
`FileBuilder.build(text, fmt)` returns `(bytes, mime_type)` entirely in memory — no disk writes.
|
|
384
|
+
|
|
385
|
+
---
|
|
386
|
+
|
|
387
|
+
## Output schema
|
|
388
|
+
|
|
389
|
+
### Top-level
|
|
390
|
+
|
|
391
|
+
```json
|
|
392
|
+
{
|
|
393
|
+
"meta": { ... },
|
|
394
|
+
"results": [ ... ]
|
|
395
|
+
}
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
### `meta`
|
|
399
|
+
|
|
400
|
+
| Field | Type | Description |
|
|
401
|
+
|---|---|---|
|
|
402
|
+
| `timestamp` | ISO 8601 string | When the scan ran |
|
|
403
|
+
| `total` | int | Total test cases run |
|
|
404
|
+
| `pass` | int | Variants detected by scanner |
|
|
405
|
+
| `fail` | int | Variants that evaded scanner |
|
|
406
|
+
| `error` | int | Adapter errors |
|
|
407
|
+
| `pass_rate` | float | `pass / total * 100` |
|
|
408
|
+
| `summary_by_category` | object | Per-category pass/fail/error counts |
|
|
409
|
+
|
|
410
|
+
### `results[]`
|
|
411
|
+
|
|
412
|
+
| Field | Type | Description |
|
|
413
|
+
|---|---|---|
|
|
414
|
+
| `payload.value` | string | Original sensitive value |
|
|
415
|
+
| `payload.category` | string | Detected category enum value |
|
|
416
|
+
| `payload.category_type` | string | `structured` or `heuristic` — see [Structured vs heuristic categories](#structured-vs-heuristic-categories) |
|
|
417
|
+
| `payload.label` | string | Human-readable label |
|
|
418
|
+
| `variant.value` | string | Transformed/obfuscated value submitted to scanner |
|
|
419
|
+
| `variant.generator` | string | Which generator produced this variant |
|
|
420
|
+
| `variant.technique` | string | Machine-readable technique name |
|
|
421
|
+
| `variant.transform_name` | string | Human-readable description of the transform |
|
|
422
|
+
| `variant.strategy` | string | Submission strategy: `text`, `docx`, `pdf`, `xlsx` |
|
|
423
|
+
| `detected` | bool | Whether the scanner flagged this variant |
|
|
424
|
+
| `severity` | string | `pass`, `fail`, or `error` |
|
|
425
|
+
| `duration_ms` | float | Time for this test case in milliseconds |
|
|
426
|
+
| `error` | string \| null | Error message if adapter threw |
|
|
427
|
+
|
|
428
|
+
---
|
|
429
|
+
|
|
430
|
+
## Publishing to PyPI
|
|
431
|
+
|
|
432
|
+
```bash
|
|
433
|
+
pip install build twine
|
|
434
|
+
python -m build
|
|
435
|
+
twine upload dist/*
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
Update the `[project.urls]` section in `pyproject.toml` with your real GitHub repository URL before publishing.
|
|
439
|
+
|
|
440
|
+
---
|
|
441
|
+
|
|
442
|
+
## License
|
|
443
|
+
|
|
444
|
+
MIT — see [LICENSE](LICENSE).
|