Seu agent foi hackeado (você nem sabe)
India: rogue agents hackeados via GitHub exposed credentials. Seu agent: credentials onde? GitHub público? Cloud role? Agent hijacking.
Equipe OpenClaw · Time de Engenharia & Produto
A Equipe OpenClaw é formada por engenheiros, designers e especialistas em IA dedicados a construir a melhor plataforma de agentes conversacionais para negócios brasileiros. Combinamos expertise…
Seu agent foi hackeado (você nem sabe)
Cenário que está acontecendo AGORA (e você não viu notícia):
Você é founder de SaaS com agent (atendimento, vendas, automação).
Seu agent precisa de credenciais pra operar:
- API keys (Stripe, Salesforce, etc)
- Database passwords
- Access tokens (M365, Google, etc)
- Cloud credentials (AWS, Azure, etc)
- Webhook secrets
Pergunta:
Onde você armazena essas credenciais?
Resposta (honesta):
Você provavelmente errou.
Opção A: Em seu código (Git repository) API_KEY = "sk_live_abc123xyz789" DB_PASSWORD = "P@ssw0rd123" → Committed to GitHub → Public (accidentally) → Attacker finds: 5 seconds (automated scan) → Agent hijacked: immediately
Opção B: Em config files (não-versioned, but...) .env file config.json settings.yaml → Occasionally committed (human error) → Repository history keeps it (forever) → Attacker finds: via GitHub search → Agent hijacked: immediately
Opção C: In environment variables (seems safe, but...) Cloud provider (AWS, Azure, Vercel, etc) Overly permissive IAM role Any process can read environment → Attacker compromises one process → Reads environment variables → Gets all credentials → Agent hijacked: immediately
Opção D: In cloud config (CloudFormation, Terraform) Sensitive values in plain text Git repository (public or internal) → Attacker gains repo access → Finds all credentials → Agent hijacked: immediately
Realidade: most SaaS teams do at least one of these wrong.
What happened in India (and what it means)
The incident (October 2026)
Timeline:
India:
- Multiple SaaS companies
- AI agents deployed (customer support, automation)
- Attackers compromised agents
- How? Via exposed credentials
Attack vector:
- Credentials in GitHub (public repo)
- Credentials in cloud config (overly permissive IAM)
- Credentials in app configuration (hardcoded)
- Attacker finds credentials
- Uses credentials to assume agent identity
- Runs rogue tasks (fraud, data theft, damage)
Scale:
Unknown how many companies But: pattern is systematic
- Not targeted attacks
- Automated scanning + exploitation
- Attacker: "Find exposed credentials, use them"
Why this matters for YOUR agent
Agent = trusted execution environment
Your SaaS: Customer → (trust) → Your agent → (trust) → Customer data/systems
If agent is compromised: Attacker → (identity of agent) → Customer data/systems
From customer perspective: "Your SaaS did this" (Even though attacker did it, YOUR agent ran it)
Liability:
- You're liable (attacker used your agent)
- Customer loses data
- Customer sues you
- Regulatory fine (LGPD)
- Reputation destroyed
Concrete example:
Your SaaS: Stripe integration agent
- Agent accesses customer's Stripe account
- Agent credentials: Stripe API key
- Stored: in GitHub (accidentally public)
Attacker:
- Finds Stripe API key on GitHub
- Uses key to impersonate your agent
- Accesses customer's Stripe data
- Refunds all transactions (fraud)
- Your customer loses R$ 500k
Customer's view: "Your SaaS refunded my transactions" "You're liable"
Your liability:
- Stripe API key was your responsibility
- You exposed it (on GitHub)
- You're negligent
- You owe customer R$ 500k+
- LGPD fine: R$ 50k - R$ 5M
Where agents get compromised (the attack surface)
1. GitHub (public/private repo leak)
How it happens:
python
BAD: credentials in code
def setup_stripe_agent(): STRIPE_KEY = "sk_live_abc123xyz789"
agent = StripeAgent(
api_key=STRIPE_KEY,
secret=STRIPE_SECRET
)
return agent
Developer commits this
git add agent.py git commit -m "Add Stripe agent" git push origin main
Oops: pushed to public GitHub
Attacker scans GitHub (automated):
"Find: sk_live_"
Results: 10,000+ exposed keys per day
Attacker uses your Stripe key
Your agent is now under attacker control
How attackers find these:
Attacker tooling:
-
GitHub API (scan public repos)
-
GitLab API
-
Bitbucket API
-
Search for patterns:
- "sk_live_" (Stripe keys)
- "AKIA" (AWS keys)
- "xoxb-" (Slack tokens)
- "pk_live_" (Checkout.com keys)
- etc.
-
When found: test key (is it valid?)
-
If valid: use key immediately
-
Agent is now compromised
Scale of the problem:
GitHub statistics:
- 10,000+ API keys exposed daily (estimated)
- 25-40% still valid when found
- Average time to compromise: 5-30 seconds
Your risk:
- If you committed credential: likely already leaked
- If key is valid: likely already compromised
- If agent uses key: attacker can impersonate
2. Cloud configuration (IAM overly permissive)
How it happens:
yaml
CloudFormation / Terraform (stores credentials)
Resources: AgentRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: lambda.amazonaws.com Action: sts:AssumeRole
ManagedPolicyArns:
# BAD: overly permissive
- arn:aws:iam::aws:policy/AdministratorAccess
# Instead of: specific permissions only
Developer saves this in Git
git add infrastructure/main.tf git push
Attacker gains access to Git repo (phishing, insider threat)
Finds Terraform file with credentials
Or: finds Git history (credentials in old commits)
Uses credentials to access AWS
AgentRole has admin access (overly permissive)
Attacker can:
- Modify agent code
- Access all customer data
- Delete resources
- Run malicious tasks
Why overly permissive is dangerous:
Principle of Least Privilege: Agent should have ONLY permissions needed
Example:
- Agent needs to read Stripe API
- Permission: stripe:read-only
- That's it
Overly permissive:
- Agent has: stripe:*, *, all resources
- Attacker compromises agent
- Attacker can: refund, refund, refund
Difference:
- Least privilege: damage = limited
- Overly permissive: damage = catastrophic
3. App configuration (hardcoded secrets)
How it happens:
javascript // config.js (loaded by app) export const CONFIG = { stripe_key: "sk_live_abc123", database_password: "P@ssw0rd123", api_token: "token_xyz", webhookSecret: "webhook_secret_abc" };
// App loads this at startup import { CONFIG } from './config';
// If app is compromised (any way): // - Attacker reads memory // - Gets all credentials // - Agent hijacked
// Or: config file is accidentally exposed // - In error logs // - In server response (debugging) // - In browser (client-side code) // - Attacker finds credentials
Why this is bad:
If ANY code path is compromised:
- Attacker reads CONFIG
- Gets all credentials
- Doesn't matter how secure rest of app is
Example:
- Your app has no known vulnerabilities
- But: one old dependency is exploited
- Attacker runs code in your process
- Reads CONFIG
- Agent hijacked
The attack: how agents get hijacked
Step-by-step hijacking
Timeline:
Day 1: 10:00 AM - Developer commits credential to GitHub 10:05 AM - GitHub post-commit hook scans for exposed secrets (if enabled) If not: attacker's automated scanner finds it 10:10 AM - Attacker confirms credential is valid (by testing) 10:11 AM - Attacker saves credential
Day 2: Any time - Attacker uses credential - Assumes agent identity - Agent appears to come from YOUR infrastructure - Runs malicious task (using agent's permissions)
Example malicious task: Agent normally: "Route support ticket to correct team" Attacker-controlled: "Transfer R$ 100k to attacker's account"
Customer sees:
- Your SaaS processed a transfer
- Appears legitimate (same agent, same permissions)
- No way to know it was attacker
What attacker can do (once in control)
Depends on agent's permissions:
Scenario A: Agent has Stripe access Attacker can: - Refund all transactions - Create fake charges - Access customer payment data - Transfer funds
Scenario B: Agent has database access Attacker can: - Steal customer data - Modify data (fraud) - Delete data (ransom) - Inject malware
Scenario C: Agent has email/communication access Attacker can: - Send emails impersonating company - Phishing attacks (to customers) - Extortion - Disinformation
Scenario D: Agent has multiple permissions (typical) Attacker can: - Combine permissions - Access everything - Maximum damage
How to prevent agent hijacking (practical)
1. NEVER commit credentials to Git
What to do:
bash
1. Add .gitignore
echo ".env" >> .gitignore echo "secrets/" >> .gitignore echo "config.secret.js" >> .gitignore
2. If already committed: REMOVE from history
git filter-branch --tree-filter 'rm -f config.js' HEAD
3. Rotate ALL credentials (they're compromised)
Find any keys you committed
Rotate them (generate new ones)
Old ones: delete/disable
**Prevention:
python
Good: load from environment
import os
STRIPE_KEY = os.getenv('STRIPE_KEY') DB_PASSWORD = os.getenv('DB_PASSWORD')
if not STRIPE_KEY: raise ValueError("STRIPE_KEY not set in environment")
Good: never in code
Good: loaded at runtime
Good: easy to rotate (change env var)
2. Use secrets manager (not environment variables)
Why environment variables are risky:
If ANY process in your container compromised:
- Attacker can read /proc/self/environ
- Gets all environment variables
- Gets all secrets
Secrets manager is better:
- Only specific code paths access secrets
- Secrets stay in vault (not in process memory)
- Access logged (you can detect theft)
- Easy to rotate (without restarting)
Practical implementation:
python
BAD: environment variable
import os STRIPE_KEY = os.getenv('STRIPE_KEY')
GOOD: secrets manager
from aws_secretsmanager_caching import SecretCache
cache = SecretCache() STRIPE_KEY = cache.get_secret_string('stripe/api_key')
Benefits:
- Secrets not in memory (until used)
- Can be rotated without restart
- Access is logged
- If code is compromised: attacker still can't read
3. Implement least privilege IAM
How to do it right:
yaml
BAD: overly permissive
AgentRole: ManagedPolicyArns: - arn:aws:iam::aws:policy/AdministratorAccess
GOOD: specific permissions
AgentRole: Policies: - PolicyName: StripeReadOnly PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - "stripe:List*" - "stripe:Get*" Resource: "*" Condition: StringEquals: "aws:RequestedRegion": "us-east-1"
- PolicyName: DatabaseReadOnly
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action: "rds-db:connect"
Resource: "arn:aws:rds:us-east-1:123456789:db/customer_db"
Condition:
StringEquals:
"aws:username": "agent_user"
Audit your current IAM:
bash
Find overly permissive policies
aws iam list-policies --scope Local --query 'Policies[*].Arn'
| xargs -I {} aws iam get-policy-version
--policy-arn {}
--version-id $(aws iam get-policy --policy-arn {} --query 'Policy.DefaultVersionId' --output text)
--query 'PolicyVersion.Document'
Look for:
- "Effect": "Allow" with "Action": "*"
- "Resource": "*"
- Any explicit "Admin" or "FullAccess" policies
4. Detect exposed credentials (before attacker)
Tools to scan your repos:
bash
Install TruffleHog (find secrets in Git history)
pip install truffleHog
Scan your repos
trufflehog filesystem .
Or: use GitHub secret scanning
Settings → Security → Secret scanning
GitHub scans automatically
Or: use pre-commit hook
Runs before each commit
pip install detect-secrets pre-commit install
5. Implement audit logging
Log all agent actions:
python import logging from datetime import datetime
logger = logging.getLogger('agent_audit')
def log_agent_action(action, agent_id, credentials_used, result): """ Log agent actions for forensics """ logger.info( f""" Agent Action: Time: {datetime.now()} Agent ID: {agent_id} Action: {action} Credentials: {credentials_used} Result: {result} Status: {result.status} """ )
Usage
log_agent_action( action="stripe_refund", agent_id="agent_001", credentials_used="stripe_key_123", result=refund_response )
Benefits:
- Can detect suspicious patterns
- Forensics if compromise happens
- Alerts on unusual activity
6. Monitor for anomalies
Detect rogue agent behavior:
python def detect_anomalies(agent_action): """ Detect if agent is behaving unusually """
# Normal behavior
normal_patterns = {
"stripe_refund": {
"max_per_day": 10,
"max_amount_per_refund": 10000,
"allowed_hours": [9, 10, 11, 12, 13, 14, 15, 16, 17],
},
"database_query": {
"max_per_minute": 5,
"max_rows_returned": 10000,
}
}
# Check if action violates patterns
pattern = normal_patterns.get(agent_action.type)
if not pattern:
alert("Unknown action type - possible attack")
return True
if agent_action.amount > pattern["max_amount_per_refund"]:
alert(f"Unusually high amount: {agent_action.amount}")
return True
if agent_action.timestamp.hour not in pattern["allowed_hours"]:
alert(f"Action outside normal hours: {agent_action.timestamp.hour}")
return True
return False
Usage
if detect_anomalies(agent_action): # Block action # Require human approval # Notify security team pass
7. Rotate credentials regularly
Automate credential rotation:
python def rotate_credentials(service, old_key): """ Rotate credentials automatically """
# Generate new key
new_key = service.create_new_api_key()
# Test new key works
test_result = service.test_key(new_key)
if not test_result.success:
raise ValueError("New key failed testing")
# Update in secrets manager
secrets_manager.put_secret(
secret_name=f'{service}_key',
secret_value=new_key
)
# Disable old key
service.disable_key(old_key)
# Log rotation
logger.info(f"Rotated {service} credentials")
Schedule: every 90 days
import schedule
schedule.every(90).days.do(rotate_credentials, 'stripe') schedule.every(90).days.do(rotate_credentials, 'database') schedule.every(90).days.do(rotate_credentials, 'api_token')
India incident: what YOU should do NOW
Immediate actions (today)
-
Search your Git repos for exposed credentials trufflehog filesystem .
-
If found: ROTATE immediately
- Generate new credentials
- Update in secrets manager
- Delete old ones
- Alert customers (if data accessed)
-
Enable GitHub secret scanning Settings → Security → Secret scanning
-
Check IAM roles (AWS/Azure/GCP) Remove "AdministratorAccess" Implement least privilege
-
Review recent agent activity logs Look for: unusual refunds, data access, emails sent
This week
-
Implement secrets manager (if not already)
-
Audit all credentials Find: where are they stored? Fix: move to secrets manager
-
Implement audit logging (if not already)
-
Add anomaly detection (for agent behavior)
-
Create incident response plan "If agent is compromised, what do we do?"
This month
-
Implement credential rotation (automated, 90-day cycle)
-
Security training for team "Never commit secrets" "Always use secrets manager"
-
Regular audits (monthly: check for exposed credentials)
-
Penetration testing (by external firm: can they hijack agent?)
Conclusion: agent hijacking is preventable
Reality:
India incident: not a bug in agents India incident: security practices failure
Credentials exposed because:
- Committed to Git
- Overly permissive IAM
- No audit logging
- No anomaly detection
- No rotation policy
All preventable with basic practices
Cost comparison:
Cost of prevention:
- Secrets manager: R$ 50-200/month
- Audit logging: R$ 100-500/month
- Anomaly detection: R$ 200-1000/month
- Total: ~R$ 500-2000/month
Cost of breach:
- LGPD fine: R$ 50k - R$ 50M
- Customer liability: R$ 100k - R$ 5M
- Remediation: R$ 50k - R$ 500k
- Reputation: -50% valuation
- Total: R$ 1M - R$ 100M+
Action: audit your agent security TODAY
Seu agent: credentials onde? GitHub? Secrets manager? 🔐
Publicado em 17 de outubro de 2026