generated from 8iq/nodejs-hackathon-boilerplate-starter-kit
-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
hotfix(condo): new semgrep rules (#5532)
* hotfix(condo): extract share data utils * test(condo): old links should work * test(condo): add backward compatibility * fix(callsenter): fix semgrep new rules * fix(condo): use old encryption because it's better to be backward compatible * refactor(condorb): fix semgrep rules * refactor(telegram-employee-bot): fix semgrep * test(condorb): fix encryption in test --------- Co-authored-by: YEgorLu <[email protected]>
- Loading branch information
Showing
10 changed files
with
134 additions
and
22 deletions.
There are no files selected for viewing
Submodule callcenter
updated
from 8d7b88 to a0f921
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import { getRandomString } from '@open-condo/keystone/test.utils' | ||
|
||
import { packShareData, unpackShareData } from './shareDataPacker' | ||
|
||
const DATA = '{"date":"2021-06-17T13:26:52.479Z","number":2135,"details":"fragment fragment fragment fragment fragment fragment","id":"3c05ed8c-56b1-41bf-9c9a-8dfeaa07feb1"}' | ||
const V1_ENCRYPTED_DATA = 'gkQ+t4yV53ToCmiGjPcjzzVICyDa76Hy474vWtbUk6P4Am66KU9zqLowFX9C/4kjstxxHbzBTRMqDqrGIjsAasdE9NR2gNLy4hPGATna6pFstDgdY45lPn+XRsuGaL55YHMKTH5gjVrQMbc34+Ro7xEGTiD25d0QngGNe8R4xKZ0JJO9df943k3botuxgyena+bjGZNEvy3vNmA3FPINNA==' | ||
const V2_ENCRYPTED_DATA = '2:pi36FZ28yjeFnSg7hDPgcXIRHjG0jCLETcpR2AUTJtadr21cR/i7YzaiLMf29tjAWcen3ANiQwAfWEcOjRbft9PuEQki2zmnLdDjuMBtO9++4O7S+wy6hfwunBYCMRYk6CyZAWLcdQRNdE8zw6oLxnzVQw==' | ||
|
||
describe('Crypto packShareData and unpackShareData', () => { | ||
it('should correctly pack and unpack data', () => { | ||
const testData = getRandomString() | ||
const packedData = packShareData(testData) | ||
const unpackedData = unpackShareData(packedData) | ||
|
||
expect(unpackedData).toBe(testData) | ||
}) | ||
|
||
it('should produce different encrypted values for different inputs', () => { | ||
const testData1 = 'Hello, world!' | ||
const testData2 = 'Goodbye, world!' | ||
const packedData1 = packShareData(testData1) | ||
const packedData2 = packShareData(testData2) | ||
|
||
expect(packedData1).not.toBe(packedData2) | ||
}) | ||
|
||
it('should throw an error when decrypting invalid data', () => { | ||
const invalidData = 'InvalidEncryptedString' | ||
expect(() => unpackShareData(invalidData)).toThrow() | ||
}) | ||
|
||
it('should produce encrypted text that is different from original text', () => { | ||
const testData = 'Sensitive information' | ||
const packedData = packShareData(testData) | ||
|
||
expect(packedData).not.toBe(testData) | ||
}) | ||
|
||
it('should decrypt existing links', () => { | ||
expect(unpackShareData(V1_ENCRYPTED_DATA)).toEqual(DATA) | ||
}) | ||
|
||
it('should decrypt existing links v2', () => { | ||
expect(unpackShareData(V2_ENCRYPTED_DATA)).toEqual(DATA) | ||
}) | ||
|
||
it('modern method should be more efficient', () => { | ||
const v2 = packShareData(DATA, true) | ||
|
||
expect(v2.length).toBeLessThan(V1_ENCRYPTED_DATA.length) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import crypto from 'crypto' | ||
import zlib from 'zlib' | ||
|
||
const ALGORITHM = 'aes256' | ||
const MODERN_ALGORITHM = 'aes-256-ctr' | ||
|
||
// NOTE: It's a hard-coded credentials by @leonid-d from 2021. | ||
// Good news: This data doesn't contain any secrets ... | ||
// and it's hard to change this key because we have many existing links ... | ||
// nosemgrep: generic.secrets.gitleaks.generic-api-key.generic-api-key | ||
const KEY = '900150983cd24fb0d6963f7d28e17f72' | ||
|
||
const CRYPTOENCODING = 'base64' | ||
const IV_LENGTH = 16 // 16 bytes for AES-CTR | ||
const MODERN_MARKER = '2:' | ||
|
||
export function unpackShareData (data: string): string { | ||
if (data.startsWith(MODERN_MARKER)) { | ||
// New version with marker '2:' using AES-CTR | ||
const trimmedData = data.slice(MODERN_MARKER.length) | ||
const encryptedText = Buffer.from(trimmedData, CRYPTOENCODING) | ||
|
||
// Using KEY directly as IV | ||
const iv = Buffer.from(KEY).subarray(0, IV_LENGTH) | ||
const decipher = crypto.createDecipheriv(MODERN_ALGORITHM, Buffer.from(KEY), iv) | ||
|
||
const decryptedBuffers = [decipher.update(encryptedText), decipher.final()] | ||
// NOTE: it's more efficient but its require modern node version! please use it in a future | ||
// const decompressedText = zlib.brotliDecompressSync(Buffer.concat(decryptedBuffers)).toString('utf8') | ||
const decompressedText = zlib.inflateSync(Buffer.concat(decryptedBuffers)).toString('utf8') | ||
return decompressedText | ||
} else { | ||
// Legacy format (backward compatibility) | ||
// nosemgrep: javascript.node-crypto.security.create-de-cipher-no-iv.create-de-cipher-no-iv | ||
const decipher = crypto.createDecipher(ALGORITHM, KEY) | ||
const decryptedBuffers = [decipher.update(data, CRYPTOENCODING), decipher.final()] | ||
const decryptedText = Buffer.concat(decryptedBuffers).toString('utf8') | ||
return decryptedText | ||
} | ||
} | ||
|
||
// NOTE: we still use old version and will use it until Node.js v23.3.0: https://nodejs.org/api/deprecations.html#DEP0106 | ||
// Probably we want also to use more efficient compression to reduce link size. At the moment I leave old encryption version | ||
export function packShareData (data: string, useModern = false): string { | ||
if (useModern) { | ||
// New version using AES-CTR and Deflate compression | ||
// Using KEY directly as IV | ||
const iv = Buffer.from(KEY).subarray(0, IV_LENGTH) | ||
const cipher = crypto.createCipheriv(MODERN_ALGORITHM, Buffer.from(KEY), iv) | ||
|
||
// NOTE: it's more efficient but its require modern node version! please use it in a future when we will use useModern = true by default! | ||
// const compressedData = zlib.brotliCompressSync(Buffer.from(data), { params: { [zlib.constants.BROTLI_PARAM_QUALITY]: 11 } }) // Use maximum Brotli compression level | ||
const compressedData = zlib.deflateSync(Buffer.from(data)) | ||
const encryptedBuffers = [cipher.update(compressedData), cipher.final()] | ||
|
||
const resultBuffer = Buffer.concat(encryptedBuffers) | ||
return MODERN_MARKER + resultBuffer.toString(CRYPTOENCODING) | ||
} else { | ||
// Legacy format (backward compatibility) | ||
// nosemgrep: javascript.node-crypto.security.create-de-cipher-no-iv.create-de-cipher-no-iv | ||
const cipher = crypto.createCipher(ALGORITHM, KEY) | ||
const encryptedBuffers = [cipher.update(data, 'utf8'), cipher.final()] | ||
const encryptedText = Buffer.concat(encryptedBuffers).toString(CRYPTOENCODING) | ||
return encryptedText | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Submodule condorb
updated
from 2cbbf1 to f4adac
Submodule telegram-employee-bot
updated
from 6bcb6f to e4471e
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters