Save products you love by clicking the heart icon.
Open-source intelligence has always been a graph problem: entities, relationships, provenance. The 2026 shift is that generative and agentic AI can do the investigation part too. This article reviews the emerging OSINT+graph research: entity resolution, temporal threat intelligence, agentic collection, and the hallucination risk that makes graphs essential.
Two August 2026 announcements crystallised a shift in offensive security: Zhipu's GLM-5.3 with "emergent cyber capabilities" and OpenAI's GPT-5.6-Cyber with "reduced safeguards for exploit development." Both are frontier coding models repurposed for security research — and both change the economics of vulnerability discovery.
The question for defensive teams is not whether AI-assisted offense is coming. It is here. The question is how to adapt: which guardrails matter, which attack patterns scale with AI, and how to map an attack surface that is now being probed by models that never sleep.
Both models are coding models first. Their "cyber capabilities" are emergent — they come from the same reasoning, code comprehension, and pattern-matching that makes them good at software engineering. The security-relevant capabilities fall into four buckets:
| Capability | What It Means | Defensive Implication |
|---|---|---|
| Code comprehension | Read and understand unfamiliar codebases at scale | Faster vulnerability triage in both directions |
| Pattern recognition | Identify vulnerability classes across code (CWE patterns) | Automated SAST at higher precision |
| Exploit generation | Generate proof-of-concept code from vulnerability descriptions | Patch-before-exploit window shrinks |
| Reasoning over systems | Understand multi-step attack chains | Complex exploit paths become discoverable |
The key insight: these capabilities are dual-use. The same model that generates an exploit can audit the patch. The same pattern recognition that finds vulnerabilities can prioritise remediation.
Never run AI-generated exploit code on production infrastructure. Period.
# Safe pattern: isolated sandbox for AI-generated PoCs
import subprocess
import tempfile
def run_ai_generated_poc(poc_code: str, target: str):
with tempfile.NamedTemporaryFile(suffix=".py", mode="w", delete=False) as f:
f.write(poc_code)
f.flush()
result = subprocess.run(
["python3", f.name],
capture_output=True,
text=True,
timeout=30,
env={
"PATH": "/usr/bin:/bin",
"HOME": "/tmp",
"TARGET": target, # Only pass the target, not credentials
},
# Run in a container or namespace
cwd="/tmp",
)
return result.stdout, result.stderr
AI models hallucinate. Every generated exploit must be validated:
def validate_exploit(poc_output: str, expected_cwe: str) -> bool:
"""Validate that a PoC actually demonstrates the vulnerability"""
checks = [
("crash" in poc_output.lower(), "No crash evidence"),
("exploit" in poc_output.lower(), "No exploit confirmation"),
(expected_cwe.lower() in poc_output.lower(), f"No {expected_cwe} reference"),
]
return all(check[0] for check in checks)
# ai-security-gateway.yml
rate_limits:
exploit_generation: 10/hour
vulnerability_scan: 100/hour
code_analysis: 1000/hour
audit_log:
enabled: true
destination: /var/log/ai-security-audit.jsonl
fields:
- timestamp
- user
- model
- prompt_hash
- output_hash
- target_system
- action_class
The real defensive opportunity is not in generating exploits — it is in mapping the attack surface before attackers do. This is where graph databases shine.
┌──────────┐
│ Internet │
└────┬─────┘
│
┌────▼─────┐
│ Firewall│
└────┬─────┘
│
┌──────────┼──────────┐
│ │ │
┌────▼───┐ ┌───▼────┐ ┌───▼────┐
│Web App │ │ API GW │ │ VPN │
└────┬───┘ └───┬────┘ └───┬────┘
│ │ │
┌────▼───┐ ┌───▼────┐ ┌───▼────┐
│Postgres│ │ Redis │ │ LDAP │
└────────┘ └────────┘ └────────┘
Each node is an asset. Each edge is a trust relationship. Vulnerabilities are properties on nodes or edges. The attack surface is the reachable subgraph from any entry point.
// Find all paths from internet-facing services to databases
MATCH path = (entry:Service {exposed: true})-[:TRUSTS*1..5]->(db:Database {sensitive: true})
WHERE ALL(r IN relationships(path) WHERE r.protocol IN ['tcp', 'http', 'grpc'])
RETURN path, length(path) AS hops
ORDER BY hops ASC
// Find services with known vulnerabilities reachable from the internet
MATCH (s:Service)-[:HAS_VULNERABILITY]->(v:Vulnerability {severity: 'critical'})
WHERE s.exposed = true
RETURN s.name, v.cve, v.severity, v.description
// Find trust paths that bypass network segmentation
MATCH path = (a:Service)-[:TRUSTS*1..10]->(b:Service)
WHERE NOT EXISTS {
MATCH (a)-[:IN_ZONE]->(z1:Zone), (b)-[:IN_ZONE]->(z2:Zone)
WHERE z1 = z2
}
RETURN path
The combination of AI and graph-based attack surface mapping is where the defensive advantage lies:
class AIAttackSurfaceMapper:
def __init__(self, graph, llm):
self.graph = graph # Neo4j with attack surface data
self.llm = llm # GLM-5.3 or GPT-5.6-Cyber
def discover_trust_relationships(self, codebase):
"""AI reads code to find trust relationships the graph is missing"""
prompt = f"""
Analyse this codebase for trust relationships:
- Service-to-service authentication
- Database connections
- API key usage
- Network calls
Return as JSON: {{"source": "...", "target": "...", "protocol": "...", "auth": "..."}}
Codebase: {codebase[:5000]}...
"""
relationships = self.llm.generate(prompt)
return self._validate_and_add(relationships)
def generate_attack_path_queries(self, target):
"""AI generates Cypher queries to find attack paths to a target"""
prompt = f"""
Given a Neo4j attack surface graph with nodes (Service, Database, Vulnerability)
and edges (TRUSTS, HAS_VULNERABILITY, EXPOSED_TO),
generate Cypher queries to find attack paths to: {target}
Consider: lateral movement, privilege escalation, vulnerability chaining.
"""
queries = self.llm.generate(prompt)
return self._execute_and_validate(queries)
def _validate_and_add(self, relationships):
"""Validate AI-generated trust relationships before adding to graph."""
...
def _execute_and_validate(self, queries):
"""Execute Cypher queries and validate results against the graph."""
...
def validate_findings(self, finding):
"""Validate AI findings against the graph (ground truth)"""
cypher = """
MATCH path = (s:Service {name: $source})
-[:TRUSTS*1..5]->
(t:Service {name: $target})
RETURN path
"""
result = self.graph.run(cypher, source=finding.source, target=finding.target)
return len(result) > 0 # Only accept findings the graph confirms
AI-assisted vulnerability research does not change the fundamental threat model. It changes the scale and speed:
| Before AI | With AI |
|---|---|
| Manual code review: days per service | AI-assisted: hours per service |
| Exploit development: days to weeks | AI-assisted: hours to days |
| Attack surface mapping: weeks | AI-augmented: continuous |
| Vulnerability triage: hours per finding | AI-assisted: minutes per finding |
The defensive implication is clear: the patch-before-exploit window is shrinking. Organisations that rely on manual processes will fall behind.
The offensive-defensive AI arms race is accelerating. Three developments to watch:
The organisations that win this race will be those that use AI for defence as aggressively as attackers use it for offence. The technology is dual-use. The advantage goes to whoever deploys it first and most thoroughly.