Security Best Practices
Protect your API keys and data when using WebLinq.
API Key Security
Never expose API keys in client-side code, logs, or public repositories
Environment Variables
Store API keys securely:
# .env file
WEBLINQ_API_KEY=your_api_key_here
// Always use environment variables
const response = await fetch('https://api.weblinq.dev/v1/web/markdown', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.WEBLINQ_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ url }),
});
Add .env to your .gitignore file
Key Rotation
Regularly rotate your API keys:
- Generate new key in dashboard
- Update your applications
- Test thoroughly
- Delete old key
Request Validation
URL Validation
Always validate URLs before making requests:
function validateUrl(url) {
try {
const parsed = new URL(url);
// Only allow HTTP/HTTPS
if (!['http:', 'https:'].includes(parsed.protocol)) {
throw new Error('Invalid protocol');
}
// Block private networks
const hostname = parsed.hostname;
if (
hostname === 'localhost' ||
hostname.startsWith('127.') ||
hostname.startsWith('192.168.') ||
hostname.startsWith('10.') ||
hostname.startsWith('172.')
) {
throw new Error('Private networks not allowed');
}
return true;
} catch (error) {
throw new Error(`Invalid URL: ${error.message}`);
}
}
Sanitize user inputs before processing:
function sanitizeInput(input) {
// Remove potentially harmful characters
return input
.replace(/[<>]/g, '') // Remove HTML brackets
.replace(/javascript:/gi, '') // Remove javascript: protocol
.replace(/data:/gi, '') // Remove data: protocol
.trim()
.substring(0, 2000); // Limit length
}
Response Handling
Secure Content Processing
Validate API responses before using them:
function validateResponse(response) {
// Check response structure
if (!response.success) {
throw new Error(response.error?.message || 'API request failed');
}
// Validate data exists
if (!response.data) {
throw new Error('No data in response');
}
return response.data;
}
// Usage
const response = await makeAPIRequest(url);
const safeData = validateResponse(response);
Content Filtering
Filter potentially malicious content:
function filterContent(content) {
const suspiciousPatterns = [
/<script[^>]*>/gi,
/javascript:/gi,
/on\w+\s*=/gi, // Event handlers like onclick=
/<iframe[^>]*>/gi,
];
for (const pattern of suspiciousPatterns) {
if (pattern.test(content)) {
console.warn('Suspicious content detected');
content = content.replace(pattern, '');
}
}
return content;
}
Error Handling
Never expose sensitive information in error messages:
async function safeAPICall(url) {
try {
validateUrl(url);
const response = await fetch('https://api.weblinq.dev/v1/web/markdown', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.WEBLINQ_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ url }),
});
const data = await response.json();
return validateResponse(data);
} catch (error) {
// Log detailed error for debugging
console.error('API call failed:', error);
// Return safe error message to user
throw new Error('Failed to process request');
}
}
Access Control
Server-Side Proxy
Never call WebLinq API directly from client-side code:
// ❌ NEVER do this in client-side code
// fetch('https://api.weblinq.dev/v1/web/markdown', {
// headers: { 'Authorization': 'Bearer ' + API_KEY }
// });
// ✅ Create a server-side proxy instead
app.post('/api/extract-content', async (req, res) => {
const { url } = req.body;
try {
validateUrl(url);
const result = await callWebLinqAPI(url);
res.json(result);
} catch (error) {
res.status(500).json({ error: 'Processing failed' });
}
});
Rate Limiting
Implement request rate limiting in your application:
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 10, // limit each IP to 10 requests per windowMs
message: 'Too many requests from this IP',
});
app.use('/api/extract-content', limiter);
Security Checklist
Secure API Keys
Store in environment variables, never in code
Validate Inputs
Check URLs and sanitize all user inputs
Use Server-Side Proxy
Never expose API keys to client-side code
Implement Rate Limiting
Protect your endpoints from abuse
Monitor Usage
Track API usage and watch for anomalies
Regular Key Rotation
Rotate API keys periodically