Add folder anatomy (scripts/agent.py + references/api-reference.md) for 648 cybersecurity skills

Complete skill folder anatomy across all cybersecurity skills:
- scripts/agent.py: 80-150 line Python agents using real libraries (impacket,
  boto3, azure-mgmt-*, kubernetes, pefile, yara, scapy, shodan, stix2, etc.)
- references/api-reference.md: real API documentation with method signatures
- LICENSE: MIT license for all skill folders
This commit is contained in:
mukul975
2026-03-10 21:02:12 +01:00
parent c74d52fa30
commit 27c6414ca5
1390 changed files with 106806 additions and 0 deletions
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Anthropic Agent Skills Contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@@ -0,0 +1,50 @@
# API Reference: GraphQL Security Assessment
## GraphQL Introspection Query
```graphql
{
__schema {
queryType { name }
mutationType { name }
types { name kind fields { name type { name kind } } }
}
}
```
## Security Test Endpoints
| Test | Query | Expected Secure Response |
|------|-------|-------------------------|
| Introspection | `{ __schema { types { name } } }` | Error: introspection disabled |
| Depth limit | Nested `{ users { friends { ... } } }` | Error: max depth exceeded |
| Batch queries | `[{query: "..."}, {query: "..."}]` | Error or single-query only |
| Aliases | `{ a1: __typename a2: __typename ... }` | Error: alias limit exceeded |
## Python Libraries
| Library | Version | Purpose |
|---------|---------|---------|
| `requests` | >=2.28 | HTTP client for GraphQL POST requests |
| `gql` | >=3.4 | Python GraphQL client with transport support |
## graphql-cop CLI
```bash
pip install graphql-cop
graphql-cop -t https://target.example.com/graphql
```
## clairvoyance (Schema Enumeration)
```bash
python3 -m clairvoyance -u <url> -w <wordlist> -o schema.json
```
## References
- GraphQL specification: https://spec.graphql.org/
- InQL Burp extension: https://github.com/doyensec/inql
- clairvoyance: https://github.com/nikitastupin/clairvoyance
- graphql-cop: https://github.com/dolevf/graphql-cop
- CSP Evaluator: https://csp-evaluator.withgoogle.com/
@@ -0,0 +1,197 @@
#!/usr/bin/env python3
"""Agent for performing GraphQL security assessment.
Tests GraphQL endpoints for introspection leaks, authorization flaws,
query depth/complexity DoS, and injection vulnerabilities.
"""
import requests
import json
import sys
from urllib.parse import urlparse
class GraphQLSecurityAgent:
"""Performs authorized security assessments on GraphQL endpoints."""
def __init__(self, target_url, auth_token=None):
self.target_url = target_url
self.session = requests.Session()
self.session.headers.update({"Content-Type": "application/json"})
if auth_token:
self.session.headers["Authorization"] = f"Bearer {auth_token}"
def _query(self, query, variables=None):
"""Send a GraphQL query and return the response."""
payload = {"query": query}
if variables:
payload["variables"] = variables
try:
resp = self.session.post(self.target_url, json=payload, timeout=10)
return {"status": resp.status_code, "body": resp.json()}
except requests.RequestException as e:
return {"status": 0, "error": str(e)}
def test_introspection(self):
"""Test if introspection is enabled in production."""
query = """{
__schema {
queryType { name }
mutationType { name }
types { name kind }
}
}"""
result = self._query(query)
has_schema = "data" in result.get("body", {}) and "__schema" in result.get("body", {}).get("data", {})
types = []
if has_schema:
types = [t["name"] for t in result["body"]["data"]["__schema"].get("types", [])
if not t["name"].startswith("__")]
return {
"vulnerable": has_schema,
"severity": "Medium",
"finding": "Introspection enabled" if has_schema else "Introspection disabled",
"types_exposed": len(types),
"type_names": types[:20],
}
def test_query_depth(self, max_depth=10):
"""Test for query depth limiting."""
nested = "{ __typename }"
for i in range(max_depth):
nested = f"{{ users {nested} }}"
query = nested
result = self._query(query)
has_error = "errors" in result.get("body", {})
return {
"vulnerable": not has_error,
"severity": "High" if not has_error else "Info",
"depth_tested": max_depth,
"finding": "No query depth limit" if not has_error else "Query depth limited",
}
def test_batch_queries(self):
"""Test if batch queries are accepted (rate limit bypass risk)."""
batch = [
{"query": "{ __typename }"},
{"query": "{ __typename }"},
{"query": "{ __typename }"},
]
try:
resp = self.session.post(self.target_url, json=batch, timeout=10)
body = resp.json()
is_array = isinstance(body, list)
return {
"vulnerable": is_array,
"severity": "High" if is_array else "Info",
"finding": "Batch queries accepted" if is_array else "Batch queries rejected",
"response_count": len(body) if is_array else 0,
}
except Exception as e:
return {"vulnerable": False, "error": str(e)}
def test_field_suggestions(self):
"""Test if field suggestions leak schema information."""
query = "{ userzzzz }"
result = self._query(query)
errors = result.get("body", {}).get("errors", [])
suggestions = []
for err in errors:
msg = err.get("message", "")
if "did you mean" in msg.lower() or "suggest" in msg.lower():
suggestions.append(msg)
return {
"vulnerable": len(suggestions) > 0,
"severity": "Low",
"finding": "Field suggestions enabled" if suggestions else "No field suggestions",
"suggestions": suggestions,
}
def test_unauthorized_access(self):
"""Test queries without authentication token."""
saved_auth = self.session.headers.pop("Authorization", None)
queries = [
("{ __typename }", "basic_access"),
("{ users { id email } }", "user_listing"),
('{ user(id: "1") { id email role } }', "user_detail"),
]
results = []
for query, test_name in queries:
result = self._query(query)
has_data = "data" in result.get("body", {})
has_null_data = has_data and all(
v is None for v in result["body"]["data"].values()
) if has_data else False
results.append({
"test": test_name,
"accessible": has_data and not has_null_data,
"status": result.get("status"),
})
if saved_auth:
self.session.headers["Authorization"] = saved_auth
accessible_count = sum(1 for r in results if r["accessible"])
return {
"vulnerable": accessible_count > 0,
"severity": "High" if accessible_count > 0 else "Info",
"finding": f"{accessible_count} queries accessible without auth",
"details": results,
}
def test_alias_overloading(self, count=50):
"""Test for alias-based resource exhaustion."""
aliases = " ".join(f'a{i}: __typename' for i in range(count))
query = f"{{ {aliases} }}"
result = self._query(query)
has_error = "errors" in result.get("body", {})
return {
"vulnerable": not has_error,
"severity": "Medium" if not has_error else "Info",
"aliases_tested": count,
"finding": f"Accepted {count} aliases" if not has_error else "Alias limit enforced",
}
def run_full_assessment(self):
"""Run all security tests and generate a report."""
report = {
"target": self.target_url,
"findings": [],
}
tests = [
("Introspection", self.test_introspection),
("Query Depth", self.test_query_depth),
("Batch Queries", self.test_batch_queries),
("Field Suggestions", self.test_field_suggestions),
("Unauthorized Access", self.test_unauthorized_access),
("Alias Overloading", self.test_alias_overloading),
]
for test_name, test_fn in tests:
result = test_fn()
result["test_name"] = test_name
report["findings"].append(result)
vulnerable_count = sum(1 for f in report["findings"] if f.get("vulnerable"))
report["summary"] = {
"total_tests": len(report["findings"]),
"vulnerabilities_found": vulnerable_count,
"critical": sum(1 for f in report["findings"] if f.get("severity") == "Critical" and f.get("vulnerable")),
"high": sum(1 for f in report["findings"] if f.get("severity") == "High" and f.get("vulnerable")),
"medium": sum(1 for f in report["findings"] if f.get("severity") == "Medium" and f.get("vulnerable")),
"low": sum(1 for f in report["findings"] if f.get("severity") == "Low" and f.get("vulnerable")),
}
return report
def main():
if len(sys.argv) < 2:
print("Usage: agent.py <graphql_url> [auth_token]")
sys.exit(1)
target_url = sys.argv[1]
auth_token = sys.argv[2] if len(sys.argv) > 2 else None
agent = GraphQLSecurityAgent(target_url, auth_token)
report = agent.run_full_assessment()
print(json.dumps(report, indent=2))
if __name__ == "__main__":
main()