Skip to content

Commit

Permalink
Fix CG for typed-rest-client (#370)
Browse files Browse the repository at this point in the history
* Fix CG

- Rewrited react samples on vite because of react'scripts contains cve and not maintained

* Fix CG

- Npm audit fix for webpack samples

* Fix CG

- Fixed CVE in typed-rest client
- Migrated package to use node14+ as mocha is not supported in versions below.
- Migrated CI to use Node14+ for tests
_ Bumped ts to v5
- Bumped typed-rest-client to new major version 2
- Added .vscode folder in .gitignore

* Fix CG

- Fixed tests for the new version of the typescript

* Fix CG

- Replaced crypto package(DES-ECB and MD4 algorythms calls) to a packages as they are become legacy in openssl3 which is used new node

* Fix CG

- Regenerated package.lock files in samples.

* Fix CG

- Fixed types in tests
- Fixed webpack samples

* Fix CG

- Bumped supported version

* Fix CG

- Updated README with new information

* Fix CG

- Updated README with new information
  • Loading branch information
DmitriiBobreshev authored Jun 4, 2024
1 parent 4c0c060 commit 593335a
Show file tree
Hide file tree
Showing 38 changed files with 6,190 additions and 29,632 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
typings
node_modules
_build
.vscode
lib/*.js
samples/*.js
samples/*.txt
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ set NODE_DEBUG=http

## Node support

The typed-rest-client is built using the latest LTS version of Node 8. We also support the latest LTS for Node 6 and newer.
v2 - [current, maintained] - Supports node 16 and above
v1 - End Of Life, for Node < 16, contains security vulnerabilities, use at your own risk

## Contributing

Expand Down
6 changes: 3 additions & 3 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ variables:
parameters:
- name: nodeVersionList
type: object
default: [6, 8, 10, 12, 14, 16]
default: [16, 18, 20]
- name: imageList
type: object
default:
Expand Down Expand Up @@ -58,8 +58,8 @@ extends:
steps:
- task: NodeTool@0
inputs:
versionSpec: '8.x'
displayName: Install node 8
versionSpec: '20.x'
displayName: Install node 20.x
- script: npm install
displayName: npm install
- script: npm run build
Expand Down
11 changes: 7 additions & 4 deletions lib/Util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ function buildParamsStringifyOptions(queryParams: IRequestQueryParams): any {
* @param {string} charset? - optional; defaults to 'utf-8'
* @return {Promise<string>}
*/
export async function decompressGzippedContent(buffer: Buffer, charset?: string): Promise<string> {
export async function decompressGzippedContent(buffer: Buffer, charset?: BufferEncoding): Promise<string> {
return new Promise<string>(async (resolve, reject) => {
zlib.gunzip(buffer, function (error, buffer) {
if (error) {
Expand Down Expand Up @@ -128,16 +128,19 @@ export function buildProxyBypassRegexFromEnv(bypass : string) : RegExp {
* @param {IHttpClientResponse} response
* @return {string} - Content Encoding Charset; Default=utf-8
*/
export function obtainContentCharset (response: IHttpClientResponse) : string {
export function obtainContentCharset (response: IHttpClientResponse) : BufferEncoding {
// Find the charset, if specified.
// Search for the `charset=CHARSET` string, not including `;,\r\n`
// Example: content-type: 'application/json;charset=utf-8'
// |__ matches would be ['charset=utf-8', 'utf-8', index: 18, input: 'application/json; charset=utf-8']
// |_____ matches[1] would have the charset :tada: , in our example it's utf-8
// However, if the matches Array was empty or no charset found, 'utf-8' would be returned by default.
const nodeSupportedEncodings = ['ascii', 'utf8', 'utf16le', 'ucs2', 'base64', 'binary', 'hex'];
const nodeSupportedEncodings: BufferEncoding[] = ['ascii', 'utf8', 'utf16le', 'ucs2', 'base64', 'binary', 'hex'];
const contentType: string = response.message.headers['content-type'] || '';
const matches: (RegExpMatchArray|null) = contentType.match(/charset=([^;,\r\n]+)/i);
if (matches && matches[1] && nodeSupportedEncodings.indexOf(matches[1] as BufferEncoding) != -1) {
return matches[1] as BufferEncoding;
}

return (matches && matches[1] && nodeSupportedEncodings.indexOf(matches[1]) != -1) ? matches[1] : 'utf-8';
return 'utf-8';
}
1 change: 1 addition & 0 deletions lib/handlers/ntlm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export class NtlmCredentialHandler implements ifm.IRequestHandler {
const callbackForResult = function (err: any, res: ifm.IHttpClientResponse) {
if (err) {
reject(err);
return;
}
// We have to readbody on the response before continuing otherwise there is a hang.
res.readBody().then(() => {
Expand Down
4 changes: 2 additions & 2 deletions lib/opensource/Node-SMB/lib/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ function oddpar(buf)
*/
function expandkey(key56)
{
var key64 = new Buffer(8);
var key64 = Buffer.alloc(8);

key64[0] = key56[0] & 0xFE;
key64[1] = ((key56[0] << 7) & 0xFF) | (key56[1] >> 1);
Expand All @@ -49,7 +49,7 @@ function expandkey(key56)
*/
function bintohex(bin)
{
var buf = (Buffer.isBuffer(buf) ? buf : new Buffer(bin, 'binary'));
var buf = (Buffer.isBuffer(buf) ? buf : Buffer.from(bin, 'binary'));
var str = buf.toString('hex').toUpperCase();
return zeroextend(str, 32);
}
Expand Down
24 changes: 15 additions & 9 deletions lib/opensource/Node-SMB/lib/ntlm.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ var $ = require('./common');
var lmhashbuf = require('./smbhash').lmhashbuf;
var nthashbuf = require('./smbhash').nthashbuf;

var desjs = require("des.js");

function encodeType1(hostname, ntdomain) {
hostname = hostname.toUpperCase();
Expand All @@ -12,7 +13,7 @@ function encodeType1(hostname, ntdomain) {
var ntdomainlen = Buffer.byteLength(ntdomain, 'ascii');

var pos = 0;
var buf = new Buffer(32 + hostnamelen + ntdomainlen);
var buf = Buffer.alloc(32 + hostnamelen + ntdomainlen);

buf.write('NTLMSSP', pos, 7, 'ascii'); // byte protocol[8];
pos += 7;
Expand Down Expand Up @@ -86,10 +87,10 @@ function encodeType3(username, hostname, ntdomain, nonce, password) {
hostname = hostname.toUpperCase();
ntdomain = ntdomain.toUpperCase();

var lmh = new Buffer(21);
var lmh = Buffer.alloc(21);
lmhashbuf(password).copy(lmh);
lmh.fill(0x00, 16); // null pad to 21 bytes
var nth = new Buffer(21);
var nth = Buffer.alloc(21);
nthashbuf(password).copy(nth);
nth.fill(0x00, 16); // null pad to 21 bytes

Expand All @@ -110,7 +111,7 @@ function encodeType3(username, hostname, ntdomain, nonce, password) {

var pos = 0;
var msg_len = 64 + ntdomainlen + usernamelen + hostnamelen + lmrlen + ntrlen;
var buf = new Buffer(msg_len);
var buf = Buffer.alloc(msg_len);

buf.write('NTLMSSP', pos, 7, 'ascii'); // byte protocol[8];
pos += 7;
Expand Down Expand Up @@ -189,12 +190,17 @@ function encodeType3(username, hostname, ntdomain, nonce, password) {

function makeResponse(hash, nonce)
{
var out = new Buffer(24);
var out = Buffer.alloc(24);

for (var i = 0; i < 3; i++) {
var keybuf = $.oddpar($.expandkey(hash.slice(i * 7, i * 7 + 7)));
var des = crypto.createCipheriv('DES-ECB', keybuf, '');
var str = des.update(nonce.toString('binary'), 'binary', 'binary');
out.write(str, i * 8, i * 8 + 8, 'binary');

var des = desjs.DES.create({type: 'encrypt', key: keybuf});
var magicKey = Buffer.from(nonce.toString('binary'));
var insertBuff = Buffer.from(des.update(magicKey));

out.fill(insertBuff, i * 8, i * 8 + 8, 'binary');

}
return out;
}
Expand All @@ -210,7 +216,7 @@ exports.challengeHeader = function (hostname, domain) {
};

exports.responseHeader = function (res, url, domain, username, password) {
var serverNonce = new Buffer((res.headers['www-authenticate'].match(/^NTLM\s+(.+?)(,|\s+|$)/) || [])[1], 'base64');
var serverNonce = Buffer.from((res.headers['www-authenticate'].match(/^NTLM\s+(.+?)(,|\s+|$)/) || [])[1], 'base64');
var hostname = require('url').parse(url).hostname;
return 'NTLM ' + exports.encodeType3(username, hostname, domain, exports.decodeType2(serverNonce), password).toString('base64')
};
Expand Down
21 changes: 12 additions & 9 deletions lib/opensource/Node-SMB/lib/smbhash.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
var crypto = require('crypto');
var $ = require('./common');

var jsmd4 = require("js-md4");
var desjs = require("des.js");

/*
* Generate the LM Hash
*/
Expand All @@ -11,7 +13,7 @@ function lmhashbuf(inputstr)
var xl = Buffer.byteLength(x, 'ascii');

/* null pad to 14 bytes */
var y = new Buffer(14);
var y = Buffer.alloc(14);
y.write(x, 0, xl, 'ascii');
y.fill(0, xl);

Expand All @@ -24,12 +26,13 @@ function lmhashbuf(inputstr)
/* DES encrypt magic number "KGS!@#$%" to two
* 8-byte ciphertexts, (ECB, no padding)
*/
var buf = new Buffer(16);
var buf = Buffer.alloc(16);
var pos = 0;
var cts = halves.forEach(function(z) {
var des = crypto.createCipheriv('DES-ECB', z, '');
var str = des.update('KGS!@#$%', 'binary', 'binary');
buf.write(str, pos, pos + 8, 'binary');
var des = desjs.DES.create({type: 'encrypt', key: z});
var magicKey = Buffer.from('KGS!@#$%', 'ascii');
var insertBuff = Buffer.from(des.update(magicKey));
buf.fill(insertBuff, pos, pos + 8, 'binary');
pos += 8;
});

Expand All @@ -41,10 +44,10 @@ function lmhashbuf(inputstr)
function nthashbuf(str)
{
/* take MD4 hash of UCS-2 encoded password */
var ucs2 = new Buffer(str, 'ucs2');
var md4 = crypto.createHash('md4');
var ucs2 = Buffer.from(str, 'ucs2');
var md4 = jsmd4.create();
md4.update(ucs2);
return new Buffer(md4.digest('binary'), 'binary');
return Buffer.from(md4.digest('binary'), 'binary');
}

function lmhash(is)
Expand Down
Loading

0 comments on commit 593335a

Please sign in to comment.