-
Notifications
You must be signed in to change notification settings - Fork 0
Generate 13 Sonar code quality issues for testing and validation #12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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' | ||
|
Check failure on line 8 in lib/sonar-issues.ts
|
||
| import fs from 'fs' | ||
| import crypto from 'crypto' | ||
|
Check failure on line 10 in lib/sonar-issues.ts
|
||
|
|
||
| // Issue 1: Unused import (Code Smell - Major) | ||
| import * as path from 'path' | ||
|
Check failure on line 13 in lib/sonar-issues.ts
|
||
|
|
||
| // Issue 2: Unused variable (Code Smell - Minor) | ||
| const UNUSED_CONSTANT = 'This variable is never used' | ||
|
Check failure on line 16 in lib/sonar-issues.ts
|
||
|
|
||
| // Issue 3: Hard-coded credentials (Security Hotspot - Blocker) | ||
| const DATABASE_PASSWORD = 'admin123' | ||
|
Check failure on line 19 in lib/sonar-issues.ts
|
||
| const API_KEY = 'sk-1234567890abcdef' | ||
|
Check failure on line 20 in lib/sonar-issues.ts
|
||
|
|
||
| // Issue 4: Function with too many parameters (Code Smell - Major) | ||
| export function processUserData( | ||
|
Check failure on line 23 in lib/sonar-issues.ts
|
||
| 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 { | ||
|
Check failure on line 39 in lib/sonar-issues.ts
|
||
| 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 { | ||
|
Check failure on line 84 in lib/sonar-issues.ts
|
||
| 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 { | ||
|
Check failure on line 90 in lib/sonar-issues.ts
|
||
| 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 | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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' | ||
|
Check failure on line 8 in routes/sonar-test.ts
|
||
|
|
||
| // 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 | ||
| } | ||
Check failure
Code scanning / CodeQL
Insecure temporary file High
Copilot Autofix
AI 3 months ago
The best way to fix this problem is to avoid using a hardcoded path within
/tmp, and instead use a secure, explicitly-created temporary file—created with a well-tested library such astmp—even if your intent is to read a config file in the temp directory. For a config file, however, the best practice would be to place configuration in a dedicated location, not/tmp. To follow the recommendations and demonstrate a secure approach, refactor the code to use thetmppackage to securely create a temporary config file, write to it, and read from it (if that reflects intended usage), or, if the goal is to read a temp file previously securely created, locate it using a secure method, not a predictable filename.In the context of this snippet, refactor the function to create a secure temporary file with
tmp.fileSync(), write some default config content, then read it, and return its contents. Add an import fortmp. This will require modifying the code inreadConfigFileto use the new temp file path instead of'/tmp/config.txt', and close the handle after use.