strix-agent 0.4.0__py3-none-any.whl → 0.6.2__py3-none-any.whl
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.
- strix/agents/StrixAgent/strix_agent.py +3 -3
- strix/agents/StrixAgent/system_prompt.jinja +30 -26
- strix/agents/base_agent.py +159 -75
- strix/agents/state.py +5 -2
- strix/config/__init__.py +12 -0
- strix/config/config.py +172 -0
- strix/interface/assets/tui_styles.tcss +195 -230
- strix/interface/cli.py +16 -41
- strix/interface/main.py +151 -74
- strix/interface/streaming_parser.py +119 -0
- strix/interface/tool_components/__init__.py +4 -0
- strix/interface/tool_components/agent_message_renderer.py +190 -0
- strix/interface/tool_components/agents_graph_renderer.py +54 -38
- strix/interface/tool_components/base_renderer.py +68 -36
- strix/interface/tool_components/browser_renderer.py +106 -91
- strix/interface/tool_components/file_edit_renderer.py +117 -36
- strix/interface/tool_components/finish_renderer.py +43 -10
- strix/interface/tool_components/notes_renderer.py +63 -38
- strix/interface/tool_components/proxy_renderer.py +133 -92
- strix/interface/tool_components/python_renderer.py +121 -8
- strix/interface/tool_components/registry.py +19 -12
- strix/interface/tool_components/reporting_renderer.py +196 -28
- strix/interface/tool_components/scan_info_renderer.py +22 -19
- strix/interface/tool_components/terminal_renderer.py +270 -90
- strix/interface/tool_components/thinking_renderer.py +8 -6
- strix/interface/tool_components/todo_renderer.py +225 -0
- strix/interface/tool_components/user_message_renderer.py +26 -19
- strix/interface/tool_components/web_search_renderer.py +7 -6
- strix/interface/tui.py +907 -262
- strix/interface/utils.py +236 -4
- strix/llm/__init__.py +6 -2
- strix/llm/config.py +8 -5
- strix/llm/dedupe.py +217 -0
- strix/llm/llm.py +209 -356
- strix/llm/memory_compressor.py +6 -5
- strix/llm/utils.py +17 -8
- strix/runtime/__init__.py +12 -3
- strix/runtime/docker_runtime.py +121 -202
- strix/runtime/tool_server.py +55 -95
- strix/skills/README.md +64 -0
- strix/skills/__init__.py +110 -0
- strix/{prompts → skills}/frameworks/nextjs.jinja +26 -0
- strix/skills/scan_modes/deep.jinja +145 -0
- strix/skills/scan_modes/quick.jinja +63 -0
- strix/skills/scan_modes/standard.jinja +91 -0
- strix/telemetry/README.md +38 -0
- strix/telemetry/__init__.py +7 -1
- strix/telemetry/posthog.py +137 -0
- strix/telemetry/tracer.py +194 -54
- strix/tools/__init__.py +11 -4
- strix/tools/agents_graph/agents_graph_actions.py +20 -21
- strix/tools/agents_graph/agents_graph_actions_schema.xml +8 -8
- strix/tools/browser/browser_actions.py +10 -6
- strix/tools/browser/browser_actions_schema.xml +6 -1
- strix/tools/browser/browser_instance.py +96 -48
- strix/tools/browser/tab_manager.py +121 -102
- strix/tools/context.py +12 -0
- strix/tools/executor.py +63 -4
- strix/tools/file_edit/file_edit_actions.py +6 -3
- strix/tools/file_edit/file_edit_actions_schema.xml +45 -3
- strix/tools/finish/finish_actions.py +80 -105
- strix/tools/finish/finish_actions_schema.xml +121 -14
- strix/tools/notes/notes_actions.py +6 -33
- strix/tools/notes/notes_actions_schema.xml +50 -46
- strix/tools/proxy/proxy_actions.py +14 -2
- strix/tools/proxy/proxy_actions_schema.xml +0 -1
- strix/tools/proxy/proxy_manager.py +28 -16
- strix/tools/python/python_actions.py +2 -2
- strix/tools/python/python_actions_schema.xml +9 -1
- strix/tools/python/python_instance.py +39 -37
- strix/tools/python/python_manager.py +43 -31
- strix/tools/registry.py +73 -12
- strix/tools/reporting/reporting_actions.py +218 -31
- strix/tools/reporting/reporting_actions_schema.xml +256 -8
- strix/tools/terminal/terminal_actions.py +2 -2
- strix/tools/terminal/terminal_actions_schema.xml +6 -0
- strix/tools/terminal/terminal_manager.py +41 -30
- strix/tools/thinking/thinking_actions_schema.xml +27 -25
- strix/tools/todo/__init__.py +18 -0
- strix/tools/todo/todo_actions.py +568 -0
- strix/tools/todo/todo_actions_schema.xml +225 -0
- strix/utils/__init__.py +0 -0
- strix/utils/resource_paths.py +13 -0
- {strix_agent-0.4.0.dist-info → strix_agent-0.6.2.dist-info}/METADATA +90 -65
- strix_agent-0.6.2.dist-info/RECORD +134 -0
- {strix_agent-0.4.0.dist-info → strix_agent-0.6.2.dist-info}/WHEEL +1 -1
- strix/llm/request_queue.py +0 -87
- strix/prompts/README.md +0 -64
- strix/prompts/__init__.py +0 -109
- strix_agent-0.4.0.dist-info/RECORD +0 -118
- /strix/{prompts → skills}/cloud/.gitkeep +0 -0
- /strix/{prompts → skills}/coordination/root_agent.jinja +0 -0
- /strix/{prompts → skills}/custom/.gitkeep +0 -0
- /strix/{prompts → skills}/frameworks/fastapi.jinja +0 -0
- /strix/{prompts → skills}/protocols/graphql.jinja +0 -0
- /strix/{prompts → skills}/reconnaissance/.gitkeep +0 -0
- /strix/{prompts → skills}/technologies/firebase_firestore.jinja +0 -0
- /strix/{prompts → skills}/technologies/supabase.jinja +0 -0
- /strix/{prompts → skills}/vulnerabilities/authentication_jwt.jinja +0 -0
- /strix/{prompts → skills}/vulnerabilities/broken_function_level_authorization.jinja +0 -0
- /strix/{prompts → skills}/vulnerabilities/business_logic.jinja +0 -0
- /strix/{prompts → skills}/vulnerabilities/csrf.jinja +0 -0
- /strix/{prompts → skills}/vulnerabilities/idor.jinja +0 -0
- /strix/{prompts → skills}/vulnerabilities/information_disclosure.jinja +0 -0
- /strix/{prompts → skills}/vulnerabilities/insecure_file_uploads.jinja +0 -0
- /strix/{prompts → skills}/vulnerabilities/mass_assignment.jinja +0 -0
- /strix/{prompts → skills}/vulnerabilities/open_redirect.jinja +0 -0
- /strix/{prompts → skills}/vulnerabilities/path_traversal_lfi_rfi.jinja +0 -0
- /strix/{prompts → skills}/vulnerabilities/race_conditions.jinja +0 -0
- /strix/{prompts → skills}/vulnerabilities/rce.jinja +0 -0
- /strix/{prompts → skills}/vulnerabilities/sql_injection.jinja +0 -0
- /strix/{prompts → skills}/vulnerabilities/ssrf.jinja +0 -0
- /strix/{prompts → skills}/vulnerabilities/subdomain_takeover.jinja +0 -0
- /strix/{prompts → skills}/vulnerabilities/xss.jinja +0 -0
- /strix/{prompts → skills}/vulnerabilities/xxe.jinja +0 -0
- {strix_agent-0.4.0.dist-info → strix_agent-0.6.2.dist-info}/entry_points.txt +0 -0
- {strix_agent-0.4.0.dist-info → strix_agent-0.6.2.dist-info/licenses}/LICENSE +0 -0
strix/runtime/tool_server.py
CHANGED
|
@@ -2,11 +2,9 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import argparse
|
|
4
4
|
import asyncio
|
|
5
|
-
import logging
|
|
6
5
|
import os
|
|
7
6
|
import signal
|
|
8
7
|
import sys
|
|
9
|
-
from multiprocessing import Process, Queue
|
|
10
8
|
from typing import Any
|
|
11
9
|
|
|
12
10
|
import uvicorn
|
|
@@ -23,17 +21,22 @@ parser = argparse.ArgumentParser(description="Start Strix tool server")
|
|
|
23
21
|
parser.add_argument("--token", required=True, help="Authentication token")
|
|
24
22
|
parser.add_argument("--host", default="0.0.0.0", help="Host to bind to") # nosec
|
|
25
23
|
parser.add_argument("--port", type=int, required=True, help="Port to bind to")
|
|
24
|
+
parser.add_argument(
|
|
25
|
+
"--timeout",
|
|
26
|
+
type=int,
|
|
27
|
+
default=120,
|
|
28
|
+
help="Hard timeout in seconds for each request execution (default: 120)",
|
|
29
|
+
)
|
|
26
30
|
|
|
27
31
|
args = parser.parse_args()
|
|
28
32
|
EXPECTED_TOKEN = args.token
|
|
33
|
+
REQUEST_TIMEOUT = args.timeout
|
|
29
34
|
|
|
30
35
|
app = FastAPI()
|
|
31
36
|
security = HTTPBearer()
|
|
32
|
-
|
|
33
37
|
security_dependency = Depends(security)
|
|
34
38
|
|
|
35
|
-
|
|
36
|
-
agent_queues: dict[str, dict[str, Queue[Any]]] = {}
|
|
39
|
+
agent_tasks: dict[str, asyncio.Task[Any]] = {}
|
|
37
40
|
|
|
38
41
|
|
|
39
42
|
def verify_token(credentials: HTTPAuthorizationCredentials) -> str:
|
|
@@ -65,60 +68,19 @@ class ToolExecutionResponse(BaseModel):
|
|
|
65
68
|
error: str | None = None
|
|
66
69
|
|
|
67
70
|
|
|
68
|
-
def
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
root_logger = logging.getLogger()
|
|
72
|
-
root_logger.handlers = [null_handler]
|
|
73
|
-
root_logger.setLevel(logging.CRITICAL)
|
|
74
|
-
|
|
75
|
-
from strix.tools.argument_parser import ArgumentConversionError, convert_arguments
|
|
71
|
+
async def _run_tool(agent_id: str, tool_name: str, kwargs: dict[str, Any]) -> Any:
|
|
72
|
+
from strix.tools.argument_parser import convert_arguments
|
|
73
|
+
from strix.tools.context import set_current_agent_id
|
|
76
74
|
from strix.tools.registry import get_tool_by_name
|
|
77
75
|
|
|
78
|
-
|
|
79
|
-
try:
|
|
80
|
-
request = request_queue.get()
|
|
81
|
-
|
|
82
|
-
if request is None:
|
|
83
|
-
break
|
|
84
|
-
|
|
85
|
-
tool_name = request["tool_name"]
|
|
86
|
-
kwargs = request["kwargs"]
|
|
87
|
-
|
|
88
|
-
try:
|
|
89
|
-
tool_func = get_tool_by_name(tool_name)
|
|
90
|
-
if not tool_func:
|
|
91
|
-
response_queue.put({"error": f"Tool '{tool_name}' not found"})
|
|
92
|
-
continue
|
|
93
|
-
|
|
94
|
-
converted_kwargs = convert_arguments(tool_func, kwargs)
|
|
95
|
-
result = tool_func(**converted_kwargs)
|
|
96
|
-
|
|
97
|
-
response_queue.put({"result": result})
|
|
76
|
+
set_current_agent_id(agent_id)
|
|
98
77
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
response_queue.put({"error": f"Tool execution error: {e}"})
|
|
78
|
+
tool_func = get_tool_by_name(tool_name)
|
|
79
|
+
if not tool_func:
|
|
80
|
+
raise ValueError(f"Tool '{tool_name}' not found")
|
|
103
81
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
def ensure_agent_process(agent_id: str) -> tuple[Queue[Any], Queue[Any]]:
|
|
109
|
-
if agent_id not in agent_processes:
|
|
110
|
-
request_queue: Queue[Any] = Queue()
|
|
111
|
-
response_queue: Queue[Any] = Queue()
|
|
112
|
-
|
|
113
|
-
process = Process(
|
|
114
|
-
target=agent_worker, args=(agent_id, request_queue, response_queue), daemon=True
|
|
115
|
-
)
|
|
116
|
-
process.start()
|
|
117
|
-
|
|
118
|
-
agent_processes[agent_id] = {"process": process, "pid": process.pid}
|
|
119
|
-
agent_queues[agent_id] = {"request": request_queue, "response": response_queue}
|
|
120
|
-
|
|
121
|
-
return agent_queues[agent_id]["request"], agent_queues[agent_id]["response"]
|
|
82
|
+
converted_kwargs = convert_arguments(tool_func, kwargs)
|
|
83
|
+
return await asyncio.to_thread(tool_func, **converted_kwargs)
|
|
122
84
|
|
|
123
85
|
|
|
124
86
|
@app.post("/execute", response_model=ToolExecutionResponse)
|
|
@@ -127,20 +89,42 @@ async def execute_tool(
|
|
|
127
89
|
) -> ToolExecutionResponse:
|
|
128
90
|
verify_token(credentials)
|
|
129
91
|
|
|
130
|
-
|
|
92
|
+
agent_id = request.agent_id
|
|
93
|
+
|
|
94
|
+
if agent_id in agent_tasks:
|
|
95
|
+
old_task = agent_tasks[agent_id]
|
|
96
|
+
if not old_task.done():
|
|
97
|
+
old_task.cancel()
|
|
131
98
|
|
|
132
|
-
|
|
99
|
+
task = asyncio.create_task(
|
|
100
|
+
asyncio.wait_for(
|
|
101
|
+
_run_tool(agent_id, request.tool_name, request.kwargs), timeout=REQUEST_TIMEOUT
|
|
102
|
+
)
|
|
103
|
+
)
|
|
104
|
+
agent_tasks[agent_id] = task
|
|
133
105
|
|
|
134
106
|
try:
|
|
135
|
-
|
|
136
|
-
|
|
107
|
+
result = await task
|
|
108
|
+
return ToolExecutionResponse(result=result)
|
|
109
|
+
|
|
110
|
+
except asyncio.CancelledError:
|
|
111
|
+
return ToolExecutionResponse(error="Cancelled by newer request")
|
|
112
|
+
|
|
113
|
+
except TimeoutError:
|
|
114
|
+
return ToolExecutionResponse(error=f"Tool timed out after {REQUEST_TIMEOUT}s")
|
|
115
|
+
|
|
116
|
+
except ValidationError as e:
|
|
117
|
+
return ToolExecutionResponse(error=f"Invalid arguments: {e}")
|
|
137
118
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
return ToolExecutionResponse(result=response.get("result"))
|
|
119
|
+
except (ValueError, RuntimeError, ImportError) as e:
|
|
120
|
+
return ToolExecutionResponse(error=f"Tool execution error: {e}")
|
|
141
121
|
|
|
142
|
-
except
|
|
143
|
-
return ToolExecutionResponse(error=f"
|
|
122
|
+
except Exception as e: # noqa: BLE001
|
|
123
|
+
return ToolExecutionResponse(error=f"Unexpected error: {e}")
|
|
124
|
+
|
|
125
|
+
finally:
|
|
126
|
+
if agent_tasks.get(agent_id) is task:
|
|
127
|
+
del agent_tasks[agent_id]
|
|
144
128
|
|
|
145
129
|
|
|
146
130
|
@app.post("/register_agent")
|
|
@@ -148,8 +132,6 @@ async def register_agent(
|
|
|
148
132
|
agent_id: str, credentials: HTTPAuthorizationCredentials = security_dependency
|
|
149
133
|
) -> dict[str, str]:
|
|
150
134
|
verify_token(credentials)
|
|
151
|
-
|
|
152
|
-
ensure_agent_process(agent_id)
|
|
153
135
|
return {"status": "registered", "agent_id": agent_id}
|
|
154
136
|
|
|
155
137
|
|
|
@@ -160,35 +142,16 @@ async def health_check() -> dict[str, Any]:
|
|
|
160
142
|
"sandbox_mode": str(SANDBOX_MODE),
|
|
161
143
|
"environment": "sandbox" if SANDBOX_MODE else "main",
|
|
162
144
|
"auth_configured": "true" if EXPECTED_TOKEN else "false",
|
|
163
|
-
"active_agents": len(
|
|
164
|
-
"agents": list(
|
|
145
|
+
"active_agents": len(agent_tasks),
|
|
146
|
+
"agents": list(agent_tasks.keys()),
|
|
165
147
|
}
|
|
166
148
|
|
|
167
149
|
|
|
168
|
-
def cleanup_all_agents() -> None:
|
|
169
|
-
for agent_id in list(agent_processes.keys()):
|
|
170
|
-
try:
|
|
171
|
-
agent_queues[agent_id]["request"].put(None)
|
|
172
|
-
process = agent_processes[agent_id]["process"]
|
|
173
|
-
|
|
174
|
-
process.join(timeout=1)
|
|
175
|
-
|
|
176
|
-
if process.is_alive():
|
|
177
|
-
process.terminate()
|
|
178
|
-
process.join(timeout=1)
|
|
179
|
-
|
|
180
|
-
if process.is_alive():
|
|
181
|
-
process.kill()
|
|
182
|
-
|
|
183
|
-
except (BrokenPipeError, EOFError, OSError):
|
|
184
|
-
pass
|
|
185
|
-
except (RuntimeError, ValueError) as e:
|
|
186
|
-
logging.getLogger(__name__).debug(f"Error during agent cleanup: {e}")
|
|
187
|
-
|
|
188
|
-
|
|
189
150
|
def signal_handler(_signum: int, _frame: Any) -> None:
|
|
190
|
-
|
|
191
|
-
|
|
151
|
+
if hasattr(signal, "SIGPIPE"):
|
|
152
|
+
signal.signal(signal.SIGPIPE, signal.SIG_IGN)
|
|
153
|
+
for task in agent_tasks.values():
|
|
154
|
+
task.cancel()
|
|
192
155
|
sys.exit(0)
|
|
193
156
|
|
|
194
157
|
|
|
@@ -199,7 +162,4 @@ signal.signal(signal.SIGTERM, signal_handler)
|
|
|
199
162
|
signal.signal(signal.SIGINT, signal_handler)
|
|
200
163
|
|
|
201
164
|
if __name__ == "__main__":
|
|
202
|
-
|
|
203
|
-
uvicorn.run(app, host=args.host, port=args.port, log_level="info")
|
|
204
|
-
finally:
|
|
205
|
-
cleanup_all_agents()
|
|
165
|
+
uvicorn.run(app, host=args.host, port=args.port, log_level="info")
|
strix/skills/README.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# 📚 Strix Skills
|
|
2
|
+
|
|
3
|
+
## 🎯 Overview
|
|
4
|
+
|
|
5
|
+
Skills are specialized knowledge packages that enhance Strix agents with deep expertise in specific vulnerability types, technologies, and testing methodologies. Each skill provides advanced techniques, practical examples, and validation methods that go beyond baseline security knowledge.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 🏗️ Architecture
|
|
10
|
+
|
|
11
|
+
### How Skills Work
|
|
12
|
+
|
|
13
|
+
When an agent is created, it can load up to 5 specialized skills relevant to the specific subtask and context at hand:
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
# Agent creation with specialized skills
|
|
17
|
+
create_agent(
|
|
18
|
+
task="Test authentication mechanisms in API",
|
|
19
|
+
name="Auth Specialist",
|
|
20
|
+
skills="authentication_jwt,business_logic"
|
|
21
|
+
)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The skills are dynamically injected into the agent's system prompt, allowing it to operate with deep expertise tailored to the specific vulnerability types or technologies required for the task at hand.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 📁 Skill Categories
|
|
29
|
+
|
|
30
|
+
| Category | Purpose |
|
|
31
|
+
|----------|---------|
|
|
32
|
+
| **`/vulnerabilities`** | Advanced testing techniques for core vulnerability classes like authentication bypasses, business logic flaws, and race conditions |
|
|
33
|
+
| **`/frameworks`** | Specific testing methods for popular frameworks e.g. Django, Express, FastAPI, and Next.js |
|
|
34
|
+
| **`/technologies`** | Specialized techniques for third-party services such as Supabase, Firebase, Auth0, and payment gateways |
|
|
35
|
+
| **`/protocols`** | Protocol-specific testing patterns for GraphQL, WebSocket, OAuth, and other communication standards |
|
|
36
|
+
| **`/cloud`** | Cloud provider security testing for AWS, Azure, GCP, and Kubernetes environments |
|
|
37
|
+
| **`/reconnaissance`** | Advanced information gathering and enumeration techniques for comprehensive attack surface mapping |
|
|
38
|
+
| **`/custom`** | Community-contributed skills for specialized or industry-specific testing scenarios |
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 🎨 Creating New Skills
|
|
43
|
+
|
|
44
|
+
### What Should a Skill Contain?
|
|
45
|
+
|
|
46
|
+
A good skill is a structured knowledge package that typically includes:
|
|
47
|
+
|
|
48
|
+
- **Advanced techniques** - Non-obvious methods specific to the task and domain
|
|
49
|
+
- **Practical examples** - Working payloads, commands, or test cases with variations
|
|
50
|
+
- **Validation methods** - How to confirm findings and avoid false positives
|
|
51
|
+
- **Context-specific insights** - Environment and version nuances, configuration-dependent behavior, and edge cases
|
|
52
|
+
|
|
53
|
+
Skills use XML-style tags for structure and focus on deep, specialized knowledge that significantly enhances agent capabilities for that specific context.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## 🤝 Contributing
|
|
58
|
+
|
|
59
|
+
Community contributions are more than welcome — contribute new skills via [pull requests](https://github.com/usestrix/strix/pulls) or [GitHub issues](https://github.com/usestrix/strix/issues) to help expand the collection and improve extensibility for Strix agents.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
> [!NOTE]
|
|
64
|
+
> **Work in Progress** - We're actively expanding the skills collection with specialized techniques and new categories.
|
strix/skills/__init__.py
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
from jinja2 import Environment
|
|
2
|
+
|
|
3
|
+
from strix.utils.resource_paths import get_strix_resource_path
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def get_available_skills() -> dict[str, list[str]]:
|
|
7
|
+
skills_dir = get_strix_resource_path("skills")
|
|
8
|
+
available_skills: dict[str, list[str]] = {}
|
|
9
|
+
|
|
10
|
+
if not skills_dir.exists():
|
|
11
|
+
return available_skills
|
|
12
|
+
|
|
13
|
+
for category_dir in skills_dir.iterdir():
|
|
14
|
+
if category_dir.is_dir() and not category_dir.name.startswith("__"):
|
|
15
|
+
category_name = category_dir.name
|
|
16
|
+
skills = []
|
|
17
|
+
|
|
18
|
+
for file_path in category_dir.glob("*.jinja"):
|
|
19
|
+
skill_name = file_path.stem
|
|
20
|
+
skills.append(skill_name)
|
|
21
|
+
|
|
22
|
+
if skills:
|
|
23
|
+
available_skills[category_name] = sorted(skills)
|
|
24
|
+
|
|
25
|
+
return available_skills
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def get_all_skill_names() -> set[str]:
|
|
29
|
+
all_skills = set()
|
|
30
|
+
for category_skills in get_available_skills().values():
|
|
31
|
+
all_skills.update(category_skills)
|
|
32
|
+
return all_skills
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def validate_skill_names(skill_names: list[str]) -> dict[str, list[str]]:
|
|
36
|
+
available_skills = get_all_skill_names()
|
|
37
|
+
valid_skills = []
|
|
38
|
+
invalid_skills = []
|
|
39
|
+
|
|
40
|
+
for skill_name in skill_names:
|
|
41
|
+
if skill_name in available_skills:
|
|
42
|
+
valid_skills.append(skill_name)
|
|
43
|
+
else:
|
|
44
|
+
invalid_skills.append(skill_name)
|
|
45
|
+
|
|
46
|
+
return {"valid": valid_skills, "invalid": invalid_skills}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def generate_skills_description() -> str:
|
|
50
|
+
available_skills = get_available_skills()
|
|
51
|
+
|
|
52
|
+
if not available_skills:
|
|
53
|
+
return "No skills available"
|
|
54
|
+
|
|
55
|
+
all_skill_names = get_all_skill_names()
|
|
56
|
+
|
|
57
|
+
if not all_skill_names:
|
|
58
|
+
return "No skills available"
|
|
59
|
+
|
|
60
|
+
sorted_skills = sorted(all_skill_names)
|
|
61
|
+
skills_str = ", ".join(sorted_skills)
|
|
62
|
+
|
|
63
|
+
description = f"List of skills to load for this agent (max 5). Available skills: {skills_str}. "
|
|
64
|
+
|
|
65
|
+
example_skills = sorted_skills[:2]
|
|
66
|
+
if example_skills:
|
|
67
|
+
example = f"Example: {', '.join(example_skills)} for specialized agent"
|
|
68
|
+
description += example
|
|
69
|
+
|
|
70
|
+
return description
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def load_skills(skill_names: list[str], jinja_env: Environment) -> dict[str, str]:
|
|
74
|
+
import logging
|
|
75
|
+
|
|
76
|
+
logger = logging.getLogger(__name__)
|
|
77
|
+
skill_content = {}
|
|
78
|
+
skills_dir = get_strix_resource_path("skills")
|
|
79
|
+
|
|
80
|
+
available_skills = get_available_skills()
|
|
81
|
+
|
|
82
|
+
for skill_name in skill_names:
|
|
83
|
+
try:
|
|
84
|
+
skill_path = None
|
|
85
|
+
|
|
86
|
+
if "/" in skill_name:
|
|
87
|
+
skill_path = f"{skill_name}.jinja"
|
|
88
|
+
else:
|
|
89
|
+
for category, skills in available_skills.items():
|
|
90
|
+
if skill_name in skills:
|
|
91
|
+
skill_path = f"{category}/{skill_name}.jinja"
|
|
92
|
+
break
|
|
93
|
+
|
|
94
|
+
if not skill_path:
|
|
95
|
+
root_candidate = f"{skill_name}.jinja"
|
|
96
|
+
if (skills_dir / root_candidate).exists():
|
|
97
|
+
skill_path = root_candidate
|
|
98
|
+
|
|
99
|
+
if skill_path and (skills_dir / skill_path).exists():
|
|
100
|
+
template = jinja_env.get_template(skill_path)
|
|
101
|
+
var_name = skill_name.split("/")[-1]
|
|
102
|
+
skill_content[var_name] = template.render()
|
|
103
|
+
logger.info(f"Loaded skill: {skill_name} -> {var_name}")
|
|
104
|
+
else:
|
|
105
|
+
logger.warning(f"Skill not found: {skill_name}")
|
|
106
|
+
|
|
107
|
+
except (FileNotFoundError, OSError, ValueError) as e:
|
|
108
|
+
logger.warning(f"Failed to load skill {skill_name}: {e}")
|
|
109
|
+
|
|
110
|
+
return skill_content
|
|
@@ -31,6 +31,18 @@
|
|
|
31
31
|
</high_value_targets>
|
|
32
32
|
|
|
33
33
|
<advanced_techniques>
|
|
34
|
+
<route_enumeration>
|
|
35
|
+
- __BUILD_MANIFEST.sortedPages: Execute `console.log(__BUILD_MANIFEST.sortedPages.join('\n'))` in browser console to instantly reveal all registered routes (Pages Router and static App Router paths compiled at build time)
|
|
36
|
+
- __NEXT_DATA__: Inspect `<script id="__NEXT_DATA__">` for serverside props, pageProps, buildId, and dynamic route params on current page; reveals data flow and prop structure
|
|
37
|
+
- Source maps exposure: Check `/_next/static/` for exposed .map files revealing full route structure, server action IDs, API endpoints, and internal function names
|
|
38
|
+
- Client bundle mining: Search main-*.js and page chunks for route definitions; grep for 'pathname:', 'href:', '__next_route__', 'serverActions', and API endpoint strings
|
|
39
|
+
- Static chunk enumeration: Probe `/_next/static/chunks/pages/` and `/_next/static/chunks/app/` for build artifacts; filenames map directly to routes (e.g., `admin.js` → `/admin`)
|
|
40
|
+
- Build manifest fetch: GET `/_next/static/<buildId>/_buildManifest.js` and `/_next/static/<buildId>/_ssgManifest.js` for complete route and static generation metadata
|
|
41
|
+
- Sitemap/robots leakage: Check `/sitemap.xml`, `/robots.txt`, and `/sitemap-*.xml` for unintended exposure of admin/internal/preview paths
|
|
42
|
+
- Server action discovery: Inspect Network tab for POST requests with `Next-Action` header; extract action IDs from response streams and client hydration data
|
|
43
|
+
- Environment variable leakage: Execute `Object.keys(process.env).filter(k => k.startsWith('NEXT_PUBLIC_'))` in console to list public env vars; grep bundles for 'API_KEY', 'SECRET', 'TOKEN', 'PASSWORD' to find accidentally leaked credentials
|
|
44
|
+
</route_enumeration>
|
|
45
|
+
|
|
34
46
|
<middleware_bypass>
|
|
35
47
|
- Test for CVE-class middleware bypass via `x-middleware-subrequest` crafting and `x-nextjs-data` probing. Look for 307 + `x-middleware-rewrite`/`x-nextjs-redirect` headers and attempt bypass on protected routes.
|
|
36
48
|
- Attempt direct route access on Node vs Edge runtimes; confirm protection parity.
|
|
@@ -80,6 +92,14 @@
|
|
|
80
92
|
- Identify `dangerouslySetInnerHTML`, Markdown renderers, and user-controlled href/src attributes. Validate CSP/Trusted Types coverage for SSR/CSR/hydration.
|
|
81
93
|
- Attack hydration boundaries: server vs client render mismatches can enable gadget-based XSS.
|
|
82
94
|
</client_and_dom>
|
|
95
|
+
|
|
96
|
+
<data_fetching_over_exposure>
|
|
97
|
+
- getServerSideProps/getStaticProps leakage: Execute `JSON.parse(document.getElementById('__NEXT_DATA__').textContent).props.pageProps` in console to inspect all server-fetched data; look for sensitive fields (emails, tokens, internal IDs, full user objects) passed to client but not rendered in UI
|
|
98
|
+
- Over-fetched database queries: Check if pageProps include entire user records, relations, or admin-only fields when only username is displayed; common when using ORM select-all patterns
|
|
99
|
+
- API response pass-through: Verify if API responses are sanitized before passing to props; developers often forward entire responses including metadata, cursors, or debug info
|
|
100
|
+
- Environment-dependent data: Test if staging/dev accidentally exposes more fields in props than production due to inconsistent serialization logic
|
|
101
|
+
- Nested object inspection: Drill into nested props objects; look for `_metadata`, `_internal`, `__typename` (GraphQL), or framework-added fields containing sensitive context
|
|
102
|
+
</data_fetching_over_exposure>
|
|
83
103
|
</advanced_techniques>
|
|
84
104
|
|
|
85
105
|
<bypass_techniques>
|
|
@@ -87,6 +107,8 @@
|
|
|
87
107
|
- Method override/tunneling: `_method`, `X-HTTP-Method-Override`, GET on endpoints unexpectedly accepting writes.
|
|
88
108
|
- Case/param aliasing and query duplication affecting middleware vs handler parsing.
|
|
89
109
|
- Cache key confusion at CDN/proxy (lack of Vary on auth cookies/headers) to leak personalized SSR/ISR content.
|
|
110
|
+
- API route path normalization: Test `/api/users` vs `/api/users/` vs `/api//users` vs `/api/./users`; middleware may normalize differently than route handlers, allowing protection bypass. Try double slashes, trailing slashes, and dot segments.
|
|
111
|
+
- Parameter pollution: Send duplicate query params (`?id=1&id=2`) or array notation (`?filter[]=a&filter[]=b`) to exploit parsing differences between middleware (which may check first value) and handler (which may use last or array).
|
|
90
112
|
</bypass_techniques>
|
|
91
113
|
|
|
92
114
|
<special_contexts>
|
|
@@ -107,6 +129,10 @@
|
|
|
107
129
|
3. Demonstrate server action invocation outside UI with insufficient authorization checks.
|
|
108
130
|
4. Show middleware bypass (where applicable) with explicit headers and resulting protected content.
|
|
109
131
|
5. Include runtime parity checks (Edge vs Node) proving inconsistent enforcement.
|
|
132
|
+
6. For route enumeration: verify discovered routes return 200/403 (deployed) not 404 (build artifacts); test with authenticated vs unauthenticated requests.
|
|
133
|
+
7. For leaked credentials: test API keys with minimal read-only calls; filter placeholders (YOUR_API_KEY, demo-token); confirm keys match provider patterns (sk_live_*, pk_prod_*).
|
|
134
|
+
8. For __NEXT_DATA__ over-exposure: test cross-user (User A's props should not contain User B's PII); verify exposed fields are not in DOM; validate token validity with API calls.
|
|
135
|
+
9. For path normalization bypasses: show differential responses (403 vs 200 for path variants); redirects (307/308) don't count—only direct access bypasses matter.
|
|
110
136
|
</validation>
|
|
111
137
|
|
|
112
138
|
<pro_tips>
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
<scan_mode>
|
|
2
|
+
DEEP SCAN MODE - Exhaustive Security Assessment
|
|
3
|
+
|
|
4
|
+
This mode is for thorough security reviews where finding vulnerabilities is critical.
|
|
5
|
+
|
|
6
|
+
PHASE 1: EXHAUSTIVE RECONNAISSANCE AND MAPPING
|
|
7
|
+
Spend significant effort understanding the target before exploitation.
|
|
8
|
+
|
|
9
|
+
For whitebox (source code available):
|
|
10
|
+
- Map EVERY file, module, and code path in the repository
|
|
11
|
+
- Trace all entry points from HTTP handlers to database queries
|
|
12
|
+
- Identify all authentication mechanisms and their implementations
|
|
13
|
+
- Map all authorization checks and understand the access control model
|
|
14
|
+
- Identify all external service integrations and API calls
|
|
15
|
+
- Analyze all configuration files for secrets and misconfigurations
|
|
16
|
+
- Review all database schemas and understand data relationships
|
|
17
|
+
- Map all background jobs, cron tasks, and async processing
|
|
18
|
+
- Identify all serialization/deserialization points
|
|
19
|
+
- Review all file handling operations (upload, download, processing)
|
|
20
|
+
- Understand the deployment model and infrastructure assumptions
|
|
21
|
+
- Check all dependency versions against known CVE databases
|
|
22
|
+
|
|
23
|
+
For blackbox (no source code):
|
|
24
|
+
- Exhaustive subdomain enumeration using multiple sources and tools
|
|
25
|
+
- Full port scanning to identify all services
|
|
26
|
+
- Complete content discovery with multiple wordlists
|
|
27
|
+
- Technology fingerprinting on all discovered assets
|
|
28
|
+
- API endpoint discovery through documentation, JavaScript analysis, and fuzzing
|
|
29
|
+
- Identify all parameters including hidden and rarely-used ones
|
|
30
|
+
- Map all user roles by testing with different account types
|
|
31
|
+
- Understand rate limiting, WAF rules, and security controls in place
|
|
32
|
+
- Document the complete application architecture as understood from outside
|
|
33
|
+
|
|
34
|
+
EXECUTION STRATEGY - HIERARCHICAL AGENT SWARM:
|
|
35
|
+
After Phase 1 (Recon & Mapping) is complete:
|
|
36
|
+
1. Divide the application into major components/parts (e.g., Auth System, Payment Gateway, User Profile, Admin Panel)
|
|
37
|
+
2. Spawn a specialized subagent for EACH major component
|
|
38
|
+
3. Each component agent must then:
|
|
39
|
+
- Further subdivide its scope into subparts (e.g., Login Form, Registration API, Password Reset)
|
|
40
|
+
- Spawn sub-subagents for each distinct subpart
|
|
41
|
+
4. At the lowest level (specific functionality), spawn specialized agents for EACH potential vulnerability type:
|
|
42
|
+
- "Auth System" → "Login Form" → "SQLi Agent", "XSS Agent", "Auth Bypass Agent"
|
|
43
|
+
- This creates a massive parallel swarm covering every angle
|
|
44
|
+
- Do NOT overload a single agent with multiple vulnerability types
|
|
45
|
+
- Scale horizontally to maximum capacity
|
|
46
|
+
|
|
47
|
+
PHASE 2: DEEP BUSINESS LOGIC ANALYSIS
|
|
48
|
+
Understand the application deeply enough to find logic flaws:
|
|
49
|
+
- CREATE A FULL STORYBOARD of all user flows and state transitions
|
|
50
|
+
- Document every step of the business logic in a structured flow diagram
|
|
51
|
+
- Use the application extensively as every type of user to map the full lifecycle of data
|
|
52
|
+
- Document all state machines and workflows (e.g. Order Created -> Paid -> Shipped)
|
|
53
|
+
- Identify trust boundaries between components
|
|
54
|
+
- Map all integrations with third-party services
|
|
55
|
+
- Understand what invariants the application tries to maintain
|
|
56
|
+
- Identify all points where roles, privileges, or sensitive data changes hands
|
|
57
|
+
- Look for implicit assumptions in the business logic
|
|
58
|
+
- Consider multi-step attacks that abuse normal functionality
|
|
59
|
+
|
|
60
|
+
PHASE 3: COMPREHENSIVE ATTACK SURFACE TESTING
|
|
61
|
+
Test EVERY input vector with EVERY applicable technique.
|
|
62
|
+
|
|
63
|
+
Input Handling - Test all parameters, headers, cookies with:
|
|
64
|
+
- Multiple injection payloads (SQL, NoSQL, LDAP, XPath, Command, Template)
|
|
65
|
+
- Various encodings and bypass techniques (double encoding, unicode, null bytes)
|
|
66
|
+
- Boundary conditions and type confusion
|
|
67
|
+
- Large payloads and buffer-related issues
|
|
68
|
+
|
|
69
|
+
Authentication and Session:
|
|
70
|
+
- Exhaustive brute force protection testing
|
|
71
|
+
- Session fixation, hijacking, and prediction attacks
|
|
72
|
+
- JWT/token manipulation if applicable
|
|
73
|
+
- OAuth flow abuse scenarios
|
|
74
|
+
- Password reset flow vulnerabilities (token leakage, reuse, timing)
|
|
75
|
+
- Multi-factor authentication bypass techniques
|
|
76
|
+
- Account enumeration through all possible channels
|
|
77
|
+
|
|
78
|
+
Access Control:
|
|
79
|
+
- Test EVERY endpoint for horizontal and vertical access control
|
|
80
|
+
- Parameter tampering on all object references
|
|
81
|
+
- Forced browsing to all discovered resources
|
|
82
|
+
- HTTP method tampering
|
|
83
|
+
- Test access control after session changes (logout, role change)
|
|
84
|
+
|
|
85
|
+
File Operations:
|
|
86
|
+
- Exhaustive file upload bypass testing (extension, content-type, magic bytes)
|
|
87
|
+
- Path traversal on all file parameters
|
|
88
|
+
- Server-side request forgery through file inclusion
|
|
89
|
+
- XXE through all XML parsing points
|
|
90
|
+
|
|
91
|
+
Business Logic:
|
|
92
|
+
- Race conditions on all state-changing operations
|
|
93
|
+
- Workflow bypass attempts on every multi-step process
|
|
94
|
+
- Price/quantity manipulation in all transactions
|
|
95
|
+
- Parallel execution attacks
|
|
96
|
+
- Time-of-check to time-of-use vulnerabilities
|
|
97
|
+
|
|
98
|
+
Advanced Attacks:
|
|
99
|
+
- HTTP request smuggling if multiple proxies/servers
|
|
100
|
+
- Cache poisoning and cache deception
|
|
101
|
+
- Subdomain takeover on all subdomains
|
|
102
|
+
- Prototype pollution in JavaScript applications
|
|
103
|
+
- CORS misconfiguration exploitation
|
|
104
|
+
- WebSocket security testing
|
|
105
|
+
- GraphQL specific attacks if applicable
|
|
106
|
+
|
|
107
|
+
PHASE 4: VULNERABILITY CHAINING
|
|
108
|
+
Don't just find individual bugs - chain them:
|
|
109
|
+
- Combine information disclosure with access control bypass
|
|
110
|
+
- Chain SSRF to access internal services
|
|
111
|
+
- Use low-severity findings to enable high-impact attacks
|
|
112
|
+
- Look for multi-step attack paths that automated tools miss
|
|
113
|
+
- Consider attacks that span multiple application components
|
|
114
|
+
|
|
115
|
+
CHAINING PRINCIPLES (MAX IMPACT):
|
|
116
|
+
- Treat every finding as a pivot: ask "What does this unlock next?" until you reach maximum privilege / maximum data exposure / maximum control
|
|
117
|
+
- Prefer end-to-end exploit paths over isolated bugs: initial foothold → pivot → privilege gain → sensitive action/data
|
|
118
|
+
- Cross boundaries deliberately: user → admin, external → internal, unauthenticated → authenticated, read → write, single-tenant → cross-tenant
|
|
119
|
+
- Validate chains by executing the full sequence using the available tools (proxy + browser for workflows, python for automation, terminal for supporting commands)
|
|
120
|
+
- When a component agent finds a potential pivot, it must message/spawn the next focused agent to continue the chain in the next component/subpart
|
|
121
|
+
|
|
122
|
+
PHASE 5: PERSISTENT TESTING
|
|
123
|
+
If initial attempts fail, don't give up:
|
|
124
|
+
- Research specific technologies for known bypasses
|
|
125
|
+
- Try alternative exploitation techniques
|
|
126
|
+
- Look for edge cases and unusual functionality
|
|
127
|
+
- Test with different client contexts
|
|
128
|
+
- Revisit previously tested areas with new information
|
|
129
|
+
- Consider timing-based and blind exploitation techniques
|
|
130
|
+
|
|
131
|
+
PHASE 6: THOROUGH REPORTING
|
|
132
|
+
- Document EVERY confirmed vulnerability with full details
|
|
133
|
+
- Include all severity levels - even low findings may enable chains
|
|
134
|
+
- Provide complete reproduction steps and PoC
|
|
135
|
+
- Document remediation recommendations
|
|
136
|
+
- Note areas requiring additional review beyond current scope
|
|
137
|
+
|
|
138
|
+
MINDSET:
|
|
139
|
+
- Relentless - this is about finding what others miss
|
|
140
|
+
- Creative - think of unconventional attack vectors
|
|
141
|
+
- Patient - real vulnerabilities often require deep investigation
|
|
142
|
+
- Thorough - test every parameter, every endpoint, every edge case
|
|
143
|
+
- Persistent - if one approach fails, try ten more
|
|
144
|
+
- Holistic - understand how components interact to find systemic issues
|
|
145
|
+
</scan_mode>
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
<scan_mode>
|
|
2
|
+
QUICK SCAN MODE - Rapid Security Assessment
|
|
3
|
+
|
|
4
|
+
This mode is optimized for fast feedback. Focus on HIGH-IMPACT vulnerabilities with minimal overhead.
|
|
5
|
+
|
|
6
|
+
PHASE 1: RAPID ORIENTATION
|
|
7
|
+
- If source code is available: Focus primarily on RECENT CHANGES (git diff, new commits, modified files)
|
|
8
|
+
- Identify the most critical entry points: authentication endpoints, payment flows, admin interfaces, API endpoints handling sensitive data
|
|
9
|
+
- Quickly understand the tech stack and frameworks in use
|
|
10
|
+
- Skip exhaustive reconnaissance - use what's immediately visible
|
|
11
|
+
|
|
12
|
+
PHASE 2: TARGETED ATTACK SURFACE
|
|
13
|
+
For whitebox (source code available):
|
|
14
|
+
- Prioritize files changed in recent commits/PRs - these are most likely to contain fresh bugs
|
|
15
|
+
- Look for security-sensitive patterns in diffs: auth checks, input handling, database queries, file operations
|
|
16
|
+
- Trace user-controllable input in changed code paths
|
|
17
|
+
- Check if security controls were modified or bypassed
|
|
18
|
+
|
|
19
|
+
For blackbox (no source code):
|
|
20
|
+
- Focus on authentication and session management
|
|
21
|
+
- Test the most critical user flows only
|
|
22
|
+
- Check for obvious misconfigurations and exposed endpoints
|
|
23
|
+
- Skip deep content discovery - test what's immediately accessible
|
|
24
|
+
|
|
25
|
+
PHASE 3: HIGH-IMPACT VULNERABILITY FOCUS
|
|
26
|
+
Prioritize in this order:
|
|
27
|
+
1. Authentication bypass and broken access control
|
|
28
|
+
2. Remote code execution vectors
|
|
29
|
+
3. SQL injection in critical endpoints
|
|
30
|
+
4. Insecure direct object references (IDOR) in sensitive resources
|
|
31
|
+
5. Server-side request forgery (SSRF)
|
|
32
|
+
6. Hardcoded credentials or secrets in code
|
|
33
|
+
|
|
34
|
+
Skip lower-priority items:
|
|
35
|
+
- Extensive subdomain enumeration
|
|
36
|
+
- Full directory bruteforcing
|
|
37
|
+
- Information disclosure that doesn't lead to exploitation
|
|
38
|
+
- Theoretical vulnerabilities without PoC
|
|
39
|
+
|
|
40
|
+
PHASE 4: VALIDATION AND REPORTING
|
|
41
|
+
- Validate only critical/high severity findings with minimal PoC
|
|
42
|
+
- Report findings as you discover them - don't wait for completion
|
|
43
|
+
- Focus on exploitability and business impact
|
|
44
|
+
|
|
45
|
+
QUICK CHAINING RULE:
|
|
46
|
+
- If you find ANY strong primitive (auth weakness, access control gap, injection point, internal reachability), immediately attempt a single high-impact pivot to demonstrate real impact
|
|
47
|
+
- Do not stop at a low-context “maybe”; turn it into a concrete exploit sequence (even if short) that reaches privileged action or sensitive data
|
|
48
|
+
|
|
49
|
+
OPERATIONAL GUIDELINES:
|
|
50
|
+
- Use the browser tool for quick manual testing of critical flows
|
|
51
|
+
- Use terminal for targeted scans with fast presets (e.g., nuclei with critical/high templates only)
|
|
52
|
+
- Use proxy to inspect traffic on key endpoints
|
|
53
|
+
- Skip extensive fuzzing - use targeted payloads only
|
|
54
|
+
- Create subagents only for parallel high-priority tasks
|
|
55
|
+
- If whitebox: file_edit tool to review specific suspicious code sections
|
|
56
|
+
- Use notes tool to track critical findings only
|
|
57
|
+
|
|
58
|
+
MINDSET:
|
|
59
|
+
- Think like a time-boxed bug bounty hunter going for quick wins
|
|
60
|
+
- Prioritize breadth over depth on critical areas
|
|
61
|
+
- If something looks exploitable, validate quickly and move on
|
|
62
|
+
- Don't get stuck - if an attack vector isn't yielding results quickly, pivot
|
|
63
|
+
</scan_mode>
|