Back to Cheat Sheets

🔗 Unsafe Consumption of APIs

OWASP API Security Top 10 - API10

MEDIUM RISK

📋 What Is It?

Unsafe Consumption of APIs occurs when developers blindly trust data received from third-party APIs without proper validation and sanitization. Even if your own API is secure, consuming compromised or malicious third-party APIs can introduce vulnerabilities into your system.

API10 OWASP Rank
3rd Party API Trust Issue
Supply Chain Attack Vector

⚠️ Common Exploits

  • Unvalidated Data: Trust external API responses without validation
  • Injection Attacks: XSS, SQLi via third-party API responses
  • Compromised APIs: Third-party API hacked, serves malicious data
  • No Input Sanitization: External data stored/displayed without escaping
  • Broken Integrations: Weak authentication to third-party services
  • Data Leakage: Sending sensitive data to third-party APIs

🔴 Attack Flow

1. Your API calls third-party weather API

2. Third-party API compromised by attacker

3. Returns malicious payload with XSS

4. Your API displays data without escaping

5. BREACH: XSS executed on your users!

❌ Vulnerable Code

// Bad: Blindly trust third-party API response @app.route('/api/weather') def get_weather(): city = request.args.get('city') # Call third-party weather API response = requests.get( f'https://weather-api.com/city/{city}' ) # VULNERABLE: No validation of response! weather_data = response.json() # Directly store in database Weather.create( city=weather_data['city'], ← Could contain SQLi! description=weather_data['description'] ← Could contain XSS! ) return jsonify(weather_data) // Bad: No SSL verification response = requests.get( 'https://third-party-api.com/data', verify=False ← DANGEROUS! Allows MITM attacks ) // Bad: Sending sensitive data to third-party @app.route('/api/analytics') def track_event(): user = get_current_user() # Sends sensitive data to analytics service requests.post('https://analytics.com/track', json={ 'user_id': user.id, 'email': user.email, ← PII leaked! 'ssn': user.ssn, ← Sensitive data leaked! 'credit_card': user.cc_last4 ← Financial data leaked! }) // Bad: No timeout on third-party calls response = requests.get( 'https://slow-api.com/data' # No timeout - could hang forever! )

✅ Secure Code

// Good: Validate and sanitize third-party data from bleach import clean import re def validate_weather_response(data): """Validate structure and sanitize content""" if not isinstance(data, dict): raise ValueError("Invalid response format") # Whitelist expected fields required_fields = ['city', 'temperature', 'description'] for field in required_fields: if field not in data: raise ValueError(f"Missing field: {field}") # Sanitize strings data['city'] = clean(data['city'], tags=[], strip=True) data['description'] = clean(data['description'], tags=[], strip=True) # Validate data types and ranges if not isinstance(data['temperature'], (int, float)): raise ValueError("Invalid temperature type") if not -100 <= data['temperature'] <= 150: raise ValueError("Temperature out of range") return data @app.route('/api/weather') def get_weather(): city = request.args.get('city') try: # Secure API call with timeout and SSL verification response = requests.get( f'https://weather-api.com/city/{city}', timeout=5, # 5 second timeout verify=True, # Verify SSL certificate headers={ 'Authorization': f'Bearer {API_KEY}' } ) response.raise_for_status() # Raise on HTTP errors weather_data = response.json() # Validate and sanitize response validated_data = validate_weather_response(weather_data) # Use parameterized queries (prevents SQLi) Weather.create( city=validated_data['city'], temperature=validated_data['temperature'], description=validated_data['description'] ) return jsonify(validated_data) except requests.Timeout: return {'error': 'Third-party API timeout'}, 504 except requests.RequestException as e: logger.error(f"API error: {e}") return {'error': 'External service unavailable'}, 503 except ValueError as e: logger.warning(f"Invalid response: {e}") return {'error': 'Invalid data from external API'}, 502 // Good: Minimal data sharing with third-parties @app.route('/api/analytics') def track_event(): user = get_current_user() # Only send anonymous/aggregated data requests.post('https://analytics.com/track', json={ 'user_id_hash': hash(user.id), # Hashed, not actual ID 'event': 'page_view', 'timestamp': datetime.utcnow().isoformat() # NO PII, NO sensitive data! }, timeout=3, verify=True ) // Good: Circuit breaker for third-party APIs from pybreaker import CircuitBreaker third_party_breaker = CircuitBreaker( fail_max=5, # Open after 5 failures timeout_duration=60 # Stay open for 60 seconds ) @third_party_breaker def call_third_party_api(url): return requests.get(url, timeout=5, verify=True)

✓ Prevention Checklist

  • Validate all third-party API responses
  • Sanitize data before storing or displaying
  • Always verify SSL/TLS certificates
  • Set timeouts on external API calls
  • Use schema validation for responses
  • Implement circuit breakers for resilience
  • Never trust external data implicitly
  • Minimize data sent to third-parties
  • Encrypt sensitive data in transit
  • Monitor third-party API health
  • Have fallback mechanisms
  • Regular security audits of integrations

🔍 Detection & Tools

Validation Tools:

JSON Schema Pydantic Joi Marshmallow Bleach DOMPurify

Monitoring Tools:

Datadog New Relic Prometheus Sentry PyBreaker

How to Test:

  • Mock third-party APIs with malicious payloads
  • Test with XSS/SQLi in response data
  • Verify timeout handling
  • Test SSL certificate validation
  • Check error handling for invalid responses
  • Monitor data sent to third-parties

🌍 Real-World Breaches

  • SolarWinds (2020): Supply chain attack via compromised third-party software
  • British Airways (2018): Third-party script injected malicious code
  • Ticketmaster (2018): Compromised third-party chatbot stole payment data
  • Target (2013): Breach via compromised HVAC vendor credentials
  • Magecart Attacks: Compromised third-party JavaScript libraries stealing credit cards

📌 Quick Tips

  • DO NOT trust third-party data without validation
  • DO NOT disable SSL verification
  • DO NOT send PII to third-parties unnecessarily
  • DO validate response schemas
  • DO sanitize all external data
  • DO set timeouts on API calls
  • DO implement circuit breakers

📜 Compliance

Related Standards:

  • GDPR Art. 28 - Processor Requirements
  • PCI-DSS Requirement 12.8 - Third-party Management
  • SOC 2 CC9.2 - Vendor Management
  • ISO 27001 A.15.1.1 - Supplier Relationships
  • NIST 800-161 - Supply Chain Risk