Return to Blog List
Screenshot API Security Best Practices
Security

Screenshot API Security Best Practices

April 12, 2025
7 min read

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

javascript
01// ❌ NEVER do this
02const apiKey = "sk_live_your_actual_api_key_here";
03
04document.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

javascript
01// ✅ Server-side code (Node.js)
02const express = require('express');
03const app = express();
04
05app.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 });
15
16 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:

javascript
01const rateLimit = require('express-rate-limit');
02
03// Create rate limiter
04const screenshotLimiter = rateLimit({
05 windowMs: 15 * 60 * 1000, // 15 minutes
06 max: 100, // Limit each IP to 100 requests per windowMs
07 message: 'Too many screenshot requests, please try again later'
08});
09
10// Apply to screenshot routes
11app.use('/api/screenshots', screenshotLimiter);

User Authentication

Ensure only authenticated users can request screenshots:

javascript
01const authenticateUser = (req, res, next) => {
02 const authHeader = req.headers.authorization;
03
04 if (!authHeader || !authHeader.startsWith('Bearer ')) {
05 return res.status(401).json({ error: 'Unauthorized' });
06 }
07
08 const token = authHeader.split(' ')[1];
09
10 try {
11 // Verify JWT token
12 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};
19
20// Apply authentication middleware
21app.post('/api/screenshots', authenticateUser, screenshotController.generate);

URL Validation and Sanitization

Validate Input URLs

Always validate URLs before sending them to the Screenshot API:

javascript
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};
09
10app.post('/api/screenshots', (req, res) => {
11 const { url } = req.body;
12
13 if (!url || !isValidUrl(url)) {
14 return res.status(400).json({ error: 'Invalid URL provided' });
15 }
16
17 // Proceed with screenshot generation
18});

Implement URL Allowlists

For additional security, consider implementing an allowlist of domains:

javascript
01const allowedDomains = [
02 'example.com',
03 'yourdomain.com',
04 'trusted-partner.com'
05];
06
07const 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};
17
18app.post('/api/screenshots', (req, res) => {
19 const { url } = req.body;
20
21 if (!isDomainAllowed(url)) {
22 return res.status(403).json({ error: 'Domain not allowed' });
23 }
24
25 // Proceed with screenshot generation
26});

Secure Storage and Handling of Screenshots

Secure Storage Options

When storing screenshots, ensure they're protected:

javascript
01const AWS = require('aws-sdk');
02const s3 = new AWS.S3({
03 accessKeyId: process.env.AWS_ACCESS_KEY,
04 secretAccessKey: process.env.AWS_SECRET_KEY
05});
06
07async function storeScreenshotSecurely(screenshotBuffer, filename) {
08 // Set appropriate permissions
09 const params = {
10 Bucket: process.env.S3_BUCKET,
11 Key: `screenshots/${filename}`,
12 Body: screenshotBuffer,
13 ContentType: 'image/png',
14 ACL: 'private', // Private by default
15 ServerSideEncryption: 'AES256' // Enable server-side encryption
16 };
17
18 return s3.upload(params).promise();
19}

Implement Signed URLs for Access

Generate time-limited signed URLs for accessing screenshots:

javascript
01function getSignedScreenshotUrl(filename) {
02 const params = {
03 Bucket: process.env.S3_BUCKET,
04 Key: `screenshots/${filename}`,
05 Expires: 3600 // URL expires in 1 hour
06 };
07
08 return s3.getSignedUrl('getObject', params);
09}
10
11app.get('/api/screenshots/:id', authenticateUser, async (req, res) => {
12 // Check if user has permission to access this screenshot
13 if (!userCanAccessScreenshot(req.user, req.params.id)) {
14 return res.status(403).json({ error: 'Access denied' });
15 }
16
17 const filename = await getScreenshotFilename(req.params.id);
18 const signedUrl = getSignedScreenshotUrl(filename);
19
20 res.json({ url: signedUrl });
21});

Monitoring and Logging

Implement Comprehensive Logging

javascript
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});
10
11app.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.ip
17 });
18
19 // Process screenshot
20});

Set Up Alerts for Suspicious Activity

javascript
01function checkForSuspiciousActivity(logs) {
02 const thresholds = {
03 requestsPerMinute: 30,
04 uniqueUrlsPerMinute: 20,
05 errorRate: 0.3 // 30%
06 };
07
08 // Analyze logs and trigger alerts
09 // ...
10
11 if (suspiciousActivityDetected) {
12 sendAlert('Suspicious screenshot API activity detected');
13 }
14}

Regular Security Audits

Schedule regular security audits of your Screenshot API integration:

  1. Review API key usage and rotation policies
  2. Check access logs for unusual patterns
  3. Verify URL validation and sanitization mechanisms
  4. Test authentication and authorization controls
  5. 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.

Best PracticesAPI

Ready to Get Started?

Get your API key now and start capturing screenshots in minutes.