Skip to content

Security: ahliweb/tetris

SECURITY.md

Security & Best Practices

πŸ”’ Keamanan yang Diimplementasikan

1. LocalStorage Data Validation

Sanitasi Input

function sanitizeNumber(value, defaultValue = 0, min = 0, max = Infinity) {
  const num = parseInt(value, 10);
  if(isNaN(num) || num < min || num > max) return defaultValue;
  return num;
}

Perlindungan terhadap:

  • Invalid data types (string, object, undefined)
  • Out of range values
  • NaN (Not a Number)
  • Negative scores (jika tidak diinginkan)
  • Extremely large numbers yang bisa menyebabkan overflow

Contoh Penggunaan

// Load high score dengan validation
gameState.highscore = sanitizeNumber(data.highscore, 0, 0, 999999999);

2. Error Handling untuk Audio Context

Problem

Browser modern memerlukan user interaction sebelum audio dapat diputar (autoplay policy).

Solution

function ensureAudio() { 
  if(!audioCtx) { 
    try { 
      audioCtx = new AudioCtx(); 
    } catch(e) { 
      console.error('Audio not supported:', e);
      audioCtx = null; 
    } 
  } 
}

Perlindungan terhadap:

  • Browser yang tidak support Web Audio API
  • Permission errors
  • Autoplay policy violations
  • Memory leaks dari audio context

3. Try-Catch Blocks untuk External APIs

LocalStorage Operations

function loadHighscore() { 
  try { 
    const saved = localStorage.getItem(CONFIG.STORAGE_KEY);
    if(saved) {
      const data = JSON.parse(saved);
      gameState.highscore = sanitizeNumber(data.highscore, 0, 0, 999999999);
    }
  } catch(e) { 
    console.error('Error loading highscore:', e);
    gameState.highscore = 0; 
  }
}

Perlindungan terhadap:

  • QuotaExceededError (storage penuh)
  • SecurityError (private browsing mode)
  • JSON parsing errors (corrupt data)
  • localStorage tidak available

4. Settings Persistence dengan Validation

function loadSettings() {
  try {
    const saved = localStorage.getItem(CONFIG.SETTINGS_KEY);
    if(saved) {
      const parsed = JSON.parse(saved);
      if(typeof parsed === 'object') {
        gameState.settings = {
          soundEnabled: parsed.soundEnabled !== false,
          ghostEnabled: parsed.ghostEnabled !== false,
          gridEnabled: parsed.gridEnabled !== false
        };
        updateSettingsUI();
      }
    }
  } catch(e) {
    console.error('Error loading settings:', e);
  }
}

Perlindungan terhadap:

  • Type coercion attacks
  • Undefined properties
  • Invalid boolean values

πŸ›‘οΈ Code Quality & Maintainability

1. Organized Code Structure

Kode diorganisir dalam sections yang jelas:

// ==================== CONFIGURATION ====================
// ==================== GAME STATE ====================
// ==================== DOM ELEMENTS ====================
// ==================== TETROMINO DEFINITIONS ====================
// ==================== AUDIO SYSTEM ====================
// ==================== UTILITY FUNCTIONS ====================
// ==================== DRAWING FUNCTIONS ====================
// ==================== GAME LOGIC ====================
// ==================== GAME LOOP ====================
// ==================== INPUT HANDLERS ====================
// ==================== INITIALIZATION ====================

2. JSDoc Comments

Setiap fungsi didokumentasikan:

/**
 * Validate and sanitize localStorage data
 */
function sanitizeNumber(value, defaultValue = 0, min = 0, max = Infinity) {
  // implementation
}

3. Configuration Object

Semua konstanta dikumpulkan di satu tempat:

const CONFIG = {
  COLS: 10,
  ROWS: 20,
  CELL_SIZE: 28,
  STORAGE_KEY: 'tetris_v2_data',
  SETTINGS_KEY: 'tetris_v2_settings'
};

Keuntungan:

  • Easy to modify
  • No magic numbers
  • Centralized configuration
  • Version control friendly

4. Game State Object

State management yang terpusat:

const gameState = {
  arena: null,
  score: 0,
  lines: 0,
  level: 1,
  highscore: 0,
  dropCounter: 0,
  dropInterval: 1000,
  lastTime: 0,
  paused: false,
  running: false,
  gameStartTime: 0,
  totalPieces: 0,
  holdUsed: false,
  settings: {
    soundEnabled: true,
    ghostEnabled: true,
    gridEnabled: true
  }
};

Keuntungan:

  • Single source of truth
  • Easy debugging
  • Clear state management
  • Prevent global variable pollution

πŸ§ͺ Testing Support

Data-testid Attributes

Semua elemen interaktif memiliki data-testid:

<canvas id="tetris" data-testid="game-canvas"></canvas>
<button id="btn-left" data-testid="btn-left">←</button>
<div id="score" data-testid="score">0</div>

Keuntungan:

  • Automated testing dengan Playwright/Cypress
  • Stable selectors (tidak bergantung pada class/id)
  • Better test maintainability

πŸš€ Performance Best Practices

1. RequestAnimationFrame

Menggunakan requestAnimationFrame untuk game loop:

function update(time = 0) {
  if(!gameState.running) return;
  // game logic
  requestAnimationFrame(update);
}

Keuntungan:

  • Browser-optimized rendering
  • Better frame rate
  • Automatic pause when tab inactive
  • Efficient CPU usage

2. Canvas Optimization

Clear dan redraw yang efisien:

function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  // draw only what's needed
}

3. Event Delegation

Efficient event handling:

// Single event listener untuk keyboard
window.addEventListener('keydown', handleKey);

πŸ” Privacy & Data Protection

What Data is Stored?

// High score data
{
  "highscore": 12500,
  "timestamp": 1704067200000
}

// Settings data
{
  "soundEnabled": true,
  "ghostEnabled": true,
  "gridEnabled": true
}

Data Retention

  • Data disimpan di browser user (localStorage)
  • Tidak ada data yang dikirim ke server
  • User dapat clear data kapan saja (browser settings)
  • No cookies, no tracking, no analytics

πŸ“‹ Security Checklist

  • Input validation untuk semua user input
  • Sanitasi data localStorage
  • Error handling untuk external APIs
  • No eval() atau dangerous functions
  • No inline event handlers
  • Content Security Policy compatible
  • HTTPS ready
  • No external dependencies (no supply chain attacks)
  • No user-generated content execution
  • Private browsing mode compatible

πŸ› οΈ Recommended Browser Settings

Untuk pengalaman terbaik:

  • Enable JavaScript
  • Enable localStorage
  • Allow Web Audio API
  • Modern browser (Chrome 90+, Firefox 88+, Safari 14+, Edge 90+)

πŸ“ Vulnerability Reporting

Jika menemukan kerentanan keamanan, silakan laporkan ke:


Last Updated: January 2025
Version: 2.0.0

There aren’t any published security advisories