Skip to main content

Authentication mechanism absence or evasion - Response tampering

Description

The OTP validation is performed according to the response of the request, an attacker can modify the response of the request to include the success message and thus continue with the flow to do the unblocking.

Impact

Skip OTP validation.

Recommendation

Set up an authentication process for every resource with business-critical functionality. Perform the pertinent validations of the critical functionalities in the back-end.

Threat

Unauthorized external attacker.

Expected Remediation Time

⌚ 90 minutes.

Score

Default score using CVSS 3.1. It may change depending on the context of the vulnerability.

Base

  • Attack vector: N
  • Attack complexity: L
  • Privileges required: N
  • User interaction: N
  • Scope: U
  • Confidentiality: N
  • Integrity: L
  • Availability: N

Temporal

  • Exploit code madurity: P
  • Remediation level: X
  • Report confidence: X

Result

  • Vector string: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N/E:P/RL:X/RC:X
  • Score:
    • Base: 5.3
    • Temporal: 5.0
  • Severity:
    • Base: Medium
    • Temporal: Medium

Code Examples

Compliant code

The OTP uses a secure method to generate temporary passwords

const requestPasswordReset = async (email) => {
const user = await User.findOne({ email });
if (!user) throw new Error("User does not exist");
let token = await Token.findOne({ userId: user._id });
if (token) await token.deleteOne();
let resetToken = crypto.randomBytes(32).toString("hex");
const hash = await bcrypt.hash(resetToken, Number(bcryptSalt));
const link = `${clientURL}/passwordReset?token=${resetToken}&id=${user._id}`;
const await token();
sendEmail(user.email,"Password Reset Request",{name: user.name,link: link,},"./template/requestResetPassword.handlebars");
return link;
};

Non compliant code

The OTP functionality sends an insecure temporary password

const requestPasswordTemporary = async (user) => {
if (!user) throw new Error("User does not exist");
//Password setup with an insecure algorithm, only 8 chars in length
const generatedPassword = createPassword(8, true, true);
//Send temporary insecure password
sendEmail(user.email,"Password Reset Request",{name: user.name,password: generatedPassword},"./template/requestResetPassword.handlebars");
return link;
};

Requirements