UNPKG

eslint-plugin-sonarjs

Version:
101 lines (100 loc) 5.11 kB
"use strict"; /* * SonarQube JavaScript Plugin * Copyright (C) 2011-2025 SonarSource SA * mailto:info AT sonarsource DOT com * * This program is free software; you can redistribute it and/or * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the Sonar Source-Available License for more details. * * You should have received a copy of the Sonar Source-Available License * along with this program; if not, see https://sonarsource.com/license/ssal/ */ // https://sonarsource.github.io/rspec/#/rspec/S5659/javascript Object.defineProperty(exports, "__esModule", { value: true }); exports.rule = void 0; const index_js_1 = require("../helpers/index.js"); const meta_js_1 = require("./meta.js"); exports.rule = { meta: (0, index_js_1.generateMeta)(meta_js_1.meta, undefined, true), create(context) { const SIGN_MESSAGE = 'Use only strong cipher algorithms when signing this JWT.'; const VERIFY_MESSAGE = 'Use only strong cipher algorithms when verifying the signature of this JWT.'; const SECONDARY_MESSAGE = `The "algorithms" option should be defined and should not contain 'none'.`; function checkCallToSign(callExpression, thirdArgumentValue, secondaryLocations) { const unsafeAlgorithmProperty = (0, index_js_1.getPropertyWithValue)(context, thirdArgumentValue, 'algorithm', 'none'); if (unsafeAlgorithmProperty) { const unsafeAlgorithmValue = (0, index_js_1.getValueOfExpression)(context, unsafeAlgorithmProperty.value, 'Literal'); if (unsafeAlgorithmValue && unsafeAlgorithmValue !== unsafeAlgorithmProperty.value) { secondaryLocations.push(unsafeAlgorithmValue); } raiseIssueOn(callExpression.callee, SIGN_MESSAGE, secondaryLocations); } } function checkCallToVerify(callExpression, publicKey, thirdArgumentValue, secondaryLocations) { const algorithmsProperty = (0, index_js_1.getProperty)(thirdArgumentValue, 'algorithms', context); if (!algorithmsProperty) { if ((0, index_js_1.isNullLiteral)(publicKey)) { raiseIssueOn(callExpression.callee, VERIFY_MESSAGE, secondaryLocations); } return; } const algorithmsValue = (0, index_js_1.getValueOfExpression)(context, algorithmsProperty.value, 'ArrayExpression'); if (!algorithmsValue) { return; } const algorithmsContainNone = algorithmsValue.elements.some(e => { const value = (0, index_js_1.getValueOfExpression)(context, e, 'Literal'); return value?.value === 'none'; }); if (algorithmsContainNone) { if (algorithmsProperty.value !== algorithmsValue) { secondaryLocations.push(algorithmsValue); } raiseIssueOn(callExpression.callee, VERIFY_MESSAGE, secondaryLocations); } } function raiseIssueOn(node, message, secondaryLocations) { (0, index_js_1.report)(context, { node, message, }, secondaryLocations.map(node => (0, index_js_1.toSecondaryLocation)(node, SECONDARY_MESSAGE))); } return { CallExpression: (node) => { const callExpression = node; const fqn = (0, index_js_1.getFullyQualifiedName)(context, callExpression); const isCallToSign = fqn === 'jsonwebtoken.sign'; const isCallToVerify = fqn === 'jsonwebtoken.verify'; if (!isCallToSign && !isCallToVerify) { return; } if (callExpression.arguments.length < 3) { // algorithm(s) property is contained in third argument of "sign" and "verify" calls return; } const thirdArgument = callExpression.arguments[2]; const thirdArgumentValue = (0, index_js_1.getValueOfExpression)(context, thirdArgument, 'ObjectExpression'); if (!thirdArgumentValue) { return; } const secondaryLocations = [thirdArgumentValue]; if (thirdArgumentValue !== thirdArgument) { secondaryLocations.push(thirdArgument); } if (isCallToSign) { checkCallToSign(callExpression, thirdArgumentValue, secondaryLocations); } const secondArgument = callExpression.arguments[1]; if (isCallToVerify) { checkCallToVerify(callExpression, secondArgument, thirdArgumentValue, secondaryLocations); } }, }; }, };