Articles on: Tools

Custom Tool Security Considerations

Why Security Matters for Custom Tools

Custom Tools can interact with external services, process sensitive data, and execute code. Without proper security practices, they could:

  • Expose sensitive credentials like API keys and passwords
  • Leak confidential business data
  • Allow unauthorized access to your systems
  • Execute malicious code
  • Compromise user privacy

Your responsibility:

As a tool creator, you're responsible for ensuring your tools are secure and don't put your organization or users at risk.


Protecting Credentials and Secrets


Never Hardcode Sensitive Information

❌ UNSAFE: Hardcoded API key in API action

URL: https://api.example.com/data
Headers:
Key: Authorization
Value: Bearer sk_live_abc123secretkey456def

If you save this tool or share it, anyone with access can see your API key!

✅ SAFE: Use tool inputs for secrets

Tool Input: apiKey (String)

URL: https://api.example.com/data
Headers:
Key: Authorization
Value: Bearer {{apiKey}}

Now the API key is provided at runtime, not stored in the tool.



What to never hardcode:

  • API keys and tokens
  • Passwords
  • Database connection strings
  • OAuth secrets
  • Private keys
  • Internal URLs and endpoints (if sensitive)
  • Personal information
  • Credit card numbers or payment tokens

Use environment-based secrets when possible

If your platform supports it, use secure secret storage instead of passing secrets as inputs:

  • Use your organization's secrets manager
  • Leverage platform-provided secure storage
  • Rotate secrets regularly
  • Audit who has access to secrets


API Security Best Practices

1. Always Use HTTPS

❌ UNSAFE:

URL: http://api.example.com/data

HTTP sends data in plain text. Anyone monitoring the network can see your data and credentials.

✅ SAFE:

URL: https://api.example.com/data

HTTPS encrypts data in transit, protecting it from eavesdropping.

2. Validate API Responses

Don't trust that APIs always return safe data:

async function main() {
const response = ctx.fetchData.responseBody;

// Validate the structure
if (!response || typeof response !== 'object') {
return { error: "Invalid response format" };
}

// Validate expected fields exist
if (!response.userId || !response.email) {
return { error: "Missing required fields" };
}

// Sanitize string data
const email = String(response.email).trim().toLowerCase();

return { userId: response.userId, email: email };
}

3. Set Appropriate Timeouts

Don't let API calls hang forever:

  • Default: 30 seconds (usually sufficient)
  • Maximum: 300 seconds (5 minutes)
  • Use shorter timeouts for fast APIs
  • Use longer timeouts only when necessary

4. Handle Rate Limits

Respect API rate limits to avoid being blocked:

  • Use Catch Actions to handle 429 (Too Many Requests) responses
  • Implement exponential backoff if retrying
  • Don't hammer APIs in tight loops
  • Consider caching frequently requested data

5. Limit Data Exposure in URLs

❌ UNSAFE:

URL: https://api.example.com/user?ssn={{socialSecurityNumber}}&password={{password}}

URL Parameters can be logged by proxies, firewalls, and the API itself.


✅ SAFE:

URL: https://api.example.com/user
Method: POST
Body:
{
"ssn": "{{socialSecurityNumber}}",
"password": "{{password}}"
}

Send sensitive data in the request body with HTTPS, not in URL parameters.


JavaScript Code Security

1. Never Use eval() or new Function() with User Input

❌ EXTREMELY UNSAFE:

// NEVER DO THIS
const userCode = ctx.userInput;
eval(userCode); // Allows executing arbitrary code!

This allows execution of any code, including malicious code that could compromise your system.

✅ SAFE:

Use fixed code paths and validate inputs:

const operation = ctx.operation; // User provides: "add", "subtract", etc.

if (operation === "add") {
return ctx.a + ctx.b;
} else if (operation === "subtract") {
return ctx.a - ctx.b;
} else {
return { error: "Invalid operation" };
}

2. Validate and Sanitize All Inputs

Never trust that inputs are what you expect:

async function main() {
// Validate type
if (typeof ctx.age !== 'number' || isNaN(ctx.age)) {
return { error: "Age must be a number" };
}

// Validate range
if (ctx.age < 0 || ctx.age > 150) {
return { error: "Age must be between 0 and 150" };
}

// Sanitize strings (remove dangerous characters)
const name = String(ctx.name)
.trim()
.replace(/[<>\"\']/g, '') // Remove HTML/script characters
.substring(0, 100); // Limit length

if (!name) {
return { error: "Name cannot be empty" };
}

return { age: ctx.age, name: name };
}

3. Don't Log Sensitive Data

❌ UNSAFE:

console.log("Full context:", JSON.stringify(ctx));
// Logs might include: passwords, API keys, SSNs, credit cards, etc.

✅ SAFE:

console.log("Processing user:", ctx.userId);
console.log("Operation:", ctx.operationType);
// Only log non-sensitive identifiers

4. Limit Output to Necessary Data

Don't return more information than needed:

❌ UNSAFE:

async function main() {
const user = ctx.fetchUser.responseBody;
return user; // Might include: password hashes, internal IDs, etc.
}

✅ SAFE:

async function main() {
const user = ctx.fetchUser.responseBody;

// Return only what's needed
return {
userId: user.id,
name: user.name,
email: user.email
// Exclude: passwordHash, apiKey, internalMetadata, etc.
};
}

5. Handle Errors Without Exposing Internals

❌ UNSAFE:

async function main() {
try {
return processData();
} catch (error) {
// Exposes internal paths, function names, database details
return { error: error.stack };
}
}

✅ SAFE:

async function main() {
try {
return processData();
} catch (error) {
console.log("Internal error:", error); // Log for debugging

// Return generic message to users
return {
success: false,
message: "An error occurred while processing your request. Please try again."
};
}
}



Data Privacy and Compliance

1. Minimize Data Collection

Principle: Only collect what you need

❌ Bad:

Tool Inputs:
- firstName
- lastName
- email
- phone
- address
- dateOfBirth
- socialSecurityNumber

// Only using email for the actual operation

✅ Good:

Tool Inputs:
- email

// Only collect what's actually needed

2. Don't Store Sensitive Data Unnecessarily

If data doesn't need to persist, don't save it:

  • Process and discard sensitive data immediately
  • Don't log sensitive information
  • Don't cache sensitive responses
  • Don't pass sensitive data to tools that don't need it

3. Respect Data Regulations

Be aware of and comply with:

  • GDPR (Europe): User data rights, consent, data minimization
  • CCPA (California): Consumer privacy rights
  • HIPAA (Healthcare): Protected health information
  • PCI DSS (Payment cards): Credit card data security
  • Your organization's policies: Internal data handling requirements

4. Sanitize Data Before Logging or Display

Remove sensitive patterns before logging:

function sanitizeForLogging(data) {
const sanitized = { ...data };

// Remove sensitive fields
delete sanitized.password;
delete sanitized.apiKey;
delete sanitized.ssn;
delete sanitized.creditCard;

// Mask email (keep first character and domain)
if (sanitized.email) {
sanitized.email = sanitized.email.replace(/(.{1}).*@/, '$1***@');
}

// Mask phone numbers (keep last 4 digits)
if (sanitized.phone) {
sanitized.phone = '***-***-' + sanitized.phone.slice(-4);
}

return sanitized;
}

async function main() {
console.log("Processing:", sanitizeForLogging(ctx));
// Logs: { email: "j***@example.com", phone: "***-***-5678" }

// But use the real data for processing
return processRealData(ctx);
}


Access Control and Sharing

1. Share Tools Selectively

Before sharing a tool, ask:

  • Does this tool access sensitive data or systems?
  • Should everyone on my team have access?
  • Are there any hardcoded values that shouldn't be shared?
  • Does this tool comply with our security policies?

Sharing options:

  • Private (default): Only you can use the tool
  • Shared with specific users: Selected team members can use it
  • Public*: Everyone in your organization can use it

*Only admins can make tools Public



2. Review Shared Tools

Before using a tool someone shared with you:

  • Review what data it accesses
  • Check what external services it calls
  • Understand what it does with your inputs
  • Verify it comes from a trusted source

3. Audit Tool Usage

If you're managing tools for a team:

  • Regularly review who has access to which tools
  • Check for tools that haven't been used in a long time
  • Look for duplicate tools that should be consolidated
  • Monitor error logs for suspicious activity
  • Remove access when team members leave

4. Document Required Permissions

In your tool description, note what access is needed:

Tool Name: Fetch Customer Orders
Description: Retrieves order history for a given customer email.

Required Permissions:
- Read access to Orders API
- Customer email from user input
- Valid API key with 'orders:read' scope

Notes:
- Only returns orders from the last 90 days
- Does not expose payment information


Testing for Security Issues

Security Testing Checklist

Before deploying your tool, test for these security issues:

1. Credential Exposure

  • [ ] No hardcoded API keys in tool configuration
  • [ ] No hardcoded passwords in tool configuration
  • [ ] Secrets are passed via tool inputs or secure storage
  • [ ] Test results don't display full credentials

2. Data Validation

  • [ ] All inputs are validated for type and format
  • [ ] String inputs have length limits
  • [ ] Numeric inputs have reasonable ranges
  • [ ] Enum inputs only allow specified values
  • [ ] Unexpected input types don't cause crashes

3. Error Handling

  • [ ] Errors don't expose internal system details
  • [ ] Error messages are user-friendly, not technical stack traces
  • [ ] Catch Actions handle common failure scenarios
  • [ ] Errors are logged securely without sensitive data

4. API Security

  • [ ] All API calls use HTTPS
  • [ ] Authentication headers use input variables, not hardcoded values
  • [ ] Timeouts are set appropriately
  • [ ] Rate limiting is handled
  • [ ] API responses are validated before use

5. Data Privacy

  • [ ] Only necessary data is collected
  • [ ] Sensitive data is not logged
  • [ ] Output doesn't include unnecessary sensitive fields
  • [ ] Personal information is handled per regulations

6. Access Control

  • [ ] Tool is shared only with appropriate users
  • [ ] Tool description documents security requirements
  • [ ] Sensitive tools are not made public


Incident Response


If You Discover a Security Issue

If you find a security vulnerability in a tool:

  1. Stop using the tool immediately
    • Don't run it with real data
    • Don't share it with others
  1. Assess the impact
    • Was sensitive data exposed?
    • Were credentials compromised?
    • Who else has access to the tool?
  1. Fix the vulnerability
    • Update the tool configuration
    • Remove hardcoded secrets
    • Add proper validation
    • Test the fix thoroughly
  1. Rotate compromised credentials
    • Change any exposed API keys
    • Reset any exposed passwords
    • Revoke and regenerate tokens
  1. Notify affected parties
    • Inform your security team
    • Notify users who may have been affected
    • Document what happened and how it was fixed
  1. Review other tools
    • Check for similar issues in other tools
    • Update your tool creation practices
    • Share lessons learned with your team


If Credentials Are Compromised

Immediate actions:

  1. Revoke the compromised credentials in the external service
  2. Delete or update the tool to remove the credentials
  3. Generate new credentials
  4. Update the tool to use the new credentials securely
  5. Review logs to see if the credentials were used maliciously
  6. Notify your security team


Security Resources and Best Practices Summary

Quick Security Checklist

Every time you create a tool, verify:

Credentials

  • No hardcoded API keys, passwords, or secrets
  • Sensitive values use tool inputs or secure storage
  • HTTPS is used for all API calls

Code

  • No use of eval() or new Function() with user input
  • All inputs are validated and sanitized
  • Errors don't expose internal system details

Data

  • Only necessary data is collected and processed
  • Sensitive data is not logged or displayed unnecessarily
  • Output includes only what's needed

Access

  • Tool is shared appropriately (not over-shared)
  • Tool description documents security requirements
  • Regular review of who has access

Testing

  • Tool tested with invalid inputs
  • Error scenarios tested
  • Security checklist completed before deployment


Security Principles

  1. Least Privilege: Only collect and access what's necessary
  2. Defense in Depth: Multiple layers of security (validation, error handling, access control)
  3. Fail Secure: When something goes wrong, fail in a secure way (don't expose data)
  4. Security by Design: Think about security from the start, not as an afterthought
  5. Assume Breach: Design tools assuming they might be compromised (limit damage)


When in Doubt

If you're unsure whether something is secure:

  • Ask your security team before deploying
  • Start with more restrictive settings (you can always loosen later)
  • Review similar tools to see how others handle security
  • Test thoroughly with security in mind
  • Document your security decisions for future reference

Remember: Security is not a one-time checkbox. Regularly review your tools, update practices, and stay informed about security best practices.

Updated on: 03/11/2025

Was this article helpful?

Share your feedback

Cancel

Thank you!