Security Standards

v1.0 Last updated: December 2025

Security Overview

QR Igniter implements a defense-in-depth security strategy, with multiple layers of protection across all system components.

Security Responsibility

Security is everyone's responsibility. All developers must understand and follow these security standards.

Security Principles

  • Defense in Depth: Multiple security layers protect against single points of failure
  • Least Privilege: Users and systems only have access to what they need
  • Secure by Default: Default configurations are secure
  • Fail Securely: System failures don't expose vulnerabilities
  • Zero Trust: Never trust, always verify

OWASP Top 10 Compliance

QR Igniter implements protections against all OWASP Top 10 (2021) vulnerabilities:

Rank Vulnerability Protection
A01 Broken Access Control Role-based access control, policy-based authorization, tenant isolation
A02 Cryptographic Failures TLS 1.3, bcrypt for passwords, encrypted secrets, secure key management
A03 Injection Eloquent ORM, prepared statements, input validation, output encoding
A04 Insecure Design Threat modeling, secure architecture review, security requirements
A05 Security Misconfiguration Hardened configs, automated security checks, minimal installs
A06 Vulnerable Components Automated dependency scanning, regular updates, CVE monitoring
A07 Auth Failures Laravel Sanctum, rate limiting, secure session management
A08 Software/Data Integrity Signed commits, CI/CD pipeline security, integrity checks
A09 Logging/Monitoring Comprehensive audit logs, security event monitoring, alerting
A10 SSRF URL validation, allowlists, network segmentation

Authentication & Authorization

Authentication (Laravel Sanctum)

// API token authentication
Route::middleware('auth:sanctum')->group(function () {
    Route::apiResource('qr-codes', QrCodeController::class);
});

// Token abilities (scopes)
$token = $user->createToken('api-token', [
    'qr-codes:read',
    'qr-codes:write',
    'analytics:read',
]);

Password Requirements

  • Minimum 12 characters
  • Must contain uppercase and lowercase letters
  • Must contain numbers
  • Must contain special characters
  • Cannot match common password lists
  • Cannot contain user information

Session Security

  • Session timeout: 2 hours of inactivity
  • Absolute timeout: 8 hours
  • Session regeneration on privilege changes
  • Secure, HttpOnly, SameSite cookies

Authorization (Policies & Gates)

// Policy-based authorization
class QrCodePolicy
{
    public function view(User $user, QrCode $qrCode): bool
    {
        return $user->client_id === $qrCode->campaign->brand->client_id;
    }

    public function update(User $user, QrCode $qrCode): bool
    {
        return $this->view($user, $qrCode)
            && $user->hasPermission('qr-codes:write');
    }
}

Multi-Tenant Isolation

// Global scope for tenant isolation
class TenantScope implements Scope
{
    public function apply(Builder $builder, Model $model): void
    {
        if (auth()->check()) {
            $builder->where('client_id', auth()->user()->client_id);
        }
    }
}

Data Protection

Data Classification

Classification Examples Protection
Public Marketing content, documentation No special protection required
Internal QR code metadata, analytics Access control, audit logging
Confidential API keys, user data Encryption at rest, strict access control
Restricted Passwords, secrets Hashing, encryption, minimal exposure

Encryption

In Transit

  • TLS 1.3 for all connections
  • HTTPS enforced (HSTS enabled)
  • Strong cipher suites only

At Rest

  • Database encryption (InnoDB tablespace)
  • Encrypted file storage (S3 SSE)
  • Environment variables encrypted

Input Validation

// Form Request validation
class StoreQrCodeRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'gtin' => ['required', 'string', 'size:14', new ValidGtin()],
            'batch_number' => ['nullable', 'string', 'max:20', 'alpha_num'],
            'serial_number' => ['nullable', 'string', 'max:20', 'alpha_num'],
            'destination_url' => ['required', 'url', 'max:2048', new SafeUrl()],
        ];
    }
}

Output Encoding

// Blade templates auto-escape output
{{ $userInput }} // Escaped

// Use raw only when explicitly needed and sanitized
{!! $sanitizedHtml !!}

Mobile App Security

Secure Storage

// Flutter secure storage for sensitive data
import 'package:flutter_secure_storage/flutter_secure_storage.dart';

class SecureStorageService {
  final _storage = const FlutterSecureStorage(
    aOptions: AndroidOptions(encryptedSharedPreferences: true),
    iOptions: IOSOptions(accessibility: KeychainAccessibility.first_unlock),
  );

  Future<void> saveToken(String token) async {
    await _storage.write(key: 'auth_token', value: token);
  }
}

Certificate Pinning

// SSL certificate pinning
class ApiClient {
  late final Dio _dio;

  ApiClient() {
    _dio = Dio()
      ..httpClientAdapter = IOHttpClientAdapter(
        createHttpClient: () {
          final client = HttpClient();
          client.badCertificateCallback = (cert, host, port) {
            // Validate certificate fingerprint
            return _validateCertificate(cert);
          };
          return client;
        },
      );
  }
}

Mobile Security Checklist

  • No sensitive data in logs
  • Secure clipboard handling
  • Biometric authentication support
  • Root/jailbreak detection
  • Code obfuscation enabled
  • Debug mode disabled in release

Security Scanning

Automated Scanning Tools

Tool Type Frequency Integration
Composer Audit Dependency scanning Every build GitLab CI
npm audit JS dependency scanning Every build GitLab CI
PHPStan Static analysis Every build GitLab CI
Trivy Container scanning Every build GitLab CI
OWASP ZAP DAST Weekly Scheduled pipeline
Snyk Dependency + container Daily GitHub integration

CI/CD Security Pipeline

# .gitlab-ci.yml security stages
security:
  stage: security
  script:
    # PHP dependency audit
    - composer audit

    # JavaScript dependency audit
    - npm audit --audit-level=high

    # Static analysis for security issues
    - ./vendor/bin/phpstan analyse --level=max

    # Container vulnerability scanning
    - trivy image --severity HIGH,CRITICAL $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA

  allow_failure: false
  only:
    - main
    - merge_requests

Vulnerability Management

Severity SLA Action
Critical 24 hours Immediate patch, consider rollback
High 7 days Priority patch in next release
Medium 30 days Scheduled patch
Low 90 days Include in regular updates

Incident Response

Security Incident Classification

Level Description Examples Response
P1 - Critical Active breach, data exposure Data leak, ransomware Immediate escalation, all hands
P2 - High Significant vulnerability Auth bypass, RCE found 24-hour response, patch priority
P3 - Medium Contained issue XSS, CSRF found 7-day response, scheduled patch
P4 - Low Minor issue Information disclosure 30-day response

Incident Response Steps

  1. Detection: Identify and confirm the incident
  2. Containment: Limit the impact and prevent spread
  3. Eradication: Remove the threat
  4. Recovery: Restore systems to normal
  5. Lessons Learned: Document and improve

Security Contacts

Report Security Issues

Report security vulnerabilities to: security@ignited.cloud

For critical issues, contact the on-call security team immediately.