api-integration-builder
Facilitates the creation of robust third-party API integrations, ensuring secure and efficient data handling and synchronization.
Install this skill
Security score
The api-integration-builder skill was audited on Feb 9, 2026 and we found 74 security issues across 3 threat categories. Review the findings below before installing.
Categories Tested
Security Issues
Template literal with variable interpolation in command context
| 56 | return fetch(`https://api.service.com${endpoint}`, { |
Template literal with variable interpolation in command context
| 59 | Authorization: `Bearer ${this.apiKey}`, |
Template literal with variable interpolation in command context
| 181 | return fetch(`https://api.service.com${endpoint}`, options) |
Template literal with variable interpolation in command context
| 201 | console.log(`Rate limited, waiting ${waitTime}ms`) |
Template literal with variable interpolation in command context
| 224 | super(`API Error: ${statusCode}`) |
Template literal with variable interpolation in command context
| 289 | console.log(`Attempt ${attempt + 1} failed, retrying in ${delay}ms`) |
Template literal with variable interpolation in command context
| 343 | console.log(`Webhook ${event_id} already processed`) |
Template literal with variable interpolation in command context
| 524 | Authorization: `Bearer ${accessToken}`, |
Template literal with variable interpolation in command context
| 540 | headers: { Authorization: `Bearer ${accessToken}` } |
Template literal with variable interpolation in command context
| 546 | throw new Error(`Slack API error: ${data.error}`) |
Template literal with variable interpolation in command context
| 605 | const message = [`To: ${to}`, `Subject: ${subject}`, '', body].join('\n') |
Template literal with variable interpolation in command context
| 698 | .update(`${timestamp}.${JSON.stringify(payload)}`) |
Template literal with variable interpolation in command context
| 704 | 'stripe-signature': `t=${timestamp},v1=${signature}` |
Template literal with variable interpolation in command context
| 806 | title: `High error rate for ${service} integration`, |
Template literal with variable interpolation in command context
| 807 | message: `${recentErrors} errors in last 5 minutes` |
Fetch to external URL
| 96 | const tokenResponse = await fetch('https://slack.com/api/oauth.v2.access', { |
Fetch to external URL
| 135 | const refreshResponse = await fetch('https://slack.com/api/oauth.v2.access', { |
Fetch to external URL
| 521 | fetch('https://slack.com/api/chat.postMessage', { |
Fetch to external URL
| 539 | const response = await fetch('https://slack.com/api/conversations.list', { |
Webhook reference - potential data exfiltration
| 3 | description: Build reliable third-party API integrations including OAuth, webhooks, rate limiting, error handling, and data sync. Use when integrating with external services (Slack, Stripe, Gmail, etc |
Webhook reference - potential data exfiltration
| 29 | └── Webhooks (if supported) |
Webhook reference - potential data exfiltration
| 36 | 3. **Webhook Handler**: Receive real-time updates from third parties |
Webhook reference - potential data exfiltration
| 301 | ## Webhook Handling |
Webhook reference - potential data exfiltration
| 303 | ### Receiving Webhooks |
Webhook reference - potential data exfiltration
| 306 | interface WebhookPayload { |
Webhook reference - potential data exfiltration
| 313 | app.post('/webhooks/stripe', async (req, res) => { |
Webhook reference - potential data exfiltration
| 319 | event = stripe.webhooks.constructEvent(req.body, signature, STRIPE_WEBHOOK_SECRET) |
Webhook reference - potential data exfiltration
| 321 | console.error('⚠️ Webhook signature verification failed:', error.message) |
Webhook reference - potential data exfiltration
| 322 | return res.status(400).send('Webhook signature verification failed') |
Webhook reference - potential data exfiltration
| 325 | // 2. Respond immediately (don't make webhook wait) |
Webhook reference - potential data exfiltration
| 329 | await queue.add('process-webhook', { |
Webhook reference - potential data exfiltration
| 336 | // Process webhook in background job |
Webhook reference - potential data exfiltration
| 337 | async function processWebhook(job: Job) { |
Webhook reference - potential data exfiltration
| 340 | // Idempotency check (handle duplicate webhooks) |
Webhook reference - potential data exfiltration
| 341 | const existing = await db.webhookEvents.findOne({ event_id }) |
Webhook reference - potential data exfiltration
| 343 | console.log(`Webhook ${event_id} already processed`) |
Webhook reference - potential data exfiltration
| 348 | await db.webhookEvents.create({ event_id, status: 'processing' }) |
Webhook reference - potential data exfiltration
| 364 | await db.webhookEvents.update(event_id, { status: 'completed' }) |
Webhook reference - potential data exfiltration
| 367 | await db.webhookEvents.update(event_id, { |
Webhook reference - potential data exfiltration
| 377 | ### Webhook Security |
Webhook reference - potential data exfiltration
| 381 | function verifyWebhookSignature(payload: string, signature: string, secret: string): boolean { |
Webhook reference - potential data exfiltration
| 389 | function validateWebhookTimestamp(timestamp: number, toleranceSeconds = 300) { |
Webhook reference - potential data exfiltration
| 407 | // Real-time sync: Use webhooks for instant updates |
Webhook reference - potential data exfiltration
| 408 | realTimeSync(webhookData: any): Promise<void> |
Webhook reference - potential data exfiltration
| 440 | async realTimeSync(webhookData: any) { |
Webhook reference - potential data exfiltration
| 442 | const { resourceId, resourceUri } = webhookData |
Webhook reference - potential data exfiltration
| 690 | ### Webhook Testing |
Webhook reference - potential data exfiltration
| 693 | // Generate valid webhook signatures for testing |
Webhook reference - potential data exfiltration
| 694 | function generateTestWebhook(payload: any, secret: string) { |
Webhook reference - potential data exfiltration
| 709 | describe('Webhook Handler', () => { |
Webhook reference - potential data exfiltration
| 710 | it('processes valid webhook', async () => { |
Webhook reference - potential data exfiltration
| 711 | const webhook = generateTestWebhook( |
Webhook reference - potential data exfiltration
| 718 | STRIPE_WEBHOOK_SECRET |
Webhook reference - potential data exfiltration
| 722 | .post('/webhooks/stripe') |
Webhook reference - potential data exfiltration
| 723 | .set(webhook.headers) |
Webhook reference - potential data exfiltration
| 724 | .send(webhook.payload) |
Webhook reference - potential data exfiltration
| 732 | .post('/webhooks/stripe') |
Webhook reference - potential data exfiltration
| 862 | - [ ] Set up webhook endpoint (if available) |
Webhook reference - potential data exfiltration
| 863 | - [ ] Add webhook signature verification |
Webhook reference - potential data exfiltration
| 864 | - [ ] Implement idempotency for webhooks |
Webhook reference - potential data exfiltration
| 872 | ❌ **Synchronous webhook processing**: Process webhooks in background jobs |
Webhook reference - potential data exfiltration
| 873 | ❌ **No idempotency**: Webhooks may be delivered multiple times |
Webhook reference - potential data exfiltration
| 877 | ❌ **Missing signature verification**: Attackers can forge webhooks |
Webhook reference - potential data exfiltration
| 886 | - ✅ Verify webhook signatures |
Webhook reference - potential data exfiltration
| 887 | - ✅ Process webhooks idempotently |
External URL reference
| 56 | return fetch(`https://api.service.com${endpoint}`, { |
External URL reference
| 77 | const authUrl = new URL('https://slack.com/oauth/v2/authorize') |
External URL reference
| 79 | authUrl.searchParams.set('redirect_uri', 'https://yourapp.com/auth/slack/callback') |
External URL reference
| 96 | const tokenResponse = await fetch('https://slack.com/api/oauth.v2.access', { |
External URL reference
| 103 | redirect_uri: 'https://yourapp.com/auth/slack/callback' |
External URL reference
| 135 | const refreshResponse = await fetch('https://slack.com/api/oauth.v2.access', { |
External URL reference
| 181 | return fetch(`https://api.service.com${endpoint}`, options) |
External URL reference
| 521 | fetch('https://slack.com/api/chat.postMessage', { |
External URL reference
| 539 | const response = await fetch('https://slack.com/api/conversations.list', { |