Third-Party Integration Security: APIs, SDKs, and Dependencies

Share

TL;DR

The #1 third-party security best practice is auditing dependencies before adding them. Use lockfiles and pin versions. Scan for vulnerabilities automatically. Apply principle of least privilege to API keys. Have fallback plans for service outages. The security of your app includes the security of everything it depends on.

"The security of your application is only as strong as its weakest dependency."

Best Practice 1: Audit Dependencies Before Adding 3 min

Evaluate security before adding new dependencies:

  • Check maintenance status (recent commits, releases)
  • Review open security issues and CVEs
  • Check download counts and community adoption
  • Review the dependency's own dependencies
  • Verify the package is the official one (typosquatting)
Dependency audit commands
# npm - check for vulnerabilities
npm audit
npm audit --audit-level=high

# Check package info
npm info package-name

# See dependency tree
npm ls package-name

# Yarn
yarn audit

# pnpm
pnpm audit

# Python
pip-audit
safety check

# Snyk (comprehensive)
snyk test
Red FlagRiskAction
No updates in 2+ yearsUnmaintained, vulnerabilitiesFind alternative
Few downloadsLess vetted, possible typosquatVerify legitimacy
Many open security issuesKnown vulnerabilitiesAssess severity
Excessive permissionsOver-privileged accessReview necessity
Obfuscated codeHidden malicious codeAvoid

Best Practice 2: Lock Dependencies 2 min

Prevent unexpected updates from introducing vulnerabilities:

Lockfile management
# Always commit lockfiles
git add package-lock.json  # npm
git add yarn.lock          # Yarn
git add pnpm-lock.yaml     # pnpm

# Use exact versions in package.json
{
  "dependencies": {
    "express": "4.18.2",        // Exact version
    "lodash": "^4.17.21"        // Avoid caret for security-critical
  }
}

# Install from lockfile in CI/CD
npm ci                    # Not npm install
yarn install --frozen-lockfile
pnpm install --frozen-lockfile

# Enable Dependabot or Renovate for updates
# .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"
    open-pull-requests-limit: 10

Best Practice 3: Minimize Permissions 2 min

Give third-party services only necessary access:

Least privilege for API keys
// WRONG: Using admin/root API keys
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);  // Full access

// CORRECT: Use restricted keys where possible
// Stripe: Create restricted keys with specific permissions
// - Can only create charges
// - Cannot access customer data
// - Cannot modify account settings

// AWS: Use IAM roles with minimal permissions
{
  "Effect": "Allow",
  "Action": [
    "s3:GetObject",
    "s3:PutObject"
  ],
  "Resource": "arn:aws:s3:::my-bucket/uploads/*"
  // Not s3:* or arn:aws:s3:::*
}

// GitHub: Use fine-grained personal access tokens
// - Specific repositories only
// - Read-only where possible
// - Short expiration

// Firebase: Use security rules, not admin SDK when possible
// Client SDK respects rules; admin SDK bypasses them

Best Practice 4: Handle Third-Party Failures 3 min

Do not let external service failures crash your app:

Resilient third-party calls
import CircuitBreaker from 'opossum';

// Circuit breaker for external APIs
const paymentBreaker = new CircuitBreaker(processPayment, {
  timeout: 10000,           // 10 second timeout
  errorThresholdPercentage: 50,
  resetTimeout: 30000,      // Try again after 30s
});

paymentBreaker.fallback(() => {
  // Queue for retry or show user-friendly error
  return { status: 'pending', message: 'Payment processing delayed' };
});

paymentBreaker.on('open', () => {
  alertOps('Payment provider circuit breaker opened');
});

// Timeout wrapper for any external call
async function withTimeout(promise, ms, fallback) {
  const timeout = new Promise((_, reject) =>
    setTimeout(() => reject(new Error('Timeout')), ms)
  );

  try {
    return await Promise.race([promise, timeout]);
  } catch (error) {
    if (fallback) return fallback;
    throw error;
  }
}

// Usage
const userData = await withTimeout(
  thirdPartyApi.getUser(userId),
  5000,
  { name: 'Unknown', cached: true }
);

Best Practice 5: Secure Third-Party Scripts 2 min

Client-side scripts are particularly risky:

Secure third-party script loading
  • Use SRI hashes for all external scripts
  • Implement strict CSP to limit script sources
  • Load non-critical scripts asynchronously
  • Sandbox third-party iframes
  • Review third-party scripts periodically
  • Self-host critical scripts when possible

Best Practice 6: Monitor Third-Party Security 2 min

Stay informed about vulnerabilities in your dependencies:

Automated vulnerability monitoring
# GitHub: Enable Dependabot alerts
# Settings > Security > Code security and analysis
# Enable: Dependency graph, Dependabot alerts, Dependabot security updates

# Snyk in CI/CD
# .github/workflows/security.yml
- name: Run Snyk to check for vulnerabilities
  uses: snyk/actions/node@master
  env:
    SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
  with:
    args: --severity-threshold=high

# npm audit in CI
- name: Security audit
  run: npm audit --audit-level=high

# Socket.dev for supply chain attacks
# Detects typosquatting, malicious packages, etc.
- name: Socket Security
  uses: socketsecurity/socket-action@v1

Supply Chain Attacks: Attackers increasingly target popular packages. The event-stream incident, ua-parser-js compromise, and colors.js sabotage show that even popular packages can become vectors. Use lockfiles, monitor for unusual updates, and consider tools like Socket.dev that analyze package behavior.

Should I vendor (copy) dependencies?

Vendoring provides maximum control but means you are responsible for updates. It is useful for critical dependencies or when you need to patch them. For most dependencies, use lockfiles and automated update tools instead.

How do I handle a vulnerability in a dependency?

Check if a patched version exists and update. If not, check for workarounds or mitigations. If the vulnerable code path is not used by your app, document and accept the risk temporarily. For critical vulnerabilities with no fix, consider removing or replacing the dependency.

Should I trust AI-generated dependency recommendations?

AI tools can suggest outdated or non-existent packages (hallucinations). Always verify that recommended packages exist, are actively maintained, and are the official version. Check npm/PyPI directly before installing anything.

Scan Your Dependencies

Check for vulnerabilities in your third-party dependencies.

Start Free Scan
Best Practices

Third-Party Integration Security: APIs, SDKs, and Dependencies