curlcommander 0.3.1__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.
- curlcommander-0.3.1/.github/workflows/ci.yml +179 -0
- curlcommander-0.3.1/.github/workflows/mlc_config.json +9 -0
- curlcommander-0.3.1/.github/workflows/release.yml +98 -0
- curlcommander-0.3.1/.gitignore +35 -0
- curlcommander-0.3.1/.pre-commit-config.yaml +14 -0
- curlcommander-0.3.1/CHANGELOG.md +221 -0
- curlcommander-0.3.1/CONTRIBUTING.md +58 -0
- curlcommander-0.3.1/LICENSE +21 -0
- curlcommander-0.3.1/PKG-INFO +533 -0
- curlcommander-0.3.1/README.en.md +354 -0
- curlcommander-0.3.1/README.md +458 -0
- curlcommander-0.3.1/bucket/curlcommander.json +31 -0
- curlcommander-0.3.1/curlcommander/__init__.py +1 -0
- curlcommander-0.3.1/curlcommander/__main__.py +6 -0
- curlcommander-0.3.1/curlcommander/cli/__init__.py +0 -0
- curlcommander-0.3.1/curlcommander/cli/arg_parser.py +342 -0
- curlcommander-0.3.1/curlcommander/cli/onboarding.py +479 -0
- curlcommander-0.3.1/curlcommander/cli/runner.py +1088 -0
- curlcommander-0.3.1/curlcommander/cli/wizard.py +107 -0
- curlcommander-0.3.1/curlcommander/config.py +73 -0
- curlcommander-0.3.1/curlcommander/core/__init__.py +0 -0
- curlcommander-0.3.1/curlcommander/core/api_styles.py +88 -0
- curlcommander-0.3.1/curlcommander/core/assertions.py +172 -0
- curlcommander-0.3.1/curlcommander/core/auth_handler.py +20 -0
- curlcommander-0.3.1/curlcommander/core/browser.py +151 -0
- curlcommander-0.3.1/curlcommander/core/clipboard.py +69 -0
- curlcommander-0.3.1/curlcommander/core/cookies.py +44 -0
- curlcommander-0.3.1/curlcommander/core/curl_builder.py +97 -0
- curlcommander-0.3.1/curlcommander/core/curl_parser.py +226 -0
- curlcommander-0.3.1/curlcommander/core/discovery.py +140 -0
- curlcommander-0.3.1/curlcommander/core/encoders.py +69 -0
- curlcommander-0.3.1/curlcommander/core/evidence.py +61 -0
- curlcommander-0.3.1/curlcommander/core/features.py +137 -0
- curlcommander-0.3.1/curlcommander/core/fuzzer.py +162 -0
- curlcommander-0.3.1/curlcommander/core/headers.py +167 -0
- curlcommander-0.3.1/curlcommander/core/http_client.py +160 -0
- curlcommander-0.3.1/curlcommander/core/intruder.py +86 -0
- curlcommander-0.3.1/curlcommander/core/logging_setup.py +55 -0
- curlcommander-0.3.1/curlcommander/core/multipart.py +57 -0
- curlcommander-0.3.1/curlcommander/core/parsing.py +59 -0
- curlcommander-0.3.1/curlcommander/core/passive.py +186 -0
- curlcommander-0.3.1/curlcommander/core/payload_catalog.py +126 -0
- curlcommander-0.3.1/curlcommander/core/payload_sources.py +232 -0
- curlcommander-0.3.1/curlcommander/core/payloads.py +34 -0
- curlcommander-0.3.1/curlcommander/core/proxy.py +199 -0
- curlcommander-0.3.1/curlcommander/core/raw_http.py +100 -0
- curlcommander-0.3.1/curlcommander/core/raw_transport.py +207 -0
- curlcommander-0.3.1/curlcommander/core/redaction.py +170 -0
- curlcommander-0.3.1/curlcommander/core/request_model.py +103 -0
- curlcommander-0.3.1/curlcommander/core/response_formatter.py +49 -0
- curlcommander-0.3.1/curlcommander/core/scope.py +60 -0
- curlcommander-0.3.1/curlcommander/core/validators/__init__.py +0 -0
- curlcommander-0.3.1/curlcommander/core/validators/base.py +27 -0
- curlcommander-0.3.1/curlcommander/core/validators/clickjacking.py +65 -0
- curlcommander-0.3.1/curlcommander/core/validators/cors.py +36 -0
- curlcommander-0.3.1/curlcommander/core/validators/csrf.py +65 -0
- curlcommander-0.3.1/curlcommander/core/validators/redirect.py +58 -0
- curlcommander-0.3.1/curlcommander/core/validators/xss.py +144 -0
- curlcommander-0.3.1/curlcommander/data/__init__.py +0 -0
- curlcommander-0.3.1/curlcommander/data/payload_map.yaml +29 -0
- curlcommander-0.3.1/curlcommander/data/payloads/__init__.py +0 -0
- curlcommander-0.3.1/curlcommander/data/payloads/cmdi.txt +6 -0
- curlcommander-0.3.1/curlcommander/data/payloads/sqli.txt +10 -0
- curlcommander-0.3.1/curlcommander/data/payloads/ssti.txt +6 -0
- curlcommander-0.3.1/curlcommander/data/payloads/traversal.txt +6 -0
- curlcommander-0.3.1/curlcommander/data/payloads/xss.txt +8 -0
- curlcommander-0.3.1/curlcommander/data/sources.yaml +20 -0
- curlcommander-0.3.1/curlcommander/gui/__init__.py +0 -0
- curlcommander-0.3.1/curlcommander/gui/app.py +248 -0
- curlcommander-0.3.1/curlcommander/gui/curl_panel.py +34 -0
- curlcommander-0.3.1/curlcommander/gui/history_panel.py +127 -0
- curlcommander-0.3.1/curlcommander/gui/intruder_panel.py +238 -0
- curlcommander-0.3.1/curlcommander/gui/proxy_panel.py +194 -0
- curlcommander-0.3.1/curlcommander/gui/rawreq.py +30 -0
- curlcommander-0.3.1/curlcommander/gui/repeater_panel.py +121 -0
- curlcommander-0.3.1/curlcommander/gui/request_panel.py +283 -0
- curlcommander-0.3.1/curlcommander/gui/response_panel.py +133 -0
- curlcommander-0.3.1/curlcommander/gui/response_view.py +221 -0
- curlcommander-0.3.1/curlcommander/main.py +33 -0
- curlcommander-0.3.1/curlcommander/storage/__init__.py +0 -0
- curlcommander-0.3.1/curlcommander/storage/db.py +76 -0
- curlcommander-0.3.1/curlcommander/storage/history_repo.py +125 -0
- curlcommander-0.3.1/docs/COMECE-AQUI.md +72 -0
- curlcommander-0.3.1/docs/demo.gif +0 -0
- curlcommander-0.3.1/install.ps1 +62 -0
- curlcommander-0.3.1/install.sh +61 -0
- curlcommander-0.3.1/packaging/curlcmd.spec +54 -0
- curlcommander-0.3.1/packaging/rthook_certs.py +18 -0
- curlcommander-0.3.1/packaging/winget/Ivomsantiago.CurlCommander.installer.yaml +18 -0
- curlcommander-0.3.1/packaging/winget/Ivomsantiago.CurlCommander.locale.en-US.yaml +26 -0
- curlcommander-0.3.1/packaging/winget/Ivomsantiago.CurlCommander.yaml +10 -0
- curlcommander-0.3.1/packaging/winget/README.md +31 -0
- curlcommander-0.3.1/pyproject.toml +105 -0
- curlcommander-0.3.1/scripts/install.ps1 +138 -0
- curlcommander-0.3.1/scripts/install.sh +159 -0
- curlcommander-0.3.1/tests/__init__.py +0 -0
- curlcommander-0.3.1/tests/test_api_styles.py +70 -0
- curlcommander-0.3.1/tests/test_assertions.py +128 -0
- curlcommander-0.3.1/tests/test_auth_handler.py +95 -0
- curlcommander-0.3.1/tests/test_browser_xss.py +119 -0
- curlcommander-0.3.1/tests/test_burp_tabs.py +179 -0
- curlcommander-0.3.1/tests/test_config.py +82 -0
- curlcommander-0.3.1/tests/test_cookies_multipart.py +87 -0
- curlcommander-0.3.1/tests/test_curl_builder.py +185 -0
- curlcommander-0.3.1/tests/test_curl_builder_fixes.py +83 -0
- curlcommander-0.3.1/tests/test_curl_parser.py +113 -0
- curlcommander-0.3.1/tests/test_discovery.py +142 -0
- curlcommander-0.3.1/tests/test_exit_codes.py +85 -0
- curlcommander-0.3.1/tests/test_features.py +53 -0
- curlcommander-0.3.1/tests/test_fuzzer.py +97 -0
- curlcommander-0.3.1/tests/test_gui.py +127 -0
- curlcommander-0.3.1/tests/test_headers.py +100 -0
- curlcommander-0.3.1/tests/test_history_repo.py +118 -0
- curlcommander-0.3.1/tests/test_http_client.py +106 -0
- curlcommander-0.3.1/tests/test_intruder.py +71 -0
- curlcommander-0.3.1/tests/test_logging.py +27 -0
- curlcommander-0.3.1/tests/test_main.py +58 -0
- curlcommander-0.3.1/tests/test_migration.py +65 -0
- curlcommander-0.3.1/tests/test_onboarding.py +158 -0
- curlcommander-0.3.1/tests/test_opsec.py +181 -0
- curlcommander-0.3.1/tests/test_parsing.py +84 -0
- curlcommander-0.3.1/tests/test_passive.py +60 -0
- curlcommander-0.3.1/tests/test_payload_catalog.py +90 -0
- curlcommander-0.3.1/tests/test_payload_sources.py +114 -0
- curlcommander-0.3.1/tests/test_payloads.py +24 -0
- curlcommander-0.3.1/tests/test_portability_raw.py +127 -0
- curlcommander-0.3.1/tests/test_proxy.py +100 -0
- curlcommander-0.3.1/tests/test_raw_transport.py +118 -0
- curlcommander-0.3.1/tests/test_redaction.py +146 -0
- curlcommander-0.3.1/tests/test_request_model.py +76 -0
- curlcommander-0.3.1/tests/test_response_formatter.py +62 -0
- curlcommander-0.3.1/tests/test_response_handling.py +94 -0
- curlcommander-0.3.1/tests/test_runner_cli.py +167 -0
- curlcommander-0.3.1/tests/test_validators.py +212 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
workflow_call: # reused as the pre-release gate by release.yml
|
|
8
|
+
|
|
9
|
+
concurrency:
|
|
10
|
+
group: ci-${{ github.ref }}
|
|
11
|
+
cancel-in-progress: true
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
lint:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
timeout-minutes: 10
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
- uses: actions/setup-python@v5
|
|
20
|
+
with:
|
|
21
|
+
python-version: "3.12"
|
|
22
|
+
- name: Install
|
|
23
|
+
run: |
|
|
24
|
+
python -m pip install --upgrade pip
|
|
25
|
+
pip install -e ".[dev]"
|
|
26
|
+
- name: Ruff lint
|
|
27
|
+
run: ruff check .
|
|
28
|
+
- name: Ruff format check
|
|
29
|
+
run: ruff format --check .
|
|
30
|
+
- name: Mypy (strict on core/ and storage/)
|
|
31
|
+
run: mypy
|
|
32
|
+
|
|
33
|
+
test:
|
|
34
|
+
needs: lint
|
|
35
|
+
strategy:
|
|
36
|
+
fail-fast: false
|
|
37
|
+
matrix:
|
|
38
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
39
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
40
|
+
runs-on: ${{ matrix.os }}
|
|
41
|
+
timeout-minutes: 15
|
|
42
|
+
steps:
|
|
43
|
+
- uses: actions/checkout@v4
|
|
44
|
+
- uses: actions/setup-python@v5
|
|
45
|
+
with:
|
|
46
|
+
python-version: ${{ matrix.python-version }}
|
|
47
|
+
- name: Install
|
|
48
|
+
run: |
|
|
49
|
+
python -m pip install --upgrade pip
|
|
50
|
+
pip install -e ".[dev]"
|
|
51
|
+
- name: Pytest with coverage gate
|
|
52
|
+
run: pytest --cov=curlcommander --cov-report=term-missing --cov-fail-under=80
|
|
53
|
+
|
|
54
|
+
browser-proxy:
|
|
55
|
+
needs: lint
|
|
56
|
+
runs-on: ubuntu-latest
|
|
57
|
+
timeout-minutes: 15
|
|
58
|
+
steps:
|
|
59
|
+
- uses: actions/checkout@v4
|
|
60
|
+
- uses: actions/setup-python@v5
|
|
61
|
+
with:
|
|
62
|
+
python-version: "3.12"
|
|
63
|
+
- name: Install with browser + proxy extras
|
|
64
|
+
run: |
|
|
65
|
+
python -m pip install --upgrade pip
|
|
66
|
+
pip install -e ".[dev,browser,proxy]"
|
|
67
|
+
python -m playwright install --with-deps chromium
|
|
68
|
+
- name: Browser validators (real Chromium) + proxy addon tests
|
|
69
|
+
run: pytest tests/test_browser_xss.py tests/test_validators.py tests/test_proxy.py -q
|
|
70
|
+
|
|
71
|
+
audit:
|
|
72
|
+
needs: lint
|
|
73
|
+
runs-on: ubuntu-latest
|
|
74
|
+
timeout-minutes: 10
|
|
75
|
+
steps:
|
|
76
|
+
- uses: actions/checkout@v4
|
|
77
|
+
- uses: actions/setup-python@v5
|
|
78
|
+
with:
|
|
79
|
+
python-version: "3.12"
|
|
80
|
+
- name: Install
|
|
81
|
+
run: |
|
|
82
|
+
python -m pip install --upgrade pip
|
|
83
|
+
pip install -e ".[dev]"
|
|
84
|
+
- name: pip-audit
|
|
85
|
+
run: pip-audit || true # advisory: report vulnerabilities, don't block
|
|
86
|
+
|
|
87
|
+
# Free/OSS SAST scan (community rulesets, no Semgrep account/token needed).
|
|
88
|
+
# Advisory for now, same as pip-audit above — flip `|| true` off once the
|
|
89
|
+
# existing backlog of findings is triaged, to make this a hard gate.
|
|
90
|
+
semgrep:
|
|
91
|
+
needs: lint
|
|
92
|
+
runs-on: ubuntu-latest
|
|
93
|
+
timeout-minutes: 10
|
|
94
|
+
steps:
|
|
95
|
+
- uses: actions/checkout@v4
|
|
96
|
+
- uses: actions/setup-python@v5
|
|
97
|
+
with:
|
|
98
|
+
python-version: "3.12"
|
|
99
|
+
- name: Install Semgrep (free OSS engine)
|
|
100
|
+
run: pip install semgrep
|
|
101
|
+
- name: Semgrep SAST scan (auto + secrets + security-audit rulesets)
|
|
102
|
+
run: |
|
|
103
|
+
semgrep scan \
|
|
104
|
+
--config auto \
|
|
105
|
+
--config p/secrets \
|
|
106
|
+
--config p/security-audit \
|
|
107
|
+
--sarif --output semgrep.sarif \
|
|
108
|
+
--error || true
|
|
109
|
+
- name: Upload SARIF as build artifact
|
|
110
|
+
if: always()
|
|
111
|
+
uses: actions/upload-artifact@v4
|
|
112
|
+
with:
|
|
113
|
+
name: semgrep-sarif
|
|
114
|
+
path: semgrep.sarif
|
|
115
|
+
if-no-files-found: ignore
|
|
116
|
+
|
|
117
|
+
# Runs the *remote* installer against the checkout on all three OSes, then
|
|
118
|
+
# confirms curlcmd resolves from PATH and that setup/doctor behave.
|
|
119
|
+
install-smoke:
|
|
120
|
+
needs: lint
|
|
121
|
+
strategy:
|
|
122
|
+
fail-fast: false
|
|
123
|
+
matrix:
|
|
124
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
125
|
+
runs-on: ${{ matrix.os }}
|
|
126
|
+
timeout-minutes: 15
|
|
127
|
+
steps:
|
|
128
|
+
- uses: actions/checkout@v4
|
|
129
|
+
- uses: actions/setup-python@v5
|
|
130
|
+
with:
|
|
131
|
+
python-version: "3.12"
|
|
132
|
+
|
|
133
|
+
- name: Run remote installer (from checkout) — Unix
|
|
134
|
+
if: runner.os != 'Windows'
|
|
135
|
+
shell: bash
|
|
136
|
+
run: |
|
|
137
|
+
CURLCMD_SOURCE="$PWD" sh scripts/install.sh --yes
|
|
138
|
+
# Publish every dir the installer may have used, so the next step
|
|
139
|
+
# finds curlcmd exactly as a fresh terminal would (uv/pipx/venv shim).
|
|
140
|
+
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
|
|
141
|
+
echo "$HOME/.curlcommander/venv/bin" >> "$GITHUB_PATH"
|
|
142
|
+
pipx environment --value PIPX_BIN_DIR >> "$GITHUB_PATH" 2>/dev/null || true
|
|
143
|
+
|
|
144
|
+
- name: Run remote installer (from checkout) — Windows
|
|
145
|
+
if: runner.os == 'Windows'
|
|
146
|
+
shell: pwsh
|
|
147
|
+
run: |
|
|
148
|
+
$env:CURLCMD_SOURCE = $PWD.Path
|
|
149
|
+
.\scripts\install.ps1 -Yes
|
|
150
|
+
"$env:LOCALAPPDATA\CurlCommander\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
|
151
|
+
"$env:LOCALAPPDATA\CurlCommander\venv\Scripts" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
|
152
|
+
$pipxBin = (pipx environment --value PIPX_BIN_DIR 2>$null)
|
|
153
|
+
if ($pipxBin) { $pipxBin | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append }
|
|
154
|
+
|
|
155
|
+
- name: curlcmd resolves from PATH
|
|
156
|
+
shell: bash
|
|
157
|
+
run: |
|
|
158
|
+
which curlcmd || command -v curlcmd
|
|
159
|
+
curlcmd --version
|
|
160
|
+
|
|
161
|
+
- name: doctor (fails on an essential ✗)
|
|
162
|
+
shell: bash
|
|
163
|
+
run: curlcmd doctor
|
|
164
|
+
|
|
165
|
+
- name: setup --yes is idempotent and non-interactive
|
|
166
|
+
shell: bash
|
|
167
|
+
run: curlcmd setup --yes
|
|
168
|
+
|
|
169
|
+
markdown-links:
|
|
170
|
+
needs: lint
|
|
171
|
+
runs-on: ubuntu-latest
|
|
172
|
+
timeout-minutes: 10
|
|
173
|
+
steps:
|
|
174
|
+
- uses: actions/checkout@v4
|
|
175
|
+
- name: Check Markdown links
|
|
176
|
+
uses: gaurav-nelson/github-action-markdown-link-check@v1
|
|
177
|
+
with:
|
|
178
|
+
use-verbose-mode: "yes"
|
|
179
|
+
config-file: .github/workflows/mlc_config.json
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
"ignorePatterns": [
|
|
3
|
+
{ "pattern": "^https://raw\\.githubusercontent\\.com/" },
|
|
4
|
+
{ "pattern": "^https://github\\.com/Ivomsantiago/Curl_Commander/releases" },
|
|
5
|
+
{ "pattern": "^https://github\\.com/Ivomsantiago/Curl_Commander/actions" },
|
|
6
|
+
{ "pattern": "^https://img\\.shields\\.io/" }
|
|
7
|
+
],
|
|
8
|
+
"aliveStatusCodes": [200, 206, 429]
|
|
9
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ["v*"]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: write # create the GitHub Release and upload assets
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
# Gate: the standard lint/type/test suite must pass before we build anything.
|
|
12
|
+
gate:
|
|
13
|
+
uses: ./.github/workflows/ci.yml
|
|
14
|
+
|
|
15
|
+
build-binary:
|
|
16
|
+
needs: gate
|
|
17
|
+
strategy:
|
|
18
|
+
fail-fast: false
|
|
19
|
+
matrix:
|
|
20
|
+
include:
|
|
21
|
+
- { os: ubuntu-latest, asset: curlcmd-linux-x86_64, exe: curlcmd }
|
|
22
|
+
- { os: windows-latest, asset: curlcmd-windows-x86_64.exe, exe: curlcmd.exe }
|
|
23
|
+
- { os: macos-13, asset: curlcmd-macos-x86_64, exe: curlcmd }
|
|
24
|
+
- { os: macos-14, asset: curlcmd-macos-arm64, exe: curlcmd }
|
|
25
|
+
runs-on: ${{ matrix.os }}
|
|
26
|
+
timeout-minutes: 20
|
|
27
|
+
steps:
|
|
28
|
+
- uses: actions/checkout@v4
|
|
29
|
+
- uses: actions/setup-python@v5
|
|
30
|
+
with:
|
|
31
|
+
python-version: "3.12"
|
|
32
|
+
- name: Install build deps
|
|
33
|
+
run: |
|
|
34
|
+
python -m pip install --upgrade pip
|
|
35
|
+
pip install -e ".[build-exe]"
|
|
36
|
+
- name: Build binary
|
|
37
|
+
run: pyinstaller packaging/curlcmd.spec --distpath dist --workpath build --noconfirm
|
|
38
|
+
|
|
39
|
+
# F4.2: smoke test the FROZEN binary on every OS to catch broken hidden
|
|
40
|
+
# imports before publishing.
|
|
41
|
+
- name: Smoke test (frozen)
|
|
42
|
+
shell: bash
|
|
43
|
+
run: |
|
|
44
|
+
BIN="dist/${{ matrix.exe }}"
|
|
45
|
+
"$BIN" --version
|
|
46
|
+
"$BIN" --curl-only -X POST --json '{"a":1}' https://api.example/x
|
|
47
|
+
"$BIN" --dry-run https://api.example/x -H "X-Test: 1"
|
|
48
|
+
|
|
49
|
+
- name: Stage asset + checksum
|
|
50
|
+
shell: bash
|
|
51
|
+
run: |
|
|
52
|
+
mkdir -p out
|
|
53
|
+
cp "dist/${{ matrix.exe }}" "out/${{ matrix.asset }}"
|
|
54
|
+
python -c "import hashlib,sys; p='out/${{ matrix.asset }}'; open(p+'.sha256','w').write(hashlib.sha256(open(p,'rb').read()).hexdigest()+' ${{ matrix.asset }}\n')"
|
|
55
|
+
|
|
56
|
+
- uses: actions/upload-artifact@v4
|
|
57
|
+
with:
|
|
58
|
+
name: ${{ matrix.asset }}
|
|
59
|
+
path: out/*
|
|
60
|
+
|
|
61
|
+
release:
|
|
62
|
+
needs: build-binary
|
|
63
|
+
runs-on: ubuntu-latest
|
|
64
|
+
timeout-minutes: 10
|
|
65
|
+
steps:
|
|
66
|
+
- uses: actions/download-artifact@v4
|
|
67
|
+
with:
|
|
68
|
+
path: artifacts
|
|
69
|
+
- name: Collect binaries + combined SHA256SUMS
|
|
70
|
+
run: |
|
|
71
|
+
mkdir -p release
|
|
72
|
+
find artifacts -type f -not -name '*.sha256' -exec cp {} release/ \;
|
|
73
|
+
find artifacts -type f -name '*.sha256' -exec cat {} + > release/SHA256SUMS
|
|
74
|
+
ls -l release
|
|
75
|
+
- name: Publish GitHub Release
|
|
76
|
+
uses: softprops/action-gh-release@v2
|
|
77
|
+
with:
|
|
78
|
+
files: release/*
|
|
79
|
+
generate_release_notes: true
|
|
80
|
+
|
|
81
|
+
publish-pypi:
|
|
82
|
+
needs: gate
|
|
83
|
+
runs-on: ubuntu-latest
|
|
84
|
+
timeout-minutes: 10
|
|
85
|
+
environment: pypi
|
|
86
|
+
permissions:
|
|
87
|
+
id-token: write # OIDC trusted publishing (no stored token)
|
|
88
|
+
steps:
|
|
89
|
+
- uses: actions/checkout@v4
|
|
90
|
+
- uses: actions/setup-python@v5
|
|
91
|
+
with:
|
|
92
|
+
python-version: "3.12"
|
|
93
|
+
- name: Build sdist + wheel
|
|
94
|
+
run: |
|
|
95
|
+
python -m pip install --upgrade pip build
|
|
96
|
+
python -m build
|
|
97
|
+
- name: Publish to PyPI
|
|
98
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.pyo
|
|
5
|
+
*.pyd
|
|
6
|
+
|
|
7
|
+
# Virtual environment
|
|
8
|
+
.venv/
|
|
9
|
+
|
|
10
|
+
env/
|
|
11
|
+
venv/
|
|
12
|
+
|
|
13
|
+
# Distribution / packaging
|
|
14
|
+
.Python
|
|
15
|
+
build/
|
|
16
|
+
dist/
|
|
17
|
+
*.egg-info/
|
|
18
|
+
.eggs/
|
|
19
|
+
|
|
20
|
+
# Pytest
|
|
21
|
+
.cache/
|
|
22
|
+
|
|
23
|
+
# IDEs
|
|
24
|
+
.vscode/
|
|
25
|
+
.idea/
|
|
26
|
+
|
|
27
|
+
# OS files
|
|
28
|
+
.DS_Store
|
|
29
|
+
Thumbs.db
|
|
30
|
+
|
|
31
|
+
# Coverage
|
|
32
|
+
.coverage
|
|
33
|
+
.coverage.*
|
|
34
|
+
coverage.xml
|
|
35
|
+
htmlcov/
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
3
|
+
rev: v0.6.9
|
|
4
|
+
hooks:
|
|
5
|
+
- id: ruff
|
|
6
|
+
args: [--fix]
|
|
7
|
+
- id: ruff-format
|
|
8
|
+
- repo: https://github.com/pre-commit/mirrors-mypy
|
|
9
|
+
rev: v1.11.2
|
|
10
|
+
hooks:
|
|
11
|
+
- id: mypy
|
|
12
|
+
additional_dependencies: [httpx, rich, textual, prompt_toolkit]
|
|
13
|
+
args: [--config-file=pyproject.toml]
|
|
14
|
+
pass_filenames: false
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to CurlCommander are documented here. This release turns a
|
|
4
|
+
basic curl generator into a request builder and API/AppSec testing tool. Format
|
|
5
|
+
loosely follows [Keep a Changelog](https://keepachangelog.com/).
|
|
6
|
+
|
|
7
|
+
## [0.3.0] - 2026-09-06 — GUI vira "Burp na TUI" + defaults consertados
|
|
8
|
+
## [0.3.1] - 2026-09-06 — Correções de release e publicação
|
|
9
|
+
|
|
10
|
+
### Corrigido
|
|
11
|
+
- Correções de configuração e metadados de release.
|
|
12
|
+
- Ajustes no fluxo de publicação do pacote no PyPI via GitHub Actions.
|
|
13
|
+
- Correções menores sem alteração da API pública ou introdução de novas funcionalidades.
|
|
14
|
+
|
|
15
|
+
_Seção em português._
|
|
16
|
+
|
|
17
|
+
### Fase 0 — defaults quebrados
|
|
18
|
+
- **Saída da TUI visível e robusta**: `compose()` agora inclui Header e Footer
|
|
19
|
+
(os atalhos aparecem na tela), há um botão **Sair**, e Ctrl+Q/Ctrl+C saem
|
|
20
|
+
mesmo com foco num Input; confirmação só enquanto há requisição em andamento.
|
|
21
|
+
- **`curlcmd setup` prepara tudo por padrão**: sem flags e interativo, pergunta
|
|
22
|
+
grupo a grupo (payloads = sim; resto = pergunta); `--yes` sem flags equivale a
|
|
23
|
+
`--all --yes`.
|
|
24
|
+
- **Frescor de wordlists**: marcador de sync por fonte; `doctor` sinaliza fontes
|
|
25
|
+
com > 30 dias e `fuzz`/`discover`/`bounty-scan` imprimem um aviso não
|
|
26
|
+
bloqueante.
|
|
27
|
+
|
|
28
|
+
### Fase 1 — abas Proxy / Repeater / Intruder
|
|
29
|
+
- A GUI é um `TabbedContent`: **Repeater** (sub-abas persistentes, editor raw,
|
|
30
|
+
histórico de reenvios), **Intruder** (posições `§…§`, 4 modos nomeados sobre o
|
|
31
|
+
motor de fuzz, grade ordenável com anomalia), **Proxy** (captura ao vivo,
|
|
32
|
+
escopo esmaecido, "enviar para Repeater/Intruder"). Roteamento por Ctrl+R/Ctrl+I.
|
|
33
|
+
- Visualizador de resposta reutilizável: Pretty/Raw/Headers/Cookies, busca com
|
|
34
|
+
contagem navegável, diff entre respostas.
|
|
35
|
+
- `core/intruder.py` mapeia os 4 modos sobre `run_fuzz` (sem duplicar lógica).
|
|
36
|
+
|
|
37
|
+
### Fase 2 — mais motor na GUI
|
|
38
|
+
- `core/passive.py`: análise passiva (headers de segurança, flags de cookie,
|
|
39
|
+
CORS, erro verboso, fingerprint) como candidatos, com saída SARIF; botão
|
|
40
|
+
**Analisar** na resposta.
|
|
41
|
+
- Opções de requisição completas na GUI (HTTP/2, compressed, cookies).
|
|
42
|
+
|
|
43
|
+
### Correção
|
|
44
|
+
- `send()` preservava `params=[]` e apagava a query embutida na URL; agora a
|
|
45
|
+
query da URL sobrevive (o curl a mantém).
|
|
46
|
+
|
|
47
|
+
## [Não lançado] — Instalação impecável & onboarding em PT-BR
|
|
48
|
+
|
|
49
|
+
_Esta seção está em português; as anteriores permanecem no idioma original._
|
|
50
|
+
|
|
51
|
+
### Instalação e onboarding
|
|
52
|
+
- **Registro central de recursos opcionais** (`core/features.py`): fonte única
|
|
53
|
+
da verdade para navegador/proxy/socks/área de transferência, com os imports
|
|
54
|
+
que detectam cada um e os pacotes que os fornecem. Recursos ausentes agora
|
|
55
|
+
geram uma mensagem única e acionável em português apontando `curlcmd setup
|
|
56
|
+
--<recurso>` (com variante para o binário standalone).
|
|
57
|
+
- **`curlcmd setup`** (`--all/--browser/--proxy/--socks/--clipboard/--payloads/
|
|
58
|
+
--yes`): instala os extras opcionais e as fontes de payloads. Idempotente,
|
|
59
|
+
mostra o plano e a rede/PyPI que vai tocar antes de agir, confirma
|
|
60
|
+
interativamente (ou `--yes`), recusa em terminal não interativo sem `--yes` e
|
|
61
|
+
explica que os extras precisam de Python quando rodado no binário standalone.
|
|
62
|
+
- **`curlcmd doctor`** (`--fix`): diagnostica versão do Python, diretório de
|
|
63
|
+
dados gravável, método de instalação, cada recurso opcional, Chromium e fontes
|
|
64
|
+
de payloads; sai com código diferente de zero só em falha essencial.
|
|
65
|
+
- **`curlcmd self-update`** (`--yes`): atualiza pelo método detectado
|
|
66
|
+
(pipx/uv/pip) ou orienta o caminho do binário. `--version` passa a mostrar o
|
|
67
|
+
método de instalação.
|
|
68
|
+
- **Instaladores remotos de uma linha** (`scripts/install.sh`,
|
|
69
|
+
`scripts/install.ps1`): `curl|sh` e `irm|iex`. Escolhem `uv tool` → `pipx` →
|
|
70
|
+
venv gerenciado com atalho `curlcmd`, resolvem o PATH, são idempotentes e
|
|
71
|
+
aceitam `--yes`/`-Yes`. `CURLCMD_SOURCE` instala a partir de um checkout local
|
|
72
|
+
(usado pela CI).
|
|
73
|
+
- **Manifestos de pacote**: winget (`packaging/winget/`, modelo preenchido no
|
|
74
|
+
release) e Scoop (`bucket/curlcommander.json`, com `checkver` + `autoupdate`).
|
|
75
|
+
|
|
76
|
+
### Documentação
|
|
77
|
+
- README traduzido para PT-BR com o original em `README.en.md` e troca de idioma
|
|
78
|
+
no topo; `docs/COMECE-AQUI.md` (guia rápido); `CONTRIBUTING.md` em PT-BR;
|
|
79
|
+
mensagens de CLI/`setup`/`doctor`/erros de extra em português.
|
|
80
|
+
|
|
81
|
+
## [Unreleased] — Bug-bounty payloads & browser/proxy validation
|
|
82
|
+
|
|
83
|
+
### Phase G — payloads for bug bounty
|
|
84
|
+
- **G.1** `core/payload_sources.py`: sync SecLists / PayloadsAllTheThings /
|
|
85
|
+
FuzzDB via shallow sparse `git clone` into the OS data dir; `SECLISTS_PATH` /
|
|
86
|
+
`CURLCOMMANDER_PAYLOADS` reuse an existing checkout; custom sources supported.
|
|
87
|
+
`curlcmd payloads sync|update`.
|
|
88
|
+
- **G.2/G.3** `data/payload_map.yaml` curated category→file map; unified catalog
|
|
89
|
+
(`core/payload_catalog.py`) with `payloads list|search|show`; fuzzer resolves
|
|
90
|
+
`-w seclists:...`, `--payloads CAT` and `--payloads-all CAT` (all sources,
|
|
91
|
+
deduped) through one engine.
|
|
92
|
+
- **G.4/G.5** `curlcmd discover` (dirbusting: response filters, extensions,
|
|
93
|
+
shallow recursion) and `curlcmd bounty-scan` (chained per-category fuzz,
|
|
94
|
+
severity-ranked candidates, `--engagement` + `--scope` gated) — both reuse the
|
|
95
|
+
fuzz engine.
|
|
96
|
+
|
|
97
|
+
### Phase H — browser validation & intercepting proxy
|
|
98
|
+
- **H.1/H.2** Optional `[browser]` extra. `core/browser.py` scope-enforced
|
|
99
|
+
Playwright wrapper; `validate xss` executes payloads in a real browser with a
|
|
100
|
+
unique canary (reflected/stored/DOM), catching dialogs and DOM sinks —
|
|
101
|
+
CONFIRMED, not just reflected.
|
|
102
|
+
- **H.3** `validate clickjacking|csrf` (browser) and `validate cors|
|
|
103
|
+
open-redirect` (HTTP) with verdicts + evidence.
|
|
104
|
+
- **H.4** Optional `[proxy]` extra. `core/proxy.py` / `curlcmd proxy`:
|
|
105
|
+
intercepting HTTPS proxy with its own CA (`<config>/ca/`, 0700),
|
|
106
|
+
match-and-replace, scope-gated capture into history, out-of-scope tunnelling,
|
|
107
|
+
`--launch-browser`, `--ca` guidance.
|
|
108
|
+
- **H.5** `--evidence` for validators saves screenshot + DOM + HAR + Playwright
|
|
109
|
+
trace.
|
|
110
|
+
- **H.6** Scenario `browser:` steps deferred — no `.http`/YAML scenario engine
|
|
111
|
+
exists in this codebase yet.
|
|
112
|
+
- Scope and secret redaction apply to browser navigation and captured proxy
|
|
113
|
+
traffic; browser/proxy actions require `--engagement`.
|
|
114
|
+
|
|
115
|
+
## [Unreleased] — Portability & packaging
|
|
116
|
+
|
|
117
|
+
### Packaging
|
|
118
|
+
- **F2.1** Standalone single-file executable via PyInstaller
|
|
119
|
+
(`packaging/curlcmd.spec`, `[build-exe]` extra): bundles the payload data
|
|
120
|
+
files, Textual/httpx/rich hidden imports, and a certifi CA store (runtime
|
|
121
|
+
hook sets `SSL_CERT_FILE`) so TLS works in the frozen binary. `curlcmd.exe`
|
|
122
|
+
on Windows, `curlcmd` on Linux/macOS. `python -m curlcommander` entry added.
|
|
123
|
+
- **F2.2** Optional `curlcmd.pyz` via shiv/zipapp (`[build-pyz]` extra) for
|
|
124
|
+
users who have Python but want a single file without installing.
|
|
125
|
+
- **F2.3** Symbols stripped where supported, tkinter/test modules excluded;
|
|
126
|
+
README documents the antivirus false-positive caveat and the SHA256 check.
|
|
127
|
+
|
|
128
|
+
### Release CI/CD
|
|
129
|
+
- **F4.1/F4.2** `.github/workflows/release.yml` on `v*` tags: runs the CI suite
|
|
130
|
+
as a gate, builds the standalone binary on Linux / Windows / macOS-x86_64 /
|
|
131
|
+
macOS-arm64, **smoke-tests the frozen binary on each OS**, publishes the
|
|
132
|
+
binaries plus a combined `SHA256SUMS` to the GitHub Release, and publishes the
|
|
133
|
+
wheel + sdist to PyPI via OIDC trusted publishing. `ci.yml` gained a
|
|
134
|
+
`workflow_call` trigger so it can be reused as that gate.
|
|
135
|
+
|
|
136
|
+
### Distribution
|
|
137
|
+
- **F3.1** `install.ps1` for Windows mirroring `install.sh` (uv tool → pipx →
|
|
138
|
+
local `.venv`, `-System` behind confirmation, `-Help`).
|
|
139
|
+
- **F3.2** `install.sh --help` points to the standalone binary for Python-less
|
|
140
|
+
installs.
|
|
141
|
+
- **F3.3** README installation table (method × OS) with the standalone binary
|
|
142
|
+
as the recommended path.
|
|
143
|
+
|
|
144
|
+
### Portability fixes
|
|
145
|
+
- **F1.1** Raw requests are read byte-for-byte from disk (`read_bytes`, no
|
|
146
|
+
universal-newline translation) and `parse_raw_request_bytes` preserves the
|
|
147
|
+
body verbatim, so hand-crafted chunked / CL.TE framing survives on Windows.
|
|
148
|
+
`--raw-request` recomputes a lone `Content-Length` for convenience but never
|
|
149
|
+
for a smuggling-shaped request, and `--no-fix-length` disables it entirely.
|
|
150
|
+
- **F1.2** Config lives in the OS data dir via `platformdirs`
|
|
151
|
+
(`%LOCALAPPDATA%`, `~/Library/Application Support`, XDG); `CURLCOMMANDER_HOME`
|
|
152
|
+
overrides it; a legacy `~/.curlcommander` migrates automatically on first run.
|
|
153
|
+
- **F1.3** Text outputs (history export, cookie jars, evidence metadata) are
|
|
154
|
+
written with explicit `newline="\n"` for reproducible, OS-independent files.
|
|
155
|
+
- **F1.4** Documented that on Windows `chmod` only sets read-only; secret
|
|
156
|
+
redaction is the real protection there.
|
|
157
|
+
|
|
158
|
+
## [0.2.0]
|
|
159
|
+
|
|
160
|
+
### Architecture
|
|
161
|
+
- **Ordered, case- and duplicate-preserving headers & params.** `HeaderList`
|
|
162
|
+
replaces `dict`, so duplicate `X-Forwarded-For`/`Cookie` headers, HPP query
|
|
163
|
+
params (`?id=1&id=2`) and exact header casing/order survive from input →
|
|
164
|
+
curl → wire → storage.
|
|
165
|
+
- **Raw byte-level socket transport** that bypasses httpx normalisation for
|
|
166
|
+
request smuggling, CRLF and path-traversal testing.
|
|
167
|
+
|
|
168
|
+
### Phase 1 — bug fixes (each with a regression test)
|
|
169
|
+
- **1.1** Basic auth now appears in the generated curl (`-u user:pass`); the
|
|
170
|
+
curl reproduces the wire for all four auth types.
|
|
171
|
+
- **1.2** `-L` is emitted only when redirects are followed.
|
|
172
|
+
- **1.3** A non-default `--timeout` is reflected as `--max-time`.
|
|
173
|
+
- **1.4** Lossless replay: the full request is stored as `config_json` and every
|
|
174
|
+
field is rehydrated; replay refuses to send an empty credential.
|
|
175
|
+
- **1.5** Secret redaction before persistence (`{{VAR}}` references or REDACTED),
|
|
176
|
+
DB dir/file at `0700`/`0600`, `--no-redact` (warned) and `--reveal`.
|
|
177
|
+
- **1.6** Meaningful exit codes: `0` ok, `1` usage, `2` network, `3` assertion,
|
|
178
|
+
`22` HTTP ≥ 400 with `--fail`.
|
|
179
|
+
- **1.7** Centralized header/param parsing; `-H "Accept:application/json"` no
|
|
180
|
+
longer silently drops.
|
|
181
|
+
- **1.8** Binary-safe `--output` (raw bytes); charset-aware display decoding.
|
|
182
|
+
- **1.9** Large response bodies are truncated for display, saved in full.
|
|
183
|
+
- **1.10** JSON pretty-printed automatically; `--raw` disables formatting.
|
|
184
|
+
- **1.11** The GUI reuses one SQLite connection and closes it.
|
|
185
|
+
|
|
186
|
+
### Phase 2 — functional gaps
|
|
187
|
+
- **2.1** Import curl commands (`--import`, `--import-file`, `--import-clipboard`).
|
|
188
|
+
- **2.2** Import raw HTTP request blocks (`--import-raw --host`).
|
|
189
|
+
- **2.3** Cookies and sessions (`--cookie`, `--cookie-jar`, `--session`).
|
|
190
|
+
- **2.4** Multipart uploads (`-F/--form-file`, controllable filename/type).
|
|
191
|
+
- **2.6** Response assertions (`--assert-*`) with `--report json|junit`.
|
|
192
|
+
- **2.12** `--version`, `--fail`, `--raw`.
|
|
193
|
+
- **2.13** TUI options panel, response tabs (Body/Headers/Raw/Cookies), body
|
|
194
|
+
search, clipboard copy, portable keybindings, env substitution.
|
|
195
|
+
|
|
196
|
+
### Phase 2B — pentest & API testing
|
|
197
|
+
- **2B.1** Full header/param/request-line control, `--no-default-headers`,
|
|
198
|
+
`--raw-path` (byte-faithful, no URL normalisation).
|
|
199
|
+
- **2B.2** Raw request transport (`--raw-request`), CL.TE/TE.CL survive.
|
|
200
|
+
- **2B.3** Fuzzing (`-w`, `--payloads`, clusterbomb/pitchfork, `--mc/--fc/--ms/
|
|
201
|
+
--fs/--mr`, `--concurrency`, `--rate`) with pluggable encoders (`--encode`).
|
|
202
|
+
- **2B.4** Built-in payload library (sqli/xss/ssti/traversal/cmdi) scaffold.
|
|
203
|
+
- **2B.6** GraphQL (`--graphql`, introspection), SOAP/XML, gRPC-web, streaming
|
|
204
|
+
(`--stream` for NDJSON/SSE).
|
|
205
|
+
- **2B.8** Scope allowlist (`--scope`), `--dry-run`, evidence capture
|
|
206
|
+
(`--evidence`, `--engagement`), visible `--no-verify` warning.
|
|
207
|
+
|
|
208
|
+
### Phase 3 — engineering quality
|
|
209
|
+
- **3.1** GitHub Actions CI: ruff + ruff-format + mypy, a 3.11/3.12/3.13 ×
|
|
210
|
+
Linux/macOS/Windows test matrix with an 80% coverage gate, and pip-audit.
|
|
211
|
+
- **3.2** ruff (lint+format), mypy `--strict` on `core/`+`storage/`, pre-commit.
|
|
212
|
+
- **3.3** Tests for the runner, main detection, the GUI (Textual pilot), the
|
|
213
|
+
curl round-trip, and that no secret reaches SQLite or the JSON export.
|
|
214
|
+
- **3.4** Full package metadata, `LICENSE` (MIT), `CONTRIBUTING.md`.
|
|
215
|
+
- **3.5** `install.sh` prefers `uv`/`pipx`, venv fallback, `--break-system-
|
|
216
|
+
packages` only behind `--system`.
|
|
217
|
+
- **3.6** SQLite schema migrations via `PRAGMA user_version`.
|
|
218
|
+
- **3.7** Structured logging (`--log-file`, `--log-level`) with secret redaction.
|
|
219
|
+
|
|
220
|
+
## [0.1.0]
|
|
221
|
+
- Initial release: curl generation, httpx sending, SQLite history, wizard, TUI.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Contribuindo com o CurlCommander
|
|
2
|
+
|
|
3
|
+
Obrigado por ajudar a melhorar o CurlCommander. Este projeto é um construtor de
|
|
4
|
+
requisições HTTP no terminal e ferramenta de testes de API/AppSec; correção e
|
|
5
|
+
fidelidade byte a byte importam, então mudanças vêm acompanhadas de testes.
|
|
6
|
+
|
|
7
|
+
> 🌐 This document is also relevant to English speakers — the commands are
|
|
8
|
+
> universal; ask in an issue if you need an English review.
|
|
9
|
+
|
|
10
|
+
## Ambiente de desenvolvimento
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
uv venv && source .venv/bin/activate # ou: python -m venv .venv
|
|
14
|
+
uv pip install -e ".[dev]" # ou: pip install -e ".[dev]"
|
|
15
|
+
pre-commit install # opcional: roda as checagens no commit
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Arquitetura
|
|
19
|
+
|
|
20
|
+
Camadas estritas — `core/` nunca pode importar de `cli/` ou `gui/`:
|
|
21
|
+
|
|
22
|
+
- `core/` — modelo de requisição, builder/parser de curl, transportes (httpx +
|
|
23
|
+
socket cru), redação, fuzzing, asserções, encoders, escopo, evidência,
|
|
24
|
+
registro de recursos opcionais (`core/features.py`).
|
|
25
|
+
- `storage/` — histórico em SQLite com migrações via `PRAGMA user_version`.
|
|
26
|
+
- `cli/` — argparse, orquestração, wizard, `setup`/`doctor`/`self-update`.
|
|
27
|
+
- `gui/` — TUI em Textual.
|
|
28
|
+
|
|
29
|
+
## Antes de abrir um PR
|
|
30
|
+
|
|
31
|
+
Rode o gate completo localmente — a CI roda o mesmo:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
ruff check .
|
|
35
|
+
ruff format --check .
|
|
36
|
+
mypy # estrito em core/ e storage/
|
|
37
|
+
pytest --cov=curlcommander
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Diretrizes:
|
|
41
|
+
|
|
42
|
+
- **Toda mudança de comportamento vem com teste.** Correções de bug ganham um
|
|
43
|
+
teste de regressão que falha antes e passa depois.
|
|
44
|
+
- **Mantenha o `mypy --strict` limpo** em `core/` e `storage/`; adicione tipos.
|
|
45
|
+
- **Nenhuma dependência de runtime nova** sem justificativa; recursos opcionais
|
|
46
|
+
vão em `[project.optional-dependencies]` e no registro `core/features.py`.
|
|
47
|
+
- **Nunca persista um segredo.** Tudo que é escrito no banco de histórico, no
|
|
48
|
+
export JSON, em evidências ou logs deve passar pela camada de redação.
|
|
49
|
+
- **Mensagens ao usuário em português**, sempre com a ação de correção.
|
|
50
|
+
- Um commit focado por mudança, com prefixo `fix:` / `feat:` / `chore:` /
|
|
51
|
+
`test:` / `docs:`.
|
|
52
|
+
|
|
53
|
+
## Escopo de testes de segurança
|
|
54
|
+
|
|
55
|
+
Esta ferramenta é para testes de segurança **autorizados**. Ao adicionar
|
|
56
|
+
recursos de pentest, mantenha as travas de segurança intactas: a imposição de
|
|
57
|
+
escopo (`--scope`), o aviso do `--no-verify` e a redação de segredos não são
|
|
58
|
+
opcionais.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 CurlCommander 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.
|