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:

  1. Set application environment to production:
APP_ENV=production
APP_DEBUG=false
  1. Configure proper error reporting:
LOG_LEVEL=error
LOG_CHANNEL=stack
  1. Disable development packages:
composer install --no-dev --optimize-autoloader

Express:

  1. Set Node environment to production:
NODE_ENV=production
  1. Disable debug output:
DEBUG=false
  1. 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:

  1. Use prepared statements (Laravel's query builder and Eloquent handle this automatically)
  2. Enable database SSL connections in production:
DB_SSL=true
DB_SSL_VERIFY=true

Express:

  1. Use parameterized queries with your ORM or query builder
  2. Enable SSL for database connections:
const connection = {
  ssl: {
    rejectUnauthorized: true,
  },
}

API Security

  1. 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)
  1. Validate all incoming Shopify webhooks:
  • Verify webhook signatures
  • Implement proper HMAC validation for app proxy requests

Session Security

Laravel:

  1. 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:

  1. 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

  1. Validate file types and sizes
  2. Store uploaded files outside the web root
  3. 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

  1. Keep dependencies updated:
# Laravel
composer update
npm update
 
# Express
npm update
  1. Run security audits regularly:
# Laravel
composer audit
npm audit
 
# Express
npm audit
  1. Monitor security advisories:
  • Subscribe to Laravel Security Advisories
  • Enable GitHub security alerts for your repository
  • Regular review of npm audit reports

Logging and Monitoring

  1. Implement proper logging:
  • Use structured logging
  • Don't log sensitive information
  • Rotate log files
  1. 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.