Screenshot API Security Best Practices
When integrating any API into your application, security should be a top priority. This is especially true for Screenshot APIs, which may process sensitive information from the websites you capture. This guide covers essential security practices to protect your data and prevent unauthorized access.
Securing Your API Keys
Your API key is the primary authentication method for our Screenshot API. Protecting it should be your first priority:
Never Expose API Keys in Client-Side Code
01// ❌ NEVER do this02const apiKey = "sk_live_your_actual_api_key_here";0304document.getElementById("capture-btn").addEventListener("click", () => {05 fetch('https://api.screenshotapi.com/capture', {06 method: 'POST',07 headers: {08 'Authorization': `Bearer ${apiKey}`, // Exposed in browser!09 'Content-Type': 'application/json'10 },11 body: JSON.stringify({ url: 'https://example.com' })12 });13});
Use Environment Variables
01// ✅ Server-side code (Node.js)02const express = require('express');03const app = express();0405app.post('/generate-screenshot', async (req, res) => {06 try {07 const response = await fetch('https://api.screenshotapi.com/capture', {08 method: 'POST',09 headers: {10 'Authorization': `Bearer ${process.env.SCREENSHOT_API_KEY}`,11 'Content-Type': 'application/json'12 },13 body: JSON.stringify({ url: req.body.url })14 });1516 const data = await response.json();17 res.json(data);18 } catch (error) {19 res.status(500).json({ error: 'Failed to generate screenshot' });20 }21});
Implementing Access Controls
Rate Limiting
Implement rate limiting to prevent abuse of your screenshot generation endpoint:
01const rateLimit = require('express-rate-limit');0203// Create rate limiter04const screenshotLimiter = rateLimit({05 windowMs: 15 * 60 * 1000, // 15 minutes06 max: 100, // Limit each IP to 100 requests per windowMs07 message: 'Too many screenshot requests, please try again later'08});0910// Apply to screenshot routes11app.use('/api/screenshots', screenshotLimiter);
User Authentication
Ensure only authenticated users can request screenshots:
01const authenticateUser = (req, res, next) => {02 const authHeader = req.headers.authorization;0304 if (!authHeader || !authHeader.startsWith('Bearer ')) {05 return res.status(401).json({ error: 'Unauthorized' });06 }0708 const token = authHeader.split(' ')[1];0910 try {11 // Verify JWT token12 const decoded = jwt.verify(token, process.env.JWT_SECRET);13 req.user = decoded;14 next();15 } catch (error) {16 return res.status(401).json({ error: 'Invalid token' });17 }18};1920// Apply authentication middleware21app.post('/api/screenshots', authenticateUser, screenshotController.generate);
URL Validation and Sanitization
Validate Input URLs
Always validate URLs before sending them to the Screenshot API:
01const isValidUrl = (string) => {02 try {03 const url = new URL(string);04 return url.protocol === 'http:' || url.protocol === 'https:';05 } catch (err) {06 return false;07 }08};0910app.post('/api/screenshots', (req, res) => {11 const { url } = req.body;1213 if (!url || !isValidUrl(url)) {14 return res.status(400).json({ error: 'Invalid URL provided' });15 }1617 // Proceed with screenshot generation18});
Implement URL Allowlists
For additional security, consider implementing an allowlist of domains:
01const allowedDomains = [02 'example.com',03 'yourdomain.com',04 'trusted-partner.com'05];0607const isDomainAllowed = (urlString) => {08 try {09 const url = new URL(urlString);10 return allowedDomains.some(domain =>11 url.hostname === domain || url.hostname.endsWith(`.${domain}`)12 );13 } catch (err) {14 return false;15 }16};1718app.post('/api/screenshots', (req, res) => {19 const { url } = req.body;2021 if (!isDomainAllowed(url)) {22 return res.status(403).json({ error: 'Domain not allowed' });23 }2425 // Proceed with screenshot generation26});
Secure Storage and Handling of Screenshots
Secure Storage Options
When storing screenshots, ensure they're protected:
01const AWS = require('aws-sdk');02const s3 = new AWS.S3({03 accessKeyId: process.env.AWS_ACCESS_KEY,04 secretAccessKey: process.env.AWS_SECRET_KEY05});0607async function storeScreenshotSecurely(screenshotBuffer, filename) {08 // Set appropriate permissions09 const params = {10 Bucket: process.env.S3_BUCKET,11 Key: `screenshots/${filename}`,12 Body: screenshotBuffer,13 ContentType: 'image/png',14 ACL: 'private', // Private by default15 ServerSideEncryption: 'AES256' // Enable server-side encryption16 };1718 return s3.upload(params).promise();19}
Implement Signed URLs for Access
Generate time-limited signed URLs for accessing screenshots:
01function getSignedScreenshotUrl(filename) {02 const params = {03 Bucket: process.env.S3_BUCKET,04 Key: `screenshots/${filename}`,05 Expires: 3600 // URL expires in 1 hour06 };0708 return s3.getSignedUrl('getObject', params);09}1011app.get('/api/screenshots/:id', authenticateUser, async (req, res) => {12 // Check if user has permission to access this screenshot13 if (!userCanAccessScreenshot(req.user, req.params.id)) {14 return res.status(403).json({ error: 'Access denied' });15 }1617 const filename = await getScreenshotFilename(req.params.id);18 const signedUrl = getSignedScreenshotUrl(filename);1920 res.json({ url: signedUrl });21});
Monitoring and Logging
Implement Comprehensive Logging
01const winston = require('winston');02const logger = winston.createLogger({03 level: 'info',04 format: winston.format.json(),05 transports: [06 new winston.transports.File({ filename: 'error.log', level: 'error' }),07 new winston.transports.File({ filename: 'combined.log' })08 ]09});1011app.post('/api/screenshots', (req, res) => {12 logger.info('Screenshot requested', {13 userId: req.user.id,14 targetUrl: req.body.url,15 timestamp: new Date().toISOString(),16 ip: req.ip17 });1819 // Process screenshot20});
Set Up Alerts for Suspicious Activity
01function checkForSuspiciousActivity(logs) {02 const thresholds = {03 requestsPerMinute: 30,04 uniqueUrlsPerMinute: 20,05 errorRate: 0.3 // 30%06 };0708 // Analyze logs and trigger alerts09 // ...1011 if (suspiciousActivityDetected) {12 sendAlert('Suspicious screenshot API activity detected');13 }14}
Regular Security Audits
Schedule regular security audits of your Screenshot API integration:
- Review API key usage and rotation policies
- Check access logs for unusual patterns
- Verify URL validation and sanitization mechanisms
- Test authentication and authorization controls
- Review screenshot storage security
By implementing these security best practices, you can safely integrate our Screenshot API into your applications while protecting your data and users from potential security risks.
Ready to Get Started?
Get your API key now and start capturing screenshots in minutes.