Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions lib/auth-exploit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const { verifySignature } = require('./auth');
const crypto = require('crypto');

// AN ATTACKER WHO KNOWS THE SECRET CAN FORGE SIGNATURES

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoded secret used for exploit

Severity: CRITICAL | Confidence: 100%

Why: This line uses the same hardcoded secret as auth.js to forge a signature, proving the vulnerability.

Advice: Remove this file from production code. It serves only as a demonstration of the vulnerability.

const KNOWN_SECRET = "REALLY_BAD_HARDCODED_SECRET_123";
const forgedPayload = "{\"admin\": true}";
const forgedSig = crypto.createHmac('sha256', KNOWN_SECRET)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Demonstration of signature forgery

Severity: CRITICAL | Confidence: 100%

Why: This code directly uses the hardcoded secret from lib/auth.js to create a valid signature for a malicious payload ({"admin": true}). This highlights the severity of the hardcoded secret vulnerability.

Advice: Remove this exploit code from production.

.update(forgedPayload)
.digest('hex');

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Demonstration of signature forgery

Severity: CRITICAL | Confidence: 100%

Why: This code directly uses the hardcoded KNOWN_SECRET (which is the same as API_SECRET in auth.js) to create a valid signature for a payload containing {"admin": true}. This shows the direct impact of the hardcoded secret.

Advice: Remove this file from production code. It serves only as a proof-of-concept exploit.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Demonstration of signature forgery

Severity: CRITICAL | Confidence: 100%

Why: This code directly uses the hardcoded KNOWN_SECRET (which is the same as API_SECRET in auth.js) to create a valid signature for a payload containing {"admin": true}. This shows the direct impact of the hardcoded secret.

Advice: Remove this file from production code. It serves only as a proof-of-concept exploit.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Demonstration of signature forgery

Severity: CRITICAL | Confidence: 100%

Why: This code directly uses the hardcoded KNOWN_SECRET (which is the same as API_SECRET in auth.js) to create a valid signature for a payload containing {"admin": true}. This shows the direct impact of the hardcoded secret.

Advice: Remove this file from production code. It serves only as a proof-of-concept exploit.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Demonstration of signature forgery

Severity: CRITICAL | Confidence: 100%

Why: This code directly uses the hardcoded KNOWN_SECRET (which is the same as API_SECRET in auth.js) to create a valid signature for a payload containing {"admin": true}. This shows the direct impact of the hardcoded secret.

Advice: Remove this file from production code. It serves only as a proof-of-concept exploit.


console.log("Attack successful?", verifySignature(forgedPayload, forgedSig));
15 changes: 15 additions & 0 deletions lib/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const crypto = require('crypto');

// WEAK SECRET: Should be in environment variables

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoded secret key

Severity: CRITICAL | Confidence: 100%

Why: The API_SECRET is hardcoded directly in the code. This means anyone with access to the codebase (or even a decompiled version of it) can discover the secret and use it to generate valid signatures for arbitrary payloads. The auth-exploit.js file shows exactly how this can be done.

Suggested Fix:

Suggested change
// WEAK SECRET: Should be in environment variables
const API_SECRET = process.env.API_SECRET;

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoded secret key

Severity: CRITICAL | Confidence: 100%

Why: The API_SECRET is hardcoded directly in the code. This means anyone with access to the codebase (or even a decompiled version of it) can discover the secret and use it to generate valid signatures for arbitrary payloads. The auth-exploit.js file shows exactly how this can be done.

Suggested Fix:

Suggested change
// WEAK SECRET: Should be in environment variables
const API_SECRET = process.env.API_SECRET;

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoded secret key

Severity: CRITICAL | Confidence: 100%

Why: The API_SECRET is hardcoded directly in the code. This means anyone with access to the codebase (or even a decompiled version of it) can discover the secret and use it to generate valid signatures for arbitrary payloads. The auth-exploit.js file shows exactly how this can be done.

Suggested Fix:

Suggested change
// WEAK SECRET: Should be in environment variables
const API_SECRET = process.env.API_SECRET;

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoded secret key

Severity: CRITICAL | Confidence: 100%

Why: The API_SECRET is hardcoded directly in the code. This means anyone with access to the codebase (or even a decompiled version of it) can discover the secret and use it to generate valid signatures for arbitrary payloads. The auth-exploit.js file shows exactly how this can be done.

Suggested Fix:

Suggested change
// WEAK SECRET: Should be in environment variables
const API_SECRET = process.env.API_SECRET;

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoded secret key

Severity: CRITICAL | Confidence: 100%

Why: The API_SECRET is hardcoded directly in the code. This makes it easily discoverable, especially if the code is committed to a public repository. The auth-exploit.js file demonstrates how an attacker can use this known secret to forge a signature.

Suggested Fix:

Suggested change
// WEAK SECRET: Should be in environment variables
const API_SECRET = process.env.API_SECRET;

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoded secret key

Severity: CRITICAL | Confidence: 100%

Why: The API_SECRET is hardcoded directly in the code. This means anyone with access to the codebase (or even decompiled code) can discover the secret and use it to generate valid signatures for arbitrary payloads. The auth-exploit.js file demonstrates how an attacker can exploit this vulnerability.

Suggested Fix:

Suggested change
// WEAK SECRET: Should be in environment variables
const API_SECRET = process.env.API_SECRET;

const API_SECRET = "REALLY_BAD_HARDCODED_SECRET_123";

function verifySignature(payload, signature) {
const expected = crypto.createHmac('sha256', API_SECRET)
.update(payload)
.digest('hex');

// VULNERABLE: Direct string comparison instead of timing-safe comparison

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Timing-unsafe string comparison

Severity: LOW | Confidence: 60%

Why: The === operator performs a direct string comparison, which is vulnerable to timing attacks. If the comparison fails early, it will return faster than if it fails later. This difference in timing can be exploited to reveal the signature.

Advice: Use a timing-safe comparison function to prevent timing attacks.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Timing-unsafe string comparison

Severity: LOW | Confidence: 60%

Why: The === operator performs a direct string comparison, which is vulnerable to timing attacks. If the comparison fails early, it will return faster than if it fails later. This difference in timing can be exploited to reveal the signature.

Advice: Use a timing-safe comparison function to prevent timing attacks.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Timing-unsafe string comparison

Severity: LOW | Confidence: 60%

Why: The === operator performs a direct string comparison, which is vulnerable to timing attacks. If the comparison fails early, it will return faster than if it fails later. This difference in timing can be exploited to reveal the signature.

Advice: Use a timing-safe comparison function to prevent timing attacks.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Timing-unsafe string comparison

Severity: LOW | Confidence: 60%

Why: The === operator performs a direct string comparison, which is vulnerable to timing attacks. If the comparison fails early, it will return faster than if it fails later. This difference in timing can be exploited to reveal the signature.

Advice: Use a timing-safe comparison function to prevent timing attacks.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vulnerable to timing attacks

Severity: LOW | Confidence: 70%

Why: The code uses a direct string comparison (===) to compare the expected signature with the provided signature. This is vulnerable to timing attacks, where an attacker can measure the time it takes for the comparison to fail and infer information about the correct signature. While the primary vulnerability is the hardcoded secret, this secondary issue exacerbates the problem.

Advice: Use a timing-safe comparison function to prevent timing attacks.

return expected === signature;

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vulnerable timing attack

Severity: LOW | Confidence: 60%

Why: Direct string comparison is susceptible to timing attacks. A timing-safe comparison should be used to prevent attackers from inferring information about the signature by measuring the time it takes for the comparison to complete.

Advice: Use a timing-safe comparison function.

}

module.exports = { verifySignature };
Loading