service-integration
Facilitates seamless integration of external services and APIs, enhancing application functionality with email, CMS, and analytics solutions.
Install this skill
Security score
The service-integration skill was audited on Feb 28, 2026 and we found 72 security issues across 4 threat categories, including 2 high-severity. Review the findings below before installing.
Categories Tested
Security Issues
Template literal with variable interpolation in command context
| 236 | throw new Error(`Email send failed: ${error.message}`); |
Template literal with variable interpolation in command context
| 662 | console.log(`[Retry] Attempt ${attempt}/${maxAttempts} failed, retrying in ${delayMs}ms`); // Note: Use structured logger in production |
Template literal with variable interpolation in command context
| 748 | const id = `mock-${Date.now()}`; |
Template literal with variable interpolation in command context
| 823 | throw new Error(`Missing required environment variable: ${envVar}`); |
Template literal with variable interpolation in command context
| 898 | throw new Error(`Email send failed: ${error.message}`); |
Template literal with variable interpolation in command context
| 969 | 1. Verify API key is set: `printf "%s\n" "${RESEND_API_KEY:0:5}..."` (bash parameter expansion to display first 5 chars) |
Curl to non-GitHub URL
| 781 | if curl -X POST http://localhost:3000/api/webhooks/sanity \ |
Webhook reference - potential data exfiltration
| 3 | description: "Load PROACTIVELY when task involves connecting external services or third-party APIs. Use when user says \"add email sending\", \"integrate a CMS\", \"set up file uploads\", \"add analyt |
Webhook reference - potential data exfiltration
| 29 | - Configure webhook endpoints for third-party services |
Webhook reference - potential data exfiltration
| 88 | - id: webhook-routes |
Webhook reference - potential data exfiltration
| 90 | patterns: ["src/app/api/webhooks/**/*.ts", "pages/api/webhooks/**/*.ts"] |
Webhook reference - potential data exfiltration
| 391 | ### Step 4.3: Set Up Webhook Endpoint |
Webhook reference - potential data exfiltration
| 393 | For real-time content updates, implement a webhook handler: |
Webhook reference - potential data exfiltration
| 398 | - path: "src/app/api/webhooks/sanity/route.ts" |
Webhook reference - potential data exfiltration
| 407 | const signature = request.headers.get('sanity-webhook-signature'); |
Webhook reference - potential data exfiltration
| 409 | // Verify webhook signature |
Webhook reference - potential data exfiltration
| 410 | const secret = process.env.SANITY_WEBHOOK_SECRET; |
Webhook reference - potential data exfiltration
| 412 | return NextResponse.json({ error: 'Webhook secret not configured' }, { status: 500 }); |
Webhook reference - potential data exfiltration
| 431 | console.log('[Webhook] Sanity content updated:', _type); // Note: Use structured logger in production |
Webhook reference - potential data exfiltration
| 434 | console.error('[Webhook] Failed to process Sanity webhook:', error); |
Webhook reference - potential data exfiltration
| 435 | return NextResponse.json({ error: 'Webhook processing failed' }, { status: 500 }); |
Webhook reference - potential data exfiltration
| 764 | ### Step 8.2: Implement Webhook Testing |
Webhook reference - potential data exfiltration
| 766 | Test webhook handlers locally: |
Webhook reference - potential data exfiltration
| 771 | - path: "scripts/test-webhook.sh" |
Webhook reference - potential data exfiltration
| 778 | # Test Sanity webhook locally |
Webhook reference - potential data exfiltration
| 780 | echo "[INFO] Testing Sanity webhook..." |
Webhook reference - potential data exfiltration
| 781 | if curl -X POST http://localhost:3000/api/webhooks/sanity \ |
Webhook reference - potential data exfiltration
| 783 | -H "sanity-webhook-signature: $SANITY_WEBHOOK_SECRET" \ |
Webhook reference - potential data exfiltration
| 789 | echo "[PASS] Webhook test successful" |
Webhook reference - potential data exfiltration
| 791 | echo "[FAIL] Webhook test failed" |
Webhook reference - potential data exfiltration
| 932 | ### 4. Missing Webhook Verification |
Webhook reference - potential data exfiltration
| 947 | const signature = request.headers.get('webhook-signature'); |
Webhook reference - potential data exfiltration
| 949 | // Validate webhook secret |
Webhook reference - potential data exfiltration
| 950 | const secret = process.env.WEBHOOK_SECRET; |
Webhook reference - potential data exfiltration
| 952 | return NextResponse.json({ error: 'Webhook secret not configured' }, { status: 500 }); |
Webhook reference - potential data exfiltration
| 977 | 1. Verify webhook endpoint is publicly accessible |
Webhook reference - potential data exfiltration
| 978 | 2. Check webhook secret matches |
Webhook reference - potential data exfiltration
| 979 | 3. Test webhook locally with ngrok |
Webhook reference - potential data exfiltration
| 981 | 5. Check CMS webhook logs |
Webhook reference - potential data exfiltration
| 1010 | - [ ] Webhook endpoints have signature verification |
Webhook reference - potential data exfiltration
| 1023 | - [Webhook Best Practices](https://webhooks.fyi) |
Ngrok tunnel reference
| 979 | 3. Test webhook locally with ngrok |
Access to .env file
| 82 | glob: ".env.example" |
Access to .env file
| 208 | if (!process.env.RESEND_API_KEY) { |
Access to .env file
| 212 | export const resend = new Resend(process.env.RESEND_API_KEY); |
Access to .env file
| 320 | - path: ".env.example" |
Access to .env file
| 355 | if (!process.env.NEXT_PUBLIC_SANITY_PROJECT_ID) { |
Access to .env file
| 359 | if (!process.env.NEXT_PUBLIC_SANITY_DATASET) { |
Access to .env file
| 364 | projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID, |
Access to .env file
| 365 | dataset: process.env.NEXT_PUBLIC_SANITY_DATASET, |
Access to .env file
| 367 | useCdn: process.env.NODE_ENV === 'production', |
Access to .env file
| 410 | const secret = process.env.SANITY_WEBHOOK_SECRET; |
Access to .env file
| 533 | if (!process.env.AWS_REGION || !process.env.AWS_ACCESS_KEY_ID || !process.env.AWS_SECRET_ACCESS_KEY || !process.env.AWS_S3_BUCKET) { |
Access to .env file
| 538 | region: process.env.AWS_REGION, |
Access to .env file
| 540 | accessKeyId: process.env.AWS_ACCESS_KEY_ID, |
Access to .env file
| 541 | secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, |
Access to .env file
| 547 | Bucket: process.env.AWS_S3_BUCKET, |
Access to .env file
| 590 | if (process.env.NEXT_PUBLIC_POSTHOG_KEY) { |
Access to .env file
| 591 | posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, { |
Access to .env file
| 592 | api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST || 'https://app.posthog.com', |
Access to .env file
| 594 | if (process.env.NODE_ENV === 'development') { |
Access to .env file
| 822 | if (!process.env[envVar]) { |
Access to .env file
| 879 | if (!process.env.RESEND_API_KEY) { |
Access to .env file
| 882 | const resend = new Resend(process.env.RESEND_API_KEY); |
Access to .env file
| 950 | const secret = process.env.WEBHOOK_SECRET; |
Access to .env file
| 1008 | - [ ] Environment variables documented in .env.example |
External URL reference
| 592 | api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST || 'https://app.posthog.com', |
External URL reference
| 781 | if curl -X POST http://localhost:3000/api/webhooks/sanity \ |
External URL reference
| 1018 | - [Resend Documentation](https://resend.com/docs) |
External URL reference
| 1019 | - [Sanity Documentation](https://www.sanity.io/docs) |
External URL reference
| 1021 | - [PostHog Documentation](https://posthog.com/docs) |
External URL reference
| 1023 | - [Webhook Best Practices](https://webhooks.fyi) |
Install this skill with one command
/learn @mgd34msu/service-integration