SECURITY: Enforce server-side validation for all PIN/password attempts

Critical security fix: PIN and password minigames were falling back to
client-side validation when the correct answer was available. This allowed
players to bypass security by inspecting client-side code.

Changes:
- PIN minigame: ALWAYS use server-side validation, never client-side
- Password minigame: ALWAYS use server-side validation, never client-side
- If API client is unavailable, fail securely by rejecting the attempt
- Removed backwards compatibility code that allowed client-side validation

Security principle: Never trust the client for authentication/authorization.
All PIN and password validation must go through the server.
This commit is contained in:
Z. Cliffe Schreuders
2025-11-22 00:46:56 +00:00
parent d59aaf51f9
commit cda71cf6f3
2 changed files with 13 additions and 20 deletions

View File

@@ -398,23 +398,15 @@ export class PasswordMinigame extends MinigameScene {
this.gameData.attempts++;
this.attemptsDisplay.textContent = this.gameData.attempts;
// Check if we need server-side validation (correctPassword is null or empty string)
// SECURITY: ALWAYS use server-side validation for password attempts
const apiClient = window.ApiClient || window.APIClient;
if ((!this.correctPassword || this.correctPassword === '') && apiClient && gameId) {
console.log('Using server-side validation');
if (apiClient && gameId) {
console.log('Using server-side validation (security enforced)');
await this.validatePasswordWithServer(enteredPassword);
} else {
console.log('Using client-side validation', {
correctPassword: this.correctPassword,
hasApiClient: !!apiClient,
gameId: gameId
});
// Client-side validation (backwards compatibility)
if (enteredPassword === this.correctPassword) {
this.passwordCorrect();
} else {
this.passwordIncorrect();
}
console.error('SECURITY WARNING: API client not available, cannot validate password');
// Fail securely - reject the attempt if we can't validate with server
this.passwordIncorrect();
}
}

View File

@@ -247,17 +247,18 @@ export class PinMinigame extends MinigameScene {
this.attemptCount++;
// Check if we need server-side validation (correctPin is null or empty)
// SECURITY: ALWAYS use server-side validation for PIN attempts
let isCorrect;
const apiClient = window.ApiClient || window.APIClient;
const gameId = window.breakEscapeConfig?.gameId;
if ((!this.correctPin || this.correctPin === '') && apiClient && gameId) {
console.log('Using server-side PIN validation');
if (apiClient && gameId) {
console.log('Using server-side PIN validation (security enforced)');
isCorrect = await this.validatePinWithServer(this.currentInput);
} else {
console.log('Using client-side PIN validation');
// Client-side validation (backwards compatibility)
isCorrect = this.currentInput === this.correctPin;
console.error('SECURITY WARNING: API client not available, cannot validate PIN');
// Fail securely - reject the attempt if we can't validate with server
isCorrect = false;
}
// Record attempt