[Avg. reading time: 7 minutes]
Application Layer
Insecure APIs
Problem: APIs are the control plane of IoT systems. If they are weak, the entire system is exposed.
Common failures:
- No authentication or weak auth
- Over-permissive endpoints
- No encryption (HTTP instead of HTTPS)
- No rate limiting
Real-World Use Case:
- CloudPets breach (2017)
- API had no authentication
- Exposed millions of voice recordings
- Attackers accessed data directly from backend storage
Mitigation:
- Enforce strong auth:
- OAuth2 / JWT / Mutual TLS
- Authorization per endpoint (RBAC)
- Always use HTTPS
- Hide internal APIs behind gateways
- Add API gateway (rate limit + auth + logging)
Demo
git clone https://github.com/gchandra10/python_api_auth_demo.git
Poor Session Management
Sessions are often:
- Long-lived
- Reused across devices
- Stored insecurely
This leads to session hijacking or replay attacks.
Real-World Use Case:
- Smart thermostat app reused same session token
- Attacker reused token -> controlled devices remotely
Mitigation:
- Short-lived access tokens
- Refresh tokens with rotation
- Store tokens securely:
- Avoid localStorage
- Use HTTP-only cookies
- Invalidate sessions:
- Logout
- Password change
- Bind session to device/IP if possible
Weak Input Validation (XSS, Injection)
Without validation -> injection attacks:
- XSS
- SQL Injection
- Command Injection
Real-World Example
- Smart fridge dashboard
- Attacker injected script -> executed on admin panel
- Stole session cookies
Mitigation
- Validate input schema strictly
- Sanitize inputs
- Escape outputs (HTML/JS)
- Use parameterized queries
- Never trust device-originated data
No Rate Limiting or Abuse Detection
Without rate limiting
- Brute force attacks succeed
- APIs get abused
- Devices become botnet nodes
Using Bots hackers cause
- Massive DDoS network
- Millions of IoT devices causes Internet outage
Mitigation
- Rate limit by IP / User / MAC address
- Detect anomalies by too many failures, spikes
- Pause access
Limit to 5 queries for given 60 seconds
from fastapi import Request
from time import time
requests = {}
def rate_limit(ip):
now=time()
window=60
limit=5
requests.setdefault(ip, [])
requests[ip]=[t for t in requests[ip] if now-t<window]
if len(requests[ip])>=limit:
return False
requests[ip].append(now)
return True
@app.get("/login")
def login(req: Request):
ip=req.client.host
if not rate_limit(ip):
raise HTTPException(status_code=429)
return {"ok":True}