@@ -274,6 +274,34 @@ private module NodeJSCrypto {
274274 * A model of the crypto-js library.
275275 */
276276private module CryptoJS {
277+ private class InstantiatedAlgorithm extends DataFlow:: CallNode {
278+ CryptographicAlgorithm algorithm ; // non-functional
279+
280+ InstantiatedAlgorithm ( ) {
281+ /*
282+ * ```
283+ * const crypto = require("crypto-js");
284+ * const cipher = crypto.algo.SHA256.create();
285+ * ```
286+ * matched as:
287+ * ```
288+ * const crypto = require("crypto-js");
289+ * const cipher = crypto.algo.<algorithmName>.create();
290+ * ```
291+ */
292+
293+ exists ( DataFlow:: SourceNode mod , DataFlow:: PropRead propRead |
294+ mod = DataFlow:: moduleImport ( "crypto-js" ) and
295+ propRead = mod .getAPropertyRead ( "algo" ) .getAPropertyRead ( ) and
296+ this = propRead .getAMemberCall ( "create" ) and
297+ not isStrongPasswordHashingAlgorithm ( propRead .getPropertyName ( ) )
298+ )
299+ }
300+
301+ CryptographicAlgorithm getAlgorithm ( ) { result = algorithm }
302+ }
303+
304+
277305 /**
278306 * Matches `CryptoJS.<algorithmName>` and `require("crypto-js/<algorithmName>")`
279307 */
@@ -325,13 +353,39 @@ private module CryptoJS {
325353 input = result .getParameter ( 0 )
326354 }
327355
356+ private DataFlow:: CallNode getUpdatedApplication ( DataFlow:: Node input , InstantiatedAlgorithm instantiation ) {
357+ /*
358+ * ```
359+ * var CryptoJS = require("crypto-js");
360+ * var hash = CryptoJS.algo.SHA256.create();
361+ * hash.update('message');
362+ * hash.update('password');
363+ * var hashInHex = hash.finalize();
364+ * ```
365+ * Matched as:
366+ * ```
367+ * var CryptoJS = require("crypto-js");
368+ * var hash = CryptoJS.algo.<algorithmName>.create();
369+ * hash.update(<input>);
370+ * hash.update(<input>);
371+ * var hashInHex = hash.finalize();
372+ * ```
373+ * Also matches where `CryptoJS.algo.<algorithmName>` has been
374+ * replaced by `require("crypto-js/<algorithmName>")`
375+ */
376+
377+ result = instantiation .getAMemberCall ( "update" ) and
378+ input = result .getArgument ( 0 )
379+ }
380+
328381 private class Apply extends CryptographicOperation:: Range instanceof API:: CallNode {
329382 API:: Node input ;
330383 CryptographicAlgorithm algorithm ; // non-functional
331384
332385 Apply ( ) {
333386 this = getEncryptionApplication ( input , algorithm ) or
334- this = getDirectApplication ( input , algorithm )
387+ this = getDirectApplication ( input , algorithm ) or
388+ this = getUpdatedApplication ( input , instantiation )
335389 }
336390
337391 override DataFlow:: Node getAnInput ( ) { result = input .asSink ( ) }
0 commit comments