-
-
Notifications
You must be signed in to change notification settings - Fork 20
feat(crypto): add RSA-PSS codemod for DEP0154 #164
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
feat(crypto): add RSA-PSS codemod for DEP0154 #164
Conversation
Add codemod to transform deprecated RSA-PSS crypto options: - hash -> hashAlgorithm - mgf1Hash -> mgf1HashAlgorithm Only transforms crypto.generateKeyPair() and crypto.generateKeyPairSync() calls with 'rsa-pss' key type. Includes comprehensive test coverage for various usage patterns. Resolves: nodejs#144
Initial code generated with Claude Code assistance. Verified functionality through detailed review and testing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good starting ! But there are missing piece:
- if user do
import * as foo from 'node:crypto'
- if use do
const { generateKeyPair: foo } = require('node:crypto')
Solution: have this pr merged #151 EDIT it's merged you should use this utility
Also for strictness on parameters analyst you should do something like that:
for (const call of callNode) {
const optionsMatch = call.getMatch("OPTIONS");
if (!optionsMatch) continue;
// Find the object node that contains the URL options
const objectNode = optionsMatch.find({
rule: {
kind: "object"
}
});
if (!objectNode) continue;
// Find all property pairs in the object
const pairs = objectNode.findAll({
rule: {
kind: "pair"
}
});
// find hash pair then replace it
pairs.find(pair => {
const keyNode = pair.find({
rule: {
kind: "property_identifier"
}
});
if (!keyNode) return false;
const key = keyNode.text();
if (key === "hash") {
const valueNode = pair.find({
rule: {
kind: "string_fragment"
}
}) || pair.find({
rule: {
kind: "string"
}
});
if (!valueNode) return false;
const value = valueNode.text().slice(1, -1); // Remove quotes
const replacement = `hashAlgorithm: '${value}'`;
edits.push(call.replace(replacement));
return true;
}
return false;
});
}
- Add support for namespace imports (import * as crypto) - Add support for destructured renamed imports ({generateKeyPair: foo}) - Implement stricter parameter analysis for hash/mgf1Hash detection - Add comprehensive test cases for new import patterns Addresses feedback from nodejs#164
Hi @AugustinMauroy, I updated the branch, I would appreciate any feedback, thank you for your attention. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit
…dingPath utility Replace manual namespace import parsing with resolveBindingPath utility for cleaner code. This change only affects namespace imports (import * as crypto) while maintaining all existing functionality for other import patterns. Changes: - Import resolveBindingPath from @nodejs/codemod-utils - Simplify namespace import handling in getCryptoBindings() - Fix TypeScript types for SgRoot<JS> and SgNode<JS> compatibility - Maintain backward compatibility and all test coverage
this case should be handled const algo = 'sha256';
crypto.generateKeyPairSync('rsa-pss', {
modulusLength: 2048,
mgf1Hash: algo
}); |
Fix transformation logic to properly handle both string literals and variable references in hash/mgf1Hash properties. Previously only property names were replaced, now the entire property is transformed while preserving the value. Changes: - Replace entire property pair instead of just the key name - Support both string literals and identifier variables as values - Add test cases for variable value scenarios (variable-value.js) - Ensure backward compatibility with existing string literal cases Fixes case where mgf1Hash: algo was not being transformed to mgf1HashAlgorithm: algo
@AugustinMauroy @brunocroh thanks for you feedback, I did the changes witch you ask for, |
… utility Replace manual import pattern parsing (~107 lines) with resolveBindingPath calls (~22 lines). This approach handles all import patterns (namespace, named, aliased, require) uniformly and improves maintainability as new patterns are automatically supported by the utility.
…suite - Add template_string support in workflow.ts for template literals - Add test cases for template literals, spread operators, nested objects - Consolidate and optimize test suite - Remove redundant tests and improve coverage
subdivision of the main code into another auxiliary function to facilitate its reading
- Merge import-aliases.js functionality into destructured.js - Add namespace imports, function aliases, and variable assignments - Maintain comprehensive coverage of all import patterns - Consolidate ES6 imports, CommonJS requires, and alias patterns
- Remove duplicate test case consolidated into destructured.js - Eliminate redundancy while maintaining test coverage - Optimize test suite from 12 to 11 unique cases
- ast-node-types.js: Test complex AST value types (member_expression, call_expression, etc.) - dynamic-options.js: Test unsupported dynamic options pattern - variable-type.js: Test unsupported variable key type pattern
- Remove "@types/node": "^24.0.3" from package.json - Fix an example in the readme
- Add resolveVariableValue() function to detect variables containing 'rsa-pss' - Update type detection logic to handle both string literals and variables - Transform variable-type.js test case (now supported) - Translate Spanish comments to English in ast-node-types.js
- Add getPromisifiedBindings() function to detect util.promisify() patterns - Extend getCryptoBindings() to include promisified crypto function wrappers - Add promisified-wrappers.js test case covering 6 different scenarios - Update workflow documentation to reflect new capabilities - Support patterns like: const genAsync = util.promisify(crypto.generateKeyPair)
- Use resolveBindingPath for dynamic promisify binding detection - Support destructured imports: const {promisify} = require('util') - Add test cases for destructured/aliased promisify patterns - Fix variable naming conflict and improve fallback logic - Fix TypeScript error: conditional_expression → ternary_expression
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work, thanks! 🚀
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for me it's an LGTM
Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…d edge cases - Remove safeGet* wrapper functions - Consolidate destructured.js test (merge aliases/mixed imports) - Delete redundant tests: ast-node-types, variable-type - Add 5 new edge case tests: complex-ast-patterns, computed-properties, method-chaining, ternary-operators, variable-key-type - Update basic.js transformations
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 🚀🎉
Use proper type assertions for SgRoot<javascriptTypes> and SgRoot<TypesMap> compatibility in utility functions getModuleStatements and resolveBindings.
- Remove 'as any' casts in crypto-rsa-pss-update workflow - Update correct-ts-specifiers test snapshot to match current behavior
…tibility - Restore package-lock.json from main
@brunocroh @AugustinMauroy, how are you? Are there other things we should change? How should I continue with this work? |
We need one more member to review/approve before proceeding with the merge. |
Good, could I take another issue while I wait, or is it better if I just wait? |
yeah if you want you can open an second pr |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 🙌
PS Sorry for the delay. This got lost in my inbox 😓
Summary
Add codemod to transform deprecated RSA-PSS crypto options:
hash
→hashAlgorithm
mgf1Hash
→mgf1HashAlgorithm
Changes
crypto.generateKeyPair()
andcrypto.generateKeyPairSync()
calls with'rsa-pss'
key typecrypto.generateKeyPair
) and destructured imports (generateKeyPair
)Test plan
Resolves #144