Security
Security Best Practices
This document outlines essential security practices for deploying and maintaining your Shopify app, covering both Laravel and Express versions.
Deployment Environment
Production Settings
Laravel:
- Set application environment to production:
APP_ENV=production
APP_DEBUG=false
- Configure proper error reporting:
LOG_LEVEL=error
LOG_CHANNEL=stack
- Disable development packages:
composer install --no-dev --optimize-autoloader
Express:
- Set Node environment to production:
NODE_ENV=production
- Disable debug output:
DEBUG=false
- Install only production dependencies:
npm ci --only=production
Credentials Management
Fly.io Deployment
Never store sensitive credentials in fly.toml
. Instead, set secrets using Fly.io's CLI:
# Set individual secrets
fly secrets set SHOPIFY_API_KEY=your_api_key
fly secrets set SHOPIFY_API_SECRET=your_api_secret
fly secrets set APP_KEY=your_app_key
# Or set multiple secrets from .env file
fly secrets import < .env
Local Development
- Never commit
.env
files to version control - Maintain an
.env.example
file with dummy values - Use different API keys for development and production
Database Security
Laravel:
- Use prepared statements (Laravel's query builder and Eloquent handle this automatically)
- Enable database SSL connections in production:
DB_SSL=true
DB_SSL_VERIFY=true
Express:
- Use parameterized queries with your ORM or query builder
- Enable SSL for database connections:
const connection = {
ssl: {
rejectUnauthorized: true,
},
}
API Security
- Implement rate limiting:
Laravel:
// In RouteServiceProvider.php
Route::middleware(['api', 'throttle:60,1'])->group(function () {
// API routes
});
Express:
const rateLimit = require("express-rate-limit")
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // limit each IP to 100 requests per windowMs
})
app.use("/api/", limiter)
- Validate all incoming Shopify webhooks:
- Verify webhook signatures
- Implement proper HMAC validation for app proxy requests
Session Security
Laravel:
- Use secure session configuration:
SESSION_DRIVER=redis
SESSION_SECURE_COOKIE=true
SESSION_DOMAIN=.yourdomain.com
Express:
app.use(
session({
secret: process.env.SESSION_SECRET,
name: "__Secure-session",
cookie: {
secure: true,
httpOnly: true,
sameSite: "strict",
},
resave: false,
saveUninitialized: false,
})
)
Headers and Middleware
Laravel:
- Enable security headers using the
SecurityHeaders
middleware:
// In app/Http/Kernel.php
protected $middleware = [
\App\Http\Middleware\SecurityHeaders::class,
];
Express:
const helmet = require("helmet")
app.use(
helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "cdn.shopify.com"],
frameSrc: ["'self'", "*.shopify.com"],
connectSrc: ["'self'", "api.shopify.com"],
},
},
referrerPolicy: { policy: "strict-origin-when-cross-origin" },
})
)
File Upload Security
- Validate file types and sizes
- Store uploaded files outside the web root
- Use signed URLs for file access
Laravel:
// config/filesystems.php
'uploads' => [
'driver' => 'local',
'root' => storage_path('app/uploads'),
'visibility' => 'private',
],
Express:
const multer = require("multer")
const storage = multer.diskStorage({
destination: "private/uploads/",
filename: (req, file, cb) => {
const uniqueSuffix = Date.now() + "-" + Math.round(Math.random() * 1e9)
cb(null, file.fieldname + "-" + uniqueSuffix)
},
})
Regular Maintenance
- Keep dependencies updated:
# Laravel
composer update
npm update
# Express
npm update
- Run security audits regularly:
# Laravel
composer audit
npm audit
# Express
npm audit
- Monitor security advisories:
- Subscribe to Laravel Security Advisories
- Enable GitHub security alerts for your repository
- Regular review of npm audit reports
Logging and Monitoring
- Implement proper logging:
- Use structured logging
- Don't log sensitive information
- Rotate log files
- Set up monitoring:
- Configure error tracking (e.g., Sentry)
- Enable performance monitoring
- Set up uptime monitoring
Remember to regularly review and update these security measures as new versions of Laravel, Express, and their dependencies are released.