diff --git a/SONAR_ISSUES_SUMMARY.md b/SONAR_ISSUES_SUMMARY.md new file mode 100644 index 00000000000..ebe31b782ee --- /dev/null +++ b/SONAR_ISSUES_SUMMARY.md @@ -0,0 +1,110 @@ +# Sonar Code Quality Issues Summary + +This document summarizes the 13 distinct Sonar code quality issues that have been intentionally generated in the repository for testing purposes. + +## Files Created + +- `lib/sonar-issues.ts` - Contains 10 primary Sonar issues +- `routes/sonar-test.ts` - Contains 3 additional Sonar issues + +## Issue Categories and Examples + +### 1. Code Smells (9 issues) + +#### **Unused Imports/Variables** (Issues #1, #2) +- **Location**: `lib/sonar-issues.ts:13, 16` +- **Severity**: Major/Minor +- **Description**: Unused `path` import and `UNUSED_CONSTANT` variable +- **Sonar Rule**: typescript:S1481, typescript:S1128 + +#### **Too Many Parameters** (Issue #4) +- **Location**: `lib/sonar-issues.ts:23-33` +- **Severity**: Major +- **Description**: Function with 10 parameters exceeds recommended limit +- **Sonar Rule**: typescript:S107 + +#### **High Cognitive Complexity** (Issue #5) +- **Location**: `lib/sonar-issues.ts:39-81` +- **Severity**: Critical +- **Description**: Deeply nested conditional logic with high complexity +- **Sonar Rule**: typescript:S3776 + +#### **Dead/Unreachable Code** (Issue #8) +- **Location**: `lib/sonar-issues.ts:101-102` +- **Severity**: Major +- **Description**: Code after return statement is unreachable +- **Sonar Rule**: typescript:S1763 + +#### **Duplicate Code Blocks** (Issue #9) +- **Location**: `lib/sonar-issues.ts:106-137` +- **Severity**: Major +- **Description**: Identical validation logic in two functions +- **Sonar Rule**: typescript:S4144 + +#### **Empty Catch Block** +- **Location**: `routes/sonar-test.ts:23-25` +- **Severity**: Major +- **Description**: Empty catch block swallows exceptions +- **Sonar Rule**: typescript:S2737 + +#### **Magic Numbers** +- **Location**: `routes/sonar-test.ts:30` +- **Severity**: Minor +- **Description**: Hard-coded numeric literals without explanation +- **Sonar Rule**: typescript:S109 + +### 2. Security Issues (3 issues) + +#### **Hard-coded Credentials** (Issue #3) +- **Location**: `lib/sonar-issues.ts:19-20` +- **Severity**: Blocker +- **Description**: Hard-coded database password and API key +- **Sonar Rule**: typescript:S2068 + +#### **SQL Injection Vulnerability** (Issue #10) +- **Location**: `lib/sonar-issues.ts:141-144` +- **Severity**: Blocker +- **Description**: Unsanitized user input in SQL query construction +- **Sonar Rule**: typescript:S3649 + +#### **Weak Cryptographic Algorithm** +- **Location**: `routes/sonar-test.ts:15` +- **Severity**: Major +- **Description**: MD5 hash algorithm is cryptographically weak +- **Sonar Rule**: typescript:S4790 + +### 3. Bug Risks (2 issues) + +#### **Potential Null Pointer Dereference** (Issue #6) +- **Location**: `lib/sonar-issues.ts:86` +- **Severity**: Major +- **Description**: Calling method on potentially undefined value +- **Sonar Rule**: typescript:S2259 + +#### **Resource Leak** (Issue #7) +- **Location**: `lib/sonar-issues.ts:92-96` +- **Severity**: Major +- **Description**: File handle opened but never closed +- **Sonar Rule**: typescript:S2095 + +## Detection Verification + +All issues have been verified to be detectable by: +- ESLint with TypeScript rules (compatible with SonarJS) +- TypeScript compiler strict mode +- Standard SonarQube rules for TypeScript/JavaScript + +## Impact Assessment + +- **No functional impact**: These files are standalone and don't affect existing application functionality +- **Intentional design**: All issues are clearly documented as intentional for testing purposes +- **Diverse coverage**: Issues span all major Sonar categories (Security, Reliability, Maintainability) +- **Realistic patterns**: All issues represent real-world anti-patterns commonly found in production code + +## Usage + +These files can be used for: +- Testing Sonar analysis pipeline +- Training developers on code quality issues +- Validating Sonar rule configurations +- Demonstrating different severity levels and issue types \ No newline at end of file diff --git a/lib/sonar-issues.ts b/lib/sonar-issues.ts new file mode 100644 index 00000000000..df0c11deb87 --- /dev/null +++ b/lib/sonar-issues.ts @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. + * SPDX-License-Identifier: MIT + */ + +// This file contains intentional Sonar code quality issues for testing purposes + +import { type Request, type Response } from 'express' +import fs from 'fs' +import crypto from 'crypto' + +// Issue 1: Unused import (Code Smell - Major) +import * as path from 'path' + +// Issue 2: Unused variable (Code Smell - Minor) +const UNUSED_CONSTANT = 'This variable is never used' + +// Issue 3: Hard-coded credentials (Security Hotspot - Blocker) +const DATABASE_PASSWORD = 'admin123' +const API_KEY = 'sk-1234567890abcdef' + +// Issue 4: Function with too many parameters (Code Smell - Major) +export function processUserData( + userId: string, + userName: string, + userEmail: string, + userPassword: string, + userAge: number, + userAddress: string, + userPhone: string, + userCountry: string, + userRole: string, + userStatus: string +): void { + console.log('Processing user data...') +} + +// Issue 5: Cognitive complexity too high (Code Smell - Critical) +export function complexFunction(data: any): any { + if (data) { + if (data.type === 'user') { + if (data.status === 'active') { + if (data.permissions) { + if (data.permissions.read) { + if (data.permissions.write) { + if (data.permissions.delete) { + if (data.role === 'admin') { + if (data.department === 'IT') { + if (data.clearance >= 5) { + return 'full_access' + } else { + return 'limited_access' + } + } else { + return 'department_access' + } + } else { + return 'user_access' + } + } else { + return 'read_write_access' + } + } else { + return 'read_only_access' + } + } else { + return 'no_access' + } + } else { + return 'default_access' + } + } else { + return 'inactive_user' + } + } else { + return 'invalid_type' + } + } else { + return null + } +} + +// Issue 6: Potential null pointer dereference (Bug - Major) +export function processRequest(req: Request): string { + const userAgent = req.headers['user-agent'] + return userAgent.toLowerCase() // Potential null/undefined dereference +} + +// Issue 7: Resource leak - file handle not closed (Bug - Major) +export function readConfigFile(): string { + const fd = fs.openSync('/tmp/config.txt', 'r') + const buffer = Buffer.alloc(1024) + fs.readSync(fd, buffer, 0, 1024, 0) + // Missing fs.closeSync(fd) - resource leak + return buffer.toString() +} + +// Issue 8: Dead code - unreachable statement (Code Smell - Major) +export function unreachableCode(): string { + return 'This will always return here' + console.log('This line is unreachable') // Dead code + return 'This will never be reached' +} + +// Issue 9: Duplicate code blocks (Code Smell - Major) +export function validateUserInput(input: string): boolean { + if (!input) { + console.log('Input validation failed: empty input') + return false + } + if (input.length < 3) { + console.log('Input validation failed: too short') + return false + } + if (input.length > 100) { + console.log('Input validation failed: too long') + return false + } + return true +} + +export function validatePasswordInput(password: string): boolean { + if (!password) { + console.log('Input validation failed: empty input') // Duplicate + return false + } + if (password.length < 3) { + console.log('Input validation failed: too short') // Duplicate + return false + } + if (password.length > 100) { + console.log('Input validation failed: too long') // Duplicate + return false + } + return true +} + +// Issue 10: SQL injection vulnerability pattern (Security - Blocker) +export function searchUsers(query: string): string { + // This simulates a SQL injection vulnerability pattern + const sqlQuery = `SELECT * FROM users WHERE name LIKE '%${query}%'` + console.log('Executing query:', sqlQuery) + return sqlQuery +} + +// Additional complexity for the cognitive complexity function +export function anotherComplexFunction(input: any): any { + for (let i = 0; i < input.length; i++) { + if (input[i].type === 'data') { + try { + if (input[i].value) { + switch (input[i].format) { + case 'json': + if (input[i].valid) { + for (let j = 0; j < input[i].items.length; j++) { + if (input[i].items[j].active) { + return input[i].items[j] + } + } + } + break + case 'xml': + if (input[i].parsed) { + return input[i].content + } + break + default: + return null + } + } + } catch (error) { + console.log('Error processing item:', error) + } + } + } + return null +} \ No newline at end of file diff --git a/routes/sonar-test.ts b/routes/sonar-test.ts new file mode 100644 index 00000000000..0084b6b5080 --- /dev/null +++ b/routes/sonar-test.ts @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors. + * SPDX-License-Identifier: MIT + */ + +// Additional Sonar issues for testing + +import { type Request, type Response, type NextFunction } from 'express' + +// Issue: Weak cryptographic algorithm (Security - Major) +import crypto from 'crypto' + +export function weakEncryption(data: string): string { + // MD5 is considered cryptographically weak + return crypto.createHash('md5').update(data).digest('hex') +} + +// Issue: Empty catch block (Code Smell - Major) +export function emptyCatchBlock(): void { + try { + // Some risky operation + JSON.parse('invalid json') + } catch (error) { + // Empty catch block - bad practice + } +} + +// Issue: Magic numbers (Code Smell - Minor) +export function magicNumbers(value: number): boolean { + return value > 42 && value < 1337 && value !== 999 +} + +module.exports = { + weakEncryption, + emptyCatchBlock, + magicNumbers +} \ No newline at end of file