1+ const { expect } = require ( 'chai' ) ;
2+ const { analyzeCodeForCrypto, exec } = require ( '../src/proxy/processors/push-action/checkCryptoImplementation.js' ) ;
3+
4+ describe ( 'Crypto Implementation Check Plugin' , ( ) => {
5+ describe ( 'analyzeCodeForCrypto' , ( ) => {
6+ it ( 'should detect non-standard encryption algorithms' , ( ) => {
7+ const testCode = `
8+ function customEncrypt(data) {
9+ return data.split('').map(char =>
10+ String.fromCharCode(char.charCodeAt(0) ^ 0x7F)
11+ ).join('');
12+ }
13+ ` ;
14+
15+ const issues = analyzeCodeForCrypto ( testCode ) ;
16+ expect ( issues ) . to . have . lengthOf . at . least ( 1 ) ;
17+ expect ( issues . some ( i => i . type === 'non_standard_algorithm' ) ) . to . be . true ;
18+ } ) ;
19+
20+ it ( 'should detect suspicious bit operations' , ( ) => {
21+ const testCode = `
22+ function scrambleData(data) {
23+ let result = '';
24+ for(let i = 0; i < data.length; i++) {
25+ result += String.fromCharCode(data.charCodeAt(i) >>> 2);
26+ }
27+ return result;
28+ }
29+ ` ;
30+
31+ const issues = analyzeCodeForCrypto ( testCode ) ;
32+ expect ( issues ) . to . have . lengthOf . at . least ( 1 ) ;
33+ expect ( issues . some ( i => i . type === 'suspicious_operation' ) ) . to . be . true ;
34+ } ) ;
35+
36+ it ( 'should detect suspicious variable names' , ( ) => {
37+ const testCode = `
38+ const cipher = {};
39+ let salt = generateRandomBytes(16);
40+ const iv = new Uint8Array(12);
41+ ` ;
42+
43+ const issues = analyzeCodeForCrypto ( testCode ) ;
44+ expect ( issues ) . to . have . lengthOf . at . least ( 3 ) ;
45+ expect ( issues . some ( i => i . type === 'suspicious_variable' ) ) . to . be . true ;
46+ } ) ;
47+
48+ it ( 'should not flag standard crypto library usage' , ( ) => {
49+ const testCode = `
50+ const crypto = require('crypto');
51+ const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
52+ ` ;
53+
54+ const issues = analyzeCodeForCrypto ( testCode ) ;
55+ expect ( issues . filter ( i => i . severity === 'high' ) ) . to . have . lengthOf ( 0 ) ;
56+ } ) ;
57+
58+ it ( 'should handle empty input' , ( ) => {
59+ const issues = analyzeCodeForCrypto ( '' ) ;
60+ expect ( issues ) . to . be . an ( 'array' ) . that . is . empty ;
61+ } ) ;
62+
63+ it ( 'should handle null or undefined input' , ( ) => {
64+ expect ( analyzeCodeForCrypto ( null ) ) . to . be . an ( 'array' ) . that . is . empty ;
65+ expect ( analyzeCodeForCrypto ( undefined ) ) . to . be . an ( 'array' ) . that . is . empty ;
66+ } ) ;
67+
68+ } ) ;
69+
70+ describe ( 'exec' , ( ) => {
71+
72+ it ( 'should handle empty diff content' , async ( ) => {
73+ const req = { } ;
74+ const action = {
75+ commitData : [ {
76+ hash : '123abc' ,
77+ diff : ''
78+ } ] ,
79+ addStep : function ( step ) { this . step = step ; }
80+ } ;
81+
82+ const result = await exec ( req , action ) ;
83+ expect ( result . step . error ) . to . be . false ;
84+ } ) ;
85+
86+ it ( 'should handle undefined diff content' , async ( ) => {
87+ const req = { } ;
88+ const action = {
89+ commitData : [ {
90+ hash : '123abc'
91+ // diff is undefined
92+ } ] ,
93+ addStep : function ( step ) { this . step = step ; }
94+ } ;
95+
96+ const result = await exec ( req , action ) ;
97+ expect ( result . step . error ) . to . be . false ;
98+ } ) ;
99+
100+ it ( 'should handle empty commitData array' , async ( ) => {
101+ const req = { } ;
102+ const action = {
103+ commitData : [ ] ,
104+ addStep : function ( step ) { this . step = step ; }
105+ } ;
106+
107+ const result = await exec ( req , action ) ;
108+ expect ( result . step . error ) . to . be . false ;
109+ } ) ;
110+ it ( 'should block commits with non-standard crypto implementations' , async ( ) => {
111+ const req = { } ;
112+ const action = {
113+ commitData : [ {
114+ hash : '123abc' ,
115+ diff : `
116+ function customEncrypt(data) {
117+ return data.split('').map(char =>
118+ String.fromCharCode(char.charCodeAt(0) ^ 0x7F)
119+ ).join('');
120+ }
121+ `
122+ } ] ,
123+ addStep : function ( step ) { this . step = step ; }
124+ } ;
125+
126+ const result = await exec ( req , action ) ;
127+ expect ( result . step . error ) . to . be . true ;
128+ } ) ;
129+
130+ it ( 'should allow commits without crypto issues' , async ( ) => {
131+ const req = { } ;
132+ const action = {
133+ commitData : [ {
134+ hash : '123abc' ,
135+ diff : `
136+ function normalFunction() {
137+ return 'Hello World';
138+ }
139+ `
140+ } ] ,
141+ addStep : function ( step ) { this . step = step ; }
142+ } ;
143+
144+ const result = await exec ( req , action ) ;
145+ expect ( result . step . error ) . to . be . false ;
146+ } ) ;
147+
148+ it ( 'should handle multiple commits' , async ( ) => {
149+ const req = { } ;
150+ const action = {
151+ commitData : [
152+ {
153+ hash : '123abc' ,
154+ diff : `function safe() { return true; }`
155+ } ,
156+ {
157+ hash : '456def' ,
158+ diff : `
159+ function rot13(str) {
160+ return str.replace(/[a-zA-Z]/g, c =>
161+ String.fromCharCode((c <= 'Z' ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26)
162+ );
163+ }
164+ `
165+ }
166+ ] ,
167+ addStep : function ( step ) { this . step = step ; }
168+ } ;
169+
170+ const result = await exec ( req , action ) ;
171+ expect ( result . step ) . to . have . property ( 'error' , true ) ;
172+ } ) ;
173+
174+
175+ it ( 'should handle errors gracefully' , async ( ) => {
176+ const req = { } ;
177+ const action = {
178+ commitData : null ,
179+ addStep : function ( step ) { this . step = step ; }
180+ } ;
181+
182+ const result = await exec ( req , action ) ;
183+ expect ( result . step . error ) . to . be . true ;
184+ } ) ;
185+ } ) ;
186+
187+ describe ( 'Pattern Detection' , ( ) => {
188+ it ( 'should detect various forms of XOR encryption' , ( ) => {
189+ const testCases = [
190+ `function encrypt(a, b) { return a ^= b; }` ,
191+ `const result = data ^ key;` ,
192+ `function xor(plaintext, key) { return plaintext ^ key; }` ,
193+ `return char ^ 0xFF;`
194+ ] ;
195+
196+ testCases . forEach ( testCode => {
197+ const issues = analyzeCodeForCrypto ( testCode ) ;
198+ const hasXORIssue = issues . some ( issue =>
199+ issue . type === 'suspicious_operation' ||
200+ issue . message . toLowerCase ( ) . includes ( 'xor' )
201+ ) ;
202+ expect ( hasXORIssue , `Failed to detect XOR in: ${ testCode } ` ) . to . be . true ;
203+ } ) ;
204+ } ) ;
205+
206+ it ( 'should detect custom hash implementations' , ( ) => {
207+ const testCode = `
208+ function customHash(input) {
209+ let hash = 0;
210+ for(let i = 0; i < input.length; i++) {
211+ hash = ((hash << 5) - hash) + input.charCodeAt(i);
212+ hash = hash & hash;
213+ }
214+ return hash;
215+ }
216+ ` ;
217+
218+ const issues = analyzeCodeForCrypto ( testCode ) ;
219+ expect ( issues ) . to . have . lengthOf . at . least ( 1 ) ;
220+ expect ( issues . some ( i => i . severity === 'high' ) ) . to . be . true ;
221+ } ) ;
222+ } ) ;
223+ } ) ;
0 commit comments