crucible-security 0.1.0__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.
- crucible_security-0.1.0/.github/ISSUE_TEMPLATE/bug_report.md +29 -0
- crucible_security-0.1.0/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- crucible_security-0.1.0/.github/ISSUE_TEMPLATE/new_attack.md +45 -0
- crucible_security-0.1.0/.github/workflows/ci.yml +71 -0
- crucible_security-0.1.0/.github/workflows/publish.yml +54 -0
- crucible_security-0.1.0/.gitignore +207 -0
- crucible_security-0.1.0/CHANGELOG.md +28 -0
- crucible_security-0.1.0/CONTRIBUTING.md +165 -0
- crucible_security-0.1.0/LICENSE +201 -0
- crucible_security-0.1.0/PKG-INFO +226 -0
- crucible_security-0.1.0/README.md +182 -0
- crucible_security-0.1.0/crucible/__init__.py +12 -0
- crucible_security-0.1.0/crucible/attacks/__init__.py +1 -0
- crucible_security-0.1.0/crucible/attacks/base.py +150 -0
- crucible_security-0.1.0/crucible/attacks/goal_hijacking.py +373 -0
- crucible_security-0.1.0/crucible/attacks/jailbreaks.py +386 -0
- crucible_security-0.1.0/crucible/attacks/mcp_attacks.py +138 -0
- crucible_security-0.1.0/crucible/attacks/prompt_injection.py +939 -0
- crucible_security-0.1.0/crucible/cli.py +273 -0
- crucible_security-0.1.0/crucible/core/__init__.py +1 -0
- crucible_security-0.1.0/crucible/core/runner.py +69 -0
- crucible_security-0.1.0/crucible/core/scorer.py +88 -0
- crucible_security-0.1.0/crucible/models.py +318 -0
- crucible_security-0.1.0/crucible/modules/__init__.py +1 -0
- crucible_security-0.1.0/crucible/modules/base.py +71 -0
- crucible_security-0.1.0/crucible/modules/security.py +69 -0
- crucible_security-0.1.0/crucible/py.typed +1 -0
- crucible_security-0.1.0/crucible/reporters/__init__.py +1 -0
- crucible_security-0.1.0/crucible/reporters/base.py +13 -0
- crucible_security-0.1.0/crucible/reporters/json_reporter.py +43 -0
- crucible_security-0.1.0/crucible/reporters/terminal.py +281 -0
- crucible_security-0.1.0/examples/test_langchain_agent.py +47 -0
- crucible_security-0.1.0/examples/test_openai_agent.py +46 -0
- crucible_security-0.1.0/examples/test_public_agent.py +9 -0
- crucible_security-0.1.0/pyproject.toml +142 -0
- crucible_security-0.1.0/tests/__init__.py +1 -0
- crucible_security-0.1.0/tests/conftest.py +92 -0
- crucible_security-0.1.0/tests/test_attacks.py +195 -0
- crucible_security-0.1.0/tests/test_cli.py +101 -0
- crucible_security-0.1.0/tests/test_models.py +218 -0
- crucible_security-0.1.0/tests/test_scorer.py +200 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug Report
|
|
3
|
+
about: Report a bug to help us improve Crucible
|
|
4
|
+
title: "[BUG] "
|
|
5
|
+
labels: bug
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Describe the Bug
|
|
10
|
+
A clear and concise description of what the bug is.
|
|
11
|
+
|
|
12
|
+
## Steps to Reproduce
|
|
13
|
+
1. Install crucible: `pip install crucible-security`
|
|
14
|
+
2. Run: `crucible scan --target ...`
|
|
15
|
+
3. See error
|
|
16
|
+
|
|
17
|
+
## Expected Behavior
|
|
18
|
+
What you expected to happen.
|
|
19
|
+
|
|
20
|
+
## Actual Behavior
|
|
21
|
+
What actually happened. Include the full error traceback if applicable.
|
|
22
|
+
|
|
23
|
+
## Environment
|
|
24
|
+
- OS: [e.g., Ubuntu 22.04, Windows 11, macOS 14]
|
|
25
|
+
- Python version: [e.g., 3.12.1]
|
|
26
|
+
- Crucible version: [run `crucible --version`]
|
|
27
|
+
|
|
28
|
+
## Additional Context
|
|
29
|
+
Add any other context about the problem here.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature Request
|
|
3
|
+
about: Suggest an idea for Crucible
|
|
4
|
+
title: "[FEATURE] "
|
|
5
|
+
labels: enhancement
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Use Case
|
|
10
|
+
Describe the problem or use case that this feature would address.
|
|
11
|
+
What are you trying to accomplish?
|
|
12
|
+
|
|
13
|
+
## Proposed Solution
|
|
14
|
+
Describe the solution you'd like to see implemented.
|
|
15
|
+
|
|
16
|
+
## Alternatives Considered
|
|
17
|
+
Any alternative solutions or features you've considered.
|
|
18
|
+
|
|
19
|
+
## Additional Context
|
|
20
|
+
Add any other context, mockups, or references.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: New Attack Vector
|
|
3
|
+
about: Propose a new attack vector for Crucible
|
|
4
|
+
title: "[ATTACK] "
|
|
5
|
+
labels: new-attack
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Attack Name
|
|
10
|
+
What should this attack be called? (e.g., "Context Window Overflow")
|
|
11
|
+
|
|
12
|
+
## OWASP Category
|
|
13
|
+
Which OWASP Agentic Top 10 category does this fall under?
|
|
14
|
+
- [ ] Goal Hijacking
|
|
15
|
+
- [ ] Prompt Injection
|
|
16
|
+
- [ ] Tool Misuse
|
|
17
|
+
- [ ] Identity Abuse
|
|
18
|
+
- [ ] Memory Poisoning
|
|
19
|
+
- [ ] Data Exfiltration
|
|
20
|
+
- [ ] Scope Violation
|
|
21
|
+
- [ ] Cascading Failure
|
|
22
|
+
- [ ] Supply Chain
|
|
23
|
+
- [ ] Rogue Agent
|
|
24
|
+
|
|
25
|
+
## Severity
|
|
26
|
+
- [ ] CRITICAL
|
|
27
|
+
- [ ] HIGH
|
|
28
|
+
- [ ] MEDIUM
|
|
29
|
+
- [ ] LOW
|
|
30
|
+
|
|
31
|
+
## Description
|
|
32
|
+
Describe the attack technique and what vulnerability it exposes.
|
|
33
|
+
|
|
34
|
+
## Example Payloads
|
|
35
|
+
Provide 2-3 example payloads:
|
|
36
|
+
```
|
|
37
|
+
Payload 1: "..."
|
|
38
|
+
Payload 2: "..."
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Detection Criteria
|
|
42
|
+
How should Crucible determine if the attack succeeded (vulnerability found)?
|
|
43
|
+
|
|
44
|
+
## References
|
|
45
|
+
Links to papers, blog posts, or documentation about this attack.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
lint:
|
|
14
|
+
name: Lint & Type Check
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
strategy:
|
|
17
|
+
matrix:
|
|
18
|
+
python-version: ["3.9", "3.10", "3.11", "3.12"]
|
|
19
|
+
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v4
|
|
22
|
+
|
|
23
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
24
|
+
uses: actions/setup-python@v5
|
|
25
|
+
with:
|
|
26
|
+
python-version: ${{ matrix.python-version }}
|
|
27
|
+
|
|
28
|
+
- name: Install dependencies
|
|
29
|
+
run: |
|
|
30
|
+
python -m pip install --upgrade pip
|
|
31
|
+
pip install -e ".[dev]"
|
|
32
|
+
|
|
33
|
+
- name: Black (formatting)
|
|
34
|
+
run: black --check crucible/ tests/
|
|
35
|
+
|
|
36
|
+
- name: Ruff (linting)
|
|
37
|
+
run: ruff check crucible/ tests/
|
|
38
|
+
|
|
39
|
+
- name: Mypy (type checking)
|
|
40
|
+
run: mypy crucible/
|
|
41
|
+
|
|
42
|
+
test:
|
|
43
|
+
name: Test Suite
|
|
44
|
+
runs-on: ${{ matrix.os }}
|
|
45
|
+
strategy:
|
|
46
|
+
matrix:
|
|
47
|
+
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
48
|
+
python-version: ["3.9", "3.10", "3.11", "3.12"]
|
|
49
|
+
|
|
50
|
+
steps:
|
|
51
|
+
- uses: actions/checkout@v4
|
|
52
|
+
|
|
53
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
54
|
+
uses: actions/setup-python@v5
|
|
55
|
+
with:
|
|
56
|
+
python-version: ${{ matrix.python-version }}
|
|
57
|
+
|
|
58
|
+
- name: Install dependencies
|
|
59
|
+
run: |
|
|
60
|
+
python -m pip install --upgrade pip
|
|
61
|
+
pip install -e ".[dev]"
|
|
62
|
+
|
|
63
|
+
- name: Run tests with coverage
|
|
64
|
+
run: pytest tests/ -v --cov=crucible --cov-report=xml
|
|
65
|
+
|
|
66
|
+
- name: Upload coverage to Codecov
|
|
67
|
+
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12'
|
|
68
|
+
uses: codecov/codecov-action@v4
|
|
69
|
+
with:
|
|
70
|
+
file: ./coverage.xml
|
|
71
|
+
fail_ci_if_error: false
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
id-token: write
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build:
|
|
13
|
+
name: Build Distribution
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Set up Python
|
|
20
|
+
uses: actions/setup-python@v5
|
|
21
|
+
with:
|
|
22
|
+
python-version: "3.12"
|
|
23
|
+
|
|
24
|
+
- name: Install build tools
|
|
25
|
+
run: |
|
|
26
|
+
python -m pip install --upgrade pip
|
|
27
|
+
pip install build
|
|
28
|
+
|
|
29
|
+
- name: Build package
|
|
30
|
+
run: python -m build
|
|
31
|
+
|
|
32
|
+
- name: Upload artifacts
|
|
33
|
+
uses: actions/upload-artifact@v4
|
|
34
|
+
with:
|
|
35
|
+
name: dist
|
|
36
|
+
path: dist/
|
|
37
|
+
|
|
38
|
+
publish:
|
|
39
|
+
name: Publish to PyPI
|
|
40
|
+
needs: build
|
|
41
|
+
runs-on: ubuntu-latest
|
|
42
|
+
environment:
|
|
43
|
+
name: pypi
|
|
44
|
+
url: https://pypi.org/p/crucible-security
|
|
45
|
+
|
|
46
|
+
steps:
|
|
47
|
+
- name: Download artifacts
|
|
48
|
+
uses: actions/download-artifact@v4
|
|
49
|
+
with:
|
|
50
|
+
name: dist
|
|
51
|
+
path: dist/
|
|
52
|
+
|
|
53
|
+
- name: Publish to PyPI
|
|
54
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[codz]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py.cover
|
|
50
|
+
.hypothesis/
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
cover/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
.pybuilder/
|
|
76
|
+
target/
|
|
77
|
+
|
|
78
|
+
# Jupyter Notebook
|
|
79
|
+
.ipynb_checkpoints
|
|
80
|
+
|
|
81
|
+
# IPython
|
|
82
|
+
profile_default/
|
|
83
|
+
ipython_config.py
|
|
84
|
+
|
|
85
|
+
# pyenv
|
|
86
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
87
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
88
|
+
# .python-version
|
|
89
|
+
|
|
90
|
+
# pipenv
|
|
91
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
92
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
93
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
94
|
+
# install all needed dependencies.
|
|
95
|
+
#Pipfile.lock
|
|
96
|
+
|
|
97
|
+
# UV
|
|
98
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
|
99
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
100
|
+
# commonly ignored for libraries.
|
|
101
|
+
#uv.lock
|
|
102
|
+
|
|
103
|
+
# poetry
|
|
104
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
105
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
106
|
+
# commonly ignored for libraries.
|
|
107
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
108
|
+
#poetry.lock
|
|
109
|
+
#poetry.toml
|
|
110
|
+
|
|
111
|
+
# pdm
|
|
112
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
113
|
+
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
|
114
|
+
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
|
115
|
+
#pdm.lock
|
|
116
|
+
#pdm.toml
|
|
117
|
+
.pdm-python
|
|
118
|
+
.pdm-build/
|
|
119
|
+
|
|
120
|
+
# pixi
|
|
121
|
+
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
|
122
|
+
#pixi.lock
|
|
123
|
+
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
|
124
|
+
# in the .venv directory. It is recommended not to include this directory in version control.
|
|
125
|
+
.pixi
|
|
126
|
+
|
|
127
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
128
|
+
__pypackages__/
|
|
129
|
+
|
|
130
|
+
# Celery stuff
|
|
131
|
+
celerybeat-schedule
|
|
132
|
+
celerybeat.pid
|
|
133
|
+
|
|
134
|
+
# SageMath parsed files
|
|
135
|
+
*.sage.py
|
|
136
|
+
|
|
137
|
+
# Environments
|
|
138
|
+
.env
|
|
139
|
+
.envrc
|
|
140
|
+
.venv
|
|
141
|
+
env/
|
|
142
|
+
venv/
|
|
143
|
+
ENV/
|
|
144
|
+
env.bak/
|
|
145
|
+
venv.bak/
|
|
146
|
+
|
|
147
|
+
# Spyder project settings
|
|
148
|
+
.spyderproject
|
|
149
|
+
.spyproject
|
|
150
|
+
|
|
151
|
+
# Rope project settings
|
|
152
|
+
.ropeproject
|
|
153
|
+
|
|
154
|
+
# mkdocs documentation
|
|
155
|
+
/site
|
|
156
|
+
|
|
157
|
+
# mypy
|
|
158
|
+
.mypy_cache/
|
|
159
|
+
.dmypy.json
|
|
160
|
+
dmypy.json
|
|
161
|
+
|
|
162
|
+
# Pyre type checker
|
|
163
|
+
.pyre/
|
|
164
|
+
|
|
165
|
+
# pytype static type analyzer
|
|
166
|
+
.pytype/
|
|
167
|
+
|
|
168
|
+
# Cython debug symbols
|
|
169
|
+
cython_debug/
|
|
170
|
+
|
|
171
|
+
# PyCharm
|
|
172
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
173
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
174
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
175
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
176
|
+
#.idea/
|
|
177
|
+
|
|
178
|
+
# Abstra
|
|
179
|
+
# Abstra is an AI-powered process automation framework.
|
|
180
|
+
# Ignore directories containing user credentials, local state, and settings.
|
|
181
|
+
# Learn more at https://abstra.io/docs
|
|
182
|
+
.abstra/
|
|
183
|
+
|
|
184
|
+
# Visual Studio Code
|
|
185
|
+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
|
186
|
+
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
|
187
|
+
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
|
188
|
+
# you could uncomment the following to ignore the entire vscode folder
|
|
189
|
+
# .vscode/
|
|
190
|
+
|
|
191
|
+
# Ruff stuff:
|
|
192
|
+
.ruff_cache/
|
|
193
|
+
|
|
194
|
+
# PyPI configuration file
|
|
195
|
+
.pypirc
|
|
196
|
+
|
|
197
|
+
# Cursor
|
|
198
|
+
# Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
|
|
199
|
+
# exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
|
|
200
|
+
# refer to https://docs.cursor.com/context/ignore-files
|
|
201
|
+
.cursorignore
|
|
202
|
+
.cursorindexingignore
|
|
203
|
+
|
|
204
|
+
# Marimo
|
|
205
|
+
marimo/_static/
|
|
206
|
+
marimo/_lsp/
|
|
207
|
+
__marimo__/
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to Crucible will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.1.0] - 2026-04-21
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- Core Pydantic data models: `AgentTarget`, `Finding`, `ModuleResult`, `ScanResult`
|
|
14
|
+
- 50 prompt injection attack vectors (PI-001 through PI-050)
|
|
15
|
+
- 20 goal hijacking attack vectors (GH-001 through GH-020)
|
|
16
|
+
- 20 jailbreak attack vectors (JB-001 through JB-020)
|
|
17
|
+
- Security modules: `PromptInjectionModule`, `GoalHijackingModule`, `JailbreakModule`
|
|
18
|
+
- Async scan runner with parallel module execution via `anyio`
|
|
19
|
+
- CVSS-inspired scoring engine with letter grading (A+ through F)
|
|
20
|
+
- Rich terminal reporter with color-coded findings and score visualization
|
|
21
|
+
- JSON reporter for CI/CD integration
|
|
22
|
+
- Typer CLI with `init`, `scan`, and `report` commands
|
|
23
|
+
- Full type annotations with strict mypy compliance
|
|
24
|
+
- Comprehensive test suite (88%+ coverage)
|
|
25
|
+
- GitHub Actions CI/CD pipelines (lint, test, publish)
|
|
26
|
+
|
|
27
|
+
[Unreleased]: https://github.com/crucible-security/crucible/compare/v0.1.0...HEAD
|
|
28
|
+
[0.1.0]: https://github.com/crucible-security/crucible/releases/tag/v0.1.0
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# Contributing to Crucible
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing to Crucible! This guide will help you get started.
|
|
4
|
+
|
|
5
|
+
## Development Setup
|
|
6
|
+
|
|
7
|
+
### Prerequisites
|
|
8
|
+
|
|
9
|
+
- Python 3.9+
|
|
10
|
+
- Git
|
|
11
|
+
|
|
12
|
+
### Installation
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
# Clone the repository
|
|
16
|
+
git clone https://github.com/crucible-security/crucible.git
|
|
17
|
+
cd crucible
|
|
18
|
+
|
|
19
|
+
# Create a virtual environment
|
|
20
|
+
python -m venv .venv
|
|
21
|
+
source .venv/bin/activate # Linux/Mac
|
|
22
|
+
# .venv\Scripts\activate # Windows
|
|
23
|
+
|
|
24
|
+
# Install in development mode
|
|
25
|
+
pip install -e ".[dev]"
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Verify Installation
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
crucible --help
|
|
32
|
+
crucible --version
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Development Workflow
|
|
36
|
+
|
|
37
|
+
### Code Quality
|
|
38
|
+
|
|
39
|
+
We enforce strict code quality standards. Before submitting a PR, ensure:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# Format code
|
|
43
|
+
black crucible/ tests/
|
|
44
|
+
|
|
45
|
+
# Lint
|
|
46
|
+
ruff check crucible/ tests/
|
|
47
|
+
|
|
48
|
+
# Type check (strict mode)
|
|
49
|
+
mypy crucible/
|
|
50
|
+
|
|
51
|
+
# Run tests
|
|
52
|
+
pytest tests/ -v --cov=crucible
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Running a Scan
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Generate a config scaffold
|
|
59
|
+
crucible init
|
|
60
|
+
|
|
61
|
+
# Run a scan
|
|
62
|
+
crucible scan --target https://your-agent.com/api --name "My Agent"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Architecture
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
crucible/
|
|
69
|
+
__init__.py # Package root, public API
|
|
70
|
+
models.py # Pydantic data models
|
|
71
|
+
cli.py # Typer CLI interface
|
|
72
|
+
attacks/
|
|
73
|
+
base.py # BaseAttack ABC
|
|
74
|
+
prompt_injection.py # 50 PI attack vectors
|
|
75
|
+
goal_hijacking.py # 20 GH attack vectors
|
|
76
|
+
jailbreaks.py # 20 JB attack vectors
|
|
77
|
+
modules/
|
|
78
|
+
base.py # BaseModule ABC
|
|
79
|
+
security.py # Module registry
|
|
80
|
+
core/
|
|
81
|
+
runner.py # Async scan runner (anyio)
|
|
82
|
+
scorer.py # Scoring + grading engine
|
|
83
|
+
reporters/
|
|
84
|
+
terminal.py # Rich terminal output
|
|
85
|
+
json_reporter.py # JSON file export
|
|
86
|
+
tests/
|
|
87
|
+
conftest.py # Shared fixtures
|
|
88
|
+
test_models.py # Model validation tests
|
|
89
|
+
test_scorer.py # Scoring engine tests
|
|
90
|
+
test_attacks.py # Attack + module tests
|
|
91
|
+
test_cli.py # CLI integration tests
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Adding a New Attack
|
|
95
|
+
|
|
96
|
+
1. Create a new class in the appropriate attack module (e.g., `prompt_injection.py`):
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
class MyNewAttack(BaseAttack):
|
|
100
|
+
name = "PI-051"
|
|
101
|
+
title = "My New Attack"
|
|
102
|
+
category = AttackCategory.PROMPT_INJECTION
|
|
103
|
+
severity = Severity.HIGH
|
|
104
|
+
description = "What this attack tests."
|
|
105
|
+
remediation = "How to fix the vulnerability."
|
|
106
|
+
|
|
107
|
+
def get_payloads(self) -> list[str]:
|
|
108
|
+
return ["payload 1", "payload 2"]
|
|
109
|
+
|
|
110
|
+
def get_detection_patterns(self) -> list[str]:
|
|
111
|
+
return ["pattern_to_detect"]
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
2. Add the class to the attack registry list (e.g., `ALL_PROMPT_INJECTION_ATTACKS`).
|
|
115
|
+
3. Add tests in `test_attacks.py`.
|
|
116
|
+
4. Run the quality gate: `black`, `mypy`, `pytest`.
|
|
117
|
+
|
|
118
|
+
## Adding a New Module
|
|
119
|
+
|
|
120
|
+
1. Create a new class in `crucible/modules/security.py`:
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
class MyModule(BaseModule):
|
|
124
|
+
name = "my_module"
|
|
125
|
+
description = "Description of what this module tests."
|
|
126
|
+
category = AttackCategory.PROMPT_INJECTION
|
|
127
|
+
|
|
128
|
+
def get_attacks(self) -> list[BaseAttack]:
|
|
129
|
+
return [MyAttack1(), MyAttack2()]
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
2. Add it to `ALL_SECURITY_MODULES`.
|
|
133
|
+
3. Add tests in `test_attacks.py`.
|
|
134
|
+
|
|
135
|
+
## Pull Request Guidelines
|
|
136
|
+
|
|
137
|
+
- **One PR per feature/fix** -- keep changes focused.
|
|
138
|
+
- **Include tests** for all new functionality.
|
|
139
|
+
- **Pass all quality gates** before requesting review.
|
|
140
|
+
- **Write descriptive commit messages** following [Conventional Commits](https://www.conventionalcommits.org/).
|
|
141
|
+
- **Update CHANGELOG.md** with your changes under `[Unreleased]`.
|
|
142
|
+
|
|
143
|
+
## Commit Message Format
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
<type>: <description>
|
|
147
|
+
|
|
148
|
+
feat: add new XSS attack vectors
|
|
149
|
+
fix: handle timeout in scan runner
|
|
150
|
+
test: add scorer edge case tests
|
|
151
|
+
docs: update contributing guide
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Reporting Issues
|
|
155
|
+
|
|
156
|
+
Use [GitHub Issues](https://github.com/crucible-security/crucible/issues) to report bugs or request features. Please include:
|
|
157
|
+
|
|
158
|
+
- Steps to reproduce
|
|
159
|
+
- Expected vs. actual behavior
|
|
160
|
+
- Python version and OS
|
|
161
|
+
- Crucible version (`crucible --version`)
|
|
162
|
+
|
|
163
|
+
## License
|
|
164
|
+
|
|
165
|
+
By contributing, you agree that your contributions will be licensed under the [Apache 2.0 License](LICENSE).
|