mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-08-03 01:10:18 +03:00
Remove backed-up duplicate skills to fix validation pipeline
This commit is contained in:
@@ -1,10 +1,22 @@
|
||||
# API Reference — Performing GraphQL Introspection Attack
|
||||
|
||||
## Libraries Used
|
||||
- **requests**: Send GraphQL introspection queries and depth test payloads
|
||||
|
||||
| Library | Purpose |
|
||||
|---------|---------|
|
||||
| `requests` | Send GraphQL introspection queries and depth test payloads |
|
||||
| `json` | Parse schema responses and format results |
|
||||
| `argparse` | CLI argument parsing for URL, auth headers, depth limits |
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
pip install requests
|
||||
```
|
||||
|
||||
## CLI Interface
|
||||
```
|
||||
|
||||
```bash
|
||||
python agent.py introspect --url <graphql_endpoint> [--auth-header "Bearer token"]
|
||||
python agent.py depth --url <graphql_endpoint> [--max-depth 10]
|
||||
```
|
||||
@@ -12,15 +24,157 @@ python agent.py depth --url <graphql_endpoint> [--max-depth 10]
|
||||
## Core Functions
|
||||
|
||||
### `run_introspection(url, headers)` — Execute `__schema` introspection query
|
||||
Returns: types, queries, mutations, sensitive field detection.
|
||||
|
||||
```python
|
||||
INTROSPECTION_QUERY = """
|
||||
{
|
||||
__schema {
|
||||
queryType { name }
|
||||
mutationType { name }
|
||||
subscriptionType { name }
|
||||
types {
|
||||
name
|
||||
kind
|
||||
fields {
|
||||
name
|
||||
type { name kind ofType { name kind } }
|
||||
args { name type { name kind } }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
def run_introspection(url, headers=None):
|
||||
"""Execute full introspection query and extract schema details."""
|
||||
resp = requests.post(
|
||||
url,
|
||||
json={"query": INTROSPECTION_QUERY},
|
||||
headers=headers or {},
|
||||
timeout=30,
|
||||
)
|
||||
resp.raise_for_status()
|
||||
schema = resp.json().get("data", {}).get("__schema", {})
|
||||
|
||||
types = [t for t in schema.get("types", []) if not t["name"].startswith("__")]
|
||||
queries = []
|
||||
mutations = []
|
||||
sensitive_fields = []
|
||||
|
||||
for t in types:
|
||||
for field in (t.get("fields") or []):
|
||||
if t["name"] == schema.get("queryType", {}).get("name"):
|
||||
queries.append(field["name"])
|
||||
if t["name"] == schema.get("mutationType", {}).get("name"):
|
||||
mutations.append(field["name"])
|
||||
if any(kw in field["name"].lower() for kw in SENSITIVE_PATTERNS):
|
||||
sensitive_fields.append({"type": t["name"], "field": field["name"]})
|
||||
|
||||
return {
|
||||
"types_count": len(types),
|
||||
"queries": queries,
|
||||
"mutations": mutations,
|
||||
"sensitive_fields": sensitive_fields,
|
||||
"introspection_enabled": True,
|
||||
}
|
||||
```
|
||||
|
||||
### `test_depth_limit(url, max_depth, headers)` — Test query depth enforcement
|
||||
Sends increasingly nested queries to detect missing depth limits.
|
||||
|
||||
```python
|
||||
def test_depth_limit(url, max_depth=15, headers=None):
|
||||
"""Send increasingly nested queries to detect missing depth limits."""
|
||||
results = []
|
||||
for depth in range(1, max_depth + 1):
|
||||
# Build a nested query using __typename
|
||||
nested = "{ __typename " * depth + "}" * depth
|
||||
query = f"query DepthTest {nested}"
|
||||
|
||||
try:
|
||||
resp = requests.post(
|
||||
url,
|
||||
json={"query": query},
|
||||
headers=headers or {},
|
||||
timeout=10,
|
||||
)
|
||||
status = resp.status_code
|
||||
has_errors = "errors" in resp.json()
|
||||
results.append({
|
||||
"depth": depth,
|
||||
"status": status,
|
||||
"blocked": has_errors and status != 200,
|
||||
})
|
||||
if has_errors:
|
||||
return {
|
||||
"max_allowed_depth": depth - 1,
|
||||
"depth_limit_enforced": True,
|
||||
"results": results,
|
||||
}
|
||||
except requests.Timeout:
|
||||
return {
|
||||
"max_allowed_depth": depth - 1,
|
||||
"depth_limit_enforced": True,
|
||||
"reason": "timeout",
|
||||
"results": results,
|
||||
}
|
||||
|
||||
return {
|
||||
"max_allowed_depth": max_depth,
|
||||
"depth_limit_enforced": False,
|
||||
"severity": "high",
|
||||
"detail": f"No depth limit detected up to {max_depth} levels",
|
||||
"results": results,
|
||||
}
|
||||
```
|
||||
|
||||
### `test_batch_query(url, headers)` — Test for batching attacks
|
||||
|
||||
```python
|
||||
def test_batch_query(url, headers=None):
|
||||
"""Test if the endpoint allows batched queries (alias-based brute force)."""
|
||||
batch = [
|
||||
{"query": '{ alias0: __typename }'},
|
||||
{"query": '{ alias1: __typename }'},
|
||||
{"query": '{ alias2: __typename }'},
|
||||
]
|
||||
resp = requests.post(url, json=batch, headers=headers or {}, timeout=10)
|
||||
return {
|
||||
"batch_supported": resp.status_code == 200 and isinstance(resp.json(), list),
|
||||
"responses": len(resp.json()) if isinstance(resp.json(), list) else 0,
|
||||
}
|
||||
```
|
||||
|
||||
## Sensitive Field Patterns
|
||||
`password`, `token`, `secret`, `credential`, `ssn`, `credit_card`, `api_key`
|
||||
|
||||
## Dependencies
|
||||
```python
|
||||
SENSITIVE_PATTERNS = [
|
||||
"password", "token", "secret", "credential", "ssn",
|
||||
"credit_card", "api_key", "apikey", "private_key",
|
||||
"auth", "session", "otp", "pin", "cvv",
|
||||
]
|
||||
```
|
||||
pip install requests
|
||||
|
||||
## Output Format
|
||||
|
||||
```json
|
||||
{
|
||||
"url": "https://api.example.com/graphql",
|
||||
"introspection_enabled": true,
|
||||
"types_count": 45,
|
||||
"queries": ["users", "orders", "admin_dashboard"],
|
||||
"mutations": ["createUser", "deleteAccount", "updatePassword"],
|
||||
"sensitive_fields": [
|
||||
{"type": "User", "field": "password_hash"},
|
||||
{"type": "Session", "field": "auth_token"}
|
||||
],
|
||||
"depth_limit": {
|
||||
"enforced": false,
|
||||
"max_tested": 15,
|
||||
"severity": "high"
|
||||
},
|
||||
"batch_queries": {
|
||||
"supported": true,
|
||||
"severity": "medium"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user