Fixed server exception on older NodeJS versions, #4102

Ylian Saint-Hilaire committed Jun 9, 2022 at 09:58 UTC cfd8521381222c5b5851b2e4788897119ea74d2a
2 files changed +281 -53
authenticode.js
+279 -51
@@ -404,7 +404,7 @@ function createAuthenticodeHandler(path) {
404 r.size = buf.readUInt32LE(4);
405 //console.log('readResourceData', r.offsetToData - obj.header.sections['.rsrc'].virtualAddr, r.size, r.offsetToData + r.size - obj.header.sections['.rsrc'].virtualAddr);
406 r.codePage = buf.readUInt32LE(8);
407 - r.reserved = buf.readUInt32LE(12);
407 + //r.reserved = buf.readUInt32LE(12);
408 return r;
409 }
410
@@ -449,9 +449,13 @@ function createAuthenticodeHandler(path) {
449 if (resources.entries[i].table) { getResourceSectionSize(resources.entries[i].table, sizes); }
450 else if (resources.entries[i].item) {
451 sizes.items += 16;
452 - var dataSize = resources.entries[i].item.size;
453 - if ((dataSize % 8) != 0) { dataSize += (8 - (dataSize % 8)); }
454 - sizes.data += dataSize;
452 + if (resources.entries[i].item.buffer) {
453 + sizes.data += resources.entries[i].item.buffer.length;
454 + } else {
455 + var dataSize = resources.entries[i].item.size;
456 + if ((dataSize % 8) != 0) { dataSize += (8 - (dataSize % 8)); }
457 + sizes.data += dataSize;
458 + }
459 }
460 }
461 }
@@ -508,20 +512,29 @@ function createAuthenticodeHandler(path) {
512 // This is a pointer to a data entry
513 data = resPointers.items;
514
515 + // Write the data
516 + var entrySize = 0;
517 + if (resources.entries[i].item.buffer) {
518 + // Write the data from given buffer
519 + resources.entries[i].item.buffer.copy(buf, resPointers.data, 0, resources.entries[i].item.buffer.length);
520 + entrySize = resources.entries[i].item.buffer.length;
521 + } else {
522 + // Write the data from original file
523 + const actualPtr = (resources.entries[i].item.offsetToData - obj.header.sections['.rsrc'].virtualAddr) + obj.header.sections['.rsrc'].rawAddr;
524 + const tmp = readFileSlice(actualPtr, resources.entries[i].item.size);
525 + tmp.copy(buf, resPointers.data, 0, tmp.length);
526 + entrySize = resources.entries[i].item.size;;
527 + }
528 +
529 // Write the item entry
530 buf.writeUInt32LE(resPointers.data + obj.header.sections['.rsrc'].virtualAddr, resPointers.items); // Write the pointer relative to the virtual address
513 - buf.writeUInt32LE(resources.entries[i].item.size, resPointers.items + 4);
531 + buf.writeUInt32LE(entrySize, resPointers.items + 4);
532 buf.writeUInt32LE(resources.entries[i].item.codePage, resPointers.items + 8);
533 buf.writeUInt32LE(resources.entries[i].item.reserved, resPointers.items + 12);
534
517 - // Write the data
518 - const actualPtr = (resources.entries[i].item.offsetToData - obj.header.sections['.rsrc'].virtualAddr) + obj.header.sections['.rsrc'].rawAddr;
519 - const tmp = readFileSlice(actualPtr, resources.entries[i].item.size);
520 - tmp.copy(buf, resPointers.data, 0, tmp.length);
521 -
535 // Move items pointers forward
536 resPointers.items += 16;
524 - var dataSize = resources.entries[i].item.size;
537 + var dataSize = entrySize;
538 if ((dataSize % 8) != 0) { dataSize += (8 - (dataSize % 8)); }
539 resPointers.data += dataSize;
540 }
@@ -531,17 +544,19 @@ function createAuthenticodeHandler(path) {
544
545 // Convert a unicode buffer to a string
546 function unicodeToString(buf) {
534 - var r = '';
535 - for (var i = 0; i < (buf.length / 2) ; i++) { r += String.fromCharCode(buf.readUInt16LE(i * 2)); }
547 + var r = '', c;
548 + for (var i = 0; i < (buf.length / 2) ; i++) {
549 + c = buf.readUInt16LE(i * 2);
550 + if (c != 0) { r += String.fromCharCode(c); } else { return r; }
551 + }
552 return r;
553 }
554
539 - // Trim a string at teh first null character
540 - function stringUntilNull(str) {
541 - if (str == null) return null;
542 - const i = str.indexOf('\0');
543 - if (i >= 0) return str.substring(0, i);
544 - return str;
555 + // Convert a string to a unicode buffer
556 + // Input is a string, a buffer to write to and the offset in the buffer (0 is default).
557 + function stringToUnicode(str, buf, offset) {
558 + if (offset == null) { offset = 0; }
559 + for (var i = 0; i < str.length; i++) { buf.writeInt16LE(str.charCodeAt(i), offset + (i * 2)); }
560 }
561
562 var resourceDefaultNames = {
@@ -612,6 +627,7 @@ function createAuthenticodeHandler(path) {
627
628 // Decode the version information from the resource
629 obj.getVersionInfo = function () {
630 + console.log('READ', getVersionInfoData().toString('hex'));
631 var r = {}, info = readVersionInfo(getVersionInfoData(), 0);
632 if ((info == null) || (info.stringFiles == null)) return null;
633 var StringFileInfo = null;
@@ -622,6 +638,42 @@ function createAuthenticodeHandler(path) {
638 return r;
639 }
640
641 + // Encode the version information to the resource
642 + obj.setVersionInfo = function (versions) {
643 + // Convert the version information into a string array
644 + const stringArray = [];
645 + for (var i in versions) { stringArray.push({ key: i, value: versions[i] }); }
646 +
647 + // Get the existing version data and switch the strings to the new strings
648 + var r = {}, info = readVersionInfo(getVersionInfoData(), 0);
649 + if ((info == null) || (info.stringFiles == null)) return;
650 + var StringFileInfo = null;
651 + for (var i in info.stringFiles) { if (info.stringFiles[i].szKey == 'StringFileInfo') { StringFileInfo = info.stringFiles[i]; } }
652 + if ((StringFileInfo == null) || (StringFileInfo.stringTable == null) || (StringFileInfo.stringTable.strings == null)) return;
653 + StringFileInfo.stringTable.strings = stringArray;
654 +
655 + // Re-encode the version information into a buffer
656 + var verInfoResBufArray = [];
657 + writeVersionInfo(verInfoResBufArray, info);
658 + var verInfoRes = Buffer.concat(verInfoResBufArray);
659 +
660 + // Display all buffers
661 + //console.log('--WRITE BUF ARRAY START--');
662 + //for (var i in verInfoResBufArray) { console.log(verInfoResBufArray[i].toString('hex')); }
663 + //console.log('--WRITE BUF ARRAY END--');
664 +
665 + // Set the new buffer as part of the resources
666 + for (var i = 0; i < obj.resources.entries.length; i++) {
667 + if (obj.resources.entries[i].name == resourceDefaultNames.versionInfo) {
668 + const verInfo = obj.resources.entries[i].table.entries[0].table.entries[0].item;
669 + delete verInfo.size;
670 + delete verInfo.offsetToData;
671 + verInfo.buffer = verInfoRes;
672 + obj.resources.entries[i].table.entries[0].table.entries[0].item = verInfo;
673 + }
674 + }
675 + }
676 +
677 // Return the version info data block
678 function getVersionInfoData() {
679 if (obj.resources == null) return null;
@@ -629,26 +681,175 @@ function createAuthenticodeHandler(path) {
681 for (var i = 0; i < obj.resources.entries.length; i++) {
682 if (obj.resources.entries[i].name == resourceDefaultNames.versionInfo) {
683 const verInfo = obj.resources.entries[i].table.entries[0].table.entries[0].item;
632 - const actualPtr = (verInfo.offsetToData - obj.header.sections['.rsrc'].virtualAddr) + ptr;
633 - return readFileSlice(actualPtr, verInfo.size);
684 + if (verInfo.buffer != null) {
685 + return verInfo.buffer;
686 + } else {
687 + const actualPtr = (verInfo.offsetToData - obj.header.sections['.rsrc'].virtualAddr) + ptr;
688 + return readFileSlice(actualPtr, verInfo.size);
689 + }
690 }
691 }
692 return null;
693 }
694
695 + // Create a VS_VERSIONINFO structure as a array of buffer that is ready to be placed in the resource section
696 + // VS_VERSIONINFO structure: https://docs.microsoft.com/en-us/windows/win32/menurc/vs-versioninfo
697 + function writeVersionInfo(bufArray, info) {
698 + const buf = Buffer.alloc(40);
699 + buf.writeUInt16LE(0, 4); // wType
700 + stringToUnicode('VS_VERSION_INFO', buf, 6);
701 + bufArray.push(buf);
702 +
703 + var wLength = 40;
704 + var wValueLength = 0;
705 + if (info.fixedFileInfo != null) {
706 + const buf2 = Buffer.alloc(52);
707 + wLength += 52;
708 + wValueLength += 52;
709 + buf2.writeUInt32LE(info.fixedFileInfo.dwSignature, 0); // dwSignature
710 + buf2.writeUInt32LE(info.fixedFileInfo.dwStrucVersion, 4); // dwStrucVersion
711 + buf2.writeUInt32LE(info.fixedFileInfo.dwFileVersionMS, 8); // dwFileVersionMS
712 + buf2.writeUInt32LE(info.fixedFileInfo.dwFileVersionLS, 12); // dwFileVersionLS
713 + buf2.writeUInt32LE(info.fixedFileInfo.dwProductVersionMS, 16); // dwProductVersionMS
714 + buf2.writeUInt32LE(info.fixedFileInfo.dwProductVersionLS, 20); // dwProductVersionLS
715 + buf2.writeUInt32LE(info.fixedFileInfo.dwFileFlagsMask, 24); // dwFileFlagsMask
716 + buf2.writeUInt32LE(info.fixedFileInfo.dwFileFlags, 28); // dwFileFlags
717 + buf2.writeUInt32LE(info.fixedFileInfo.dwFileOS, 32); // dwFileOS
718 + buf2.writeUInt32LE(info.fixedFileInfo.dwFileType, 36); // dwFileType
719 + buf2.writeUInt32LE(info.fixedFileInfo.dwFileSubtype, 40); // dwFileSubtype
720 + buf2.writeUInt32LE(info.fixedFileInfo.dwFileDateMS, 44); // dwFileDateMS
721 + buf2.writeUInt32LE(info.fixedFileInfo.dwFileDateLS, 48); // dwFileDateLS
722 + bufArray.push(buf2);
723 + }
724 +
725 + if (info.stringFiles != null) { wLength += writeStringFileInfo(bufArray, info.stringFiles); }
726 +
727 + console.log('@@@@@@Z', wLength, Buffer.concat(bufArray).length);
728 +
729 + buf.writeUInt16LE(Buffer.concat(bufArray).length, 0); // wLength
730 + buf.writeUInt16LE(wValueLength, 2); // wValueLength
731 + return wLength;
732 + }
733 +
734 + // StringFileInfo structure: https://docs.microsoft.com/en-us/windows/win32/menurc/stringfileinfo
735 + function writeStringFileInfo(bufArray, stringFiles) {
736 + //console.log('writeStringFileInfo', stringFiles);
737 + var totalLen = 0;
738 + for (var i in stringFiles) {
739 + var l = 6 + (stringFiles[i].szKey.length * 2);
740 + const buf2 = Buffer.alloc(padPointer(l));
741 + buf2.writeUInt16LE(1, 4); // wType
742 + stringToUnicode(stringFiles[i].szKey, buf2, 6);
743 + bufArray.push(buf2);
744 +
745 + var wLength = 0, wValueLength = 0;
746 +
747 + if (stringFiles[i].szKey == 'StringFileInfo') { wLength += writeStringTableStruct(bufArray, stringFiles[i].stringTable); }
748 + if (stringFiles[i].szKey == 'VarFileInfo') { wLength += writeVarFileInfoStruct(bufArray, stringFiles[i].varFileInfo); }
749 +
750 + buf2.writeUInt16LE(l + wLength, 0); // wLength
751 + buf2.writeUInt16LE(wValueLength, 2); // wValueLength
752 + totalLen += buf2.length + wLength;
753 + }
754 + return totalLen;
755 + }
756 +
757 + // VarFileInfo structure: https://docs.microsoft.com/en-us/windows/win32/menurc/var-str
758 + function writeVarFileInfoStruct(bufArray, varFileInfo) {
759 + console.log('*************writeVarFileInfoStruct', varFileInfo);
760 + var l = 6 + (varFileInfo.szKey.length * 2);
761 + const buf = Buffer.alloc(padPointer(l));
762 + buf.writeUInt16LE(0, 4); // wType
763 + stringToUnicode(varFileInfo.szKey, buf, 6);
764 + bufArray.push(buf);
765 +
766 + var wLength = 0;
767 + var wValueLength = 0;
768 +
769 + if (varFileInfo.value) {
770 + bufArray.push(varFileInfo.value);
771 + wLength += varFileInfo.value.length;
772 + }
773 + buf.writeUInt16LE(l + wLength, 0); // wLength
774 + buf.writeUInt16LE(wValueLength, 2); // wValueLength
775 +
776 + //console.log('WwriteVarFileInfoStruct', buf.toString('hex'));
777 + return buf.length + wLength;
778 + }
779 +
780 + // StringTable structure: https://docs.microsoft.com/en-us/windows/win32/menurc/stringtable
781 + function writeStringTableStruct(bufArray, stringTable) {
782 + //console.log('writeStringTableStruct', stringTable);
783 + var l = 6 + (stringTable.szKey.length * 2);
784 + const buf = Buffer.alloc(padPointer(l));
785 + buf.writeUInt16LE(1, 4); // wType
786 + stringToUnicode(stringTable.szKey, buf, 6);
787 + bufArray.push(buf);
788 +
789 + var wLength = 0;
790 + var wValueLength = 0;
791 +
792 + if (stringTable.strings) { wLength += writeStringStructs(bufArray, stringTable.strings); }
793 + buf.writeUInt16LE(l + wLength, 0); // wLength
794 + buf.writeUInt16LE(wValueLength, 2); // wValueLength
795 +
796 + //console.log('WStringTableStruct', buf.toString('hex'));
797 + return buf.length + wLength;
798 + }
799 +
800 + // String structure: https://docs.microsoft.com/en-us/windows/win32/menurc/string-str
801 + function writeStringStructs(bufArray, stringTable) {
802 + //console.log('writeStringStructs', stringTable);
803 + var totalLen = 0, bufadd = 0;
804 + for (var i in stringTable) {
805 + //console.log('writeStringStructs', stringTable[i]);
806 + const buf = Buffer.alloc(padPointer(6 + ((stringTable[i].key.length + 1) * 2)));
807 + var buf2, wLength = buf.length;
808 + var wValueLength = 0;
809 + stringToUnicode(stringTable[i].key, buf, 6);
810 + bufArray.push(buf);
811 + bufadd += buf.length;
812 + if (typeof stringTable[i].value == 'string') {
813 + // wType (string)
814 + buf.writeUInt16LE(1, 4);
815 + var l = (stringTable[i].value.length + 1) * 2;
816 + buf2 = Buffer.alloc(padPointer(l));
817 + stringToUnicode(stringTable[i].value, buf2, 0);
818 + bufArray.push(buf2);
819 + bufadd += buf2.length;
820 + wValueLength = stringTable[i].value.length + 1;
821 + wLength += l;
822 + }
823 + if (typeof stringTable[i].value == 'object') {
824 + // wType (binary)
825 + buf.writeUInt16LE(2, 4); // TODO: PADDING
826 + bufArray.push(stringTable[i].value);
827 + bufadd += stringTable[i].value.length;
828 + wValueLength = stringTable[i].value.length;
829 + wLength += wValueLength;
830 + }
831 + buf.writeUInt16LE(wLength, 0); // wLength
832 + buf.writeUInt16LE(wValueLength, 2); // wValueLength
833 + //console.log('WStringStruct', buf.toString('hex'), buf2.toString('hex'));
834 + totalLen += wLength;
835 + }
836 + //return totalLen;
837 + return bufadd;
838 + }
839 +
840 // VS_VERSIONINFO structure: https://docs.microsoft.com/en-us/windows/win32/menurc/vs-versioninfo
841 function readVersionInfo(buf, ptr) {
842 const r = {};
843 if (buf.length < 2) return null;
643 - r.wLength = buf.readUInt16LE(ptr);
644 - if (buf.length < r.wLength) return null;
645 - r.wValueLength = buf.readUInt16LE(ptr + 2);
646 - r.wType = buf.readUInt16LE(ptr + 4);
844 + const wLength = buf.readUInt16LE(ptr);
845 + if (buf.length < wLength) return null;
846 + const wValueLength = buf.readUInt16LE(ptr + 2);
847 + const wType = buf.readUInt16LE(ptr + 4);
848 r.szKey = unicodeToString(buf.slice(ptr + 6, ptr + 36));
849 if (r.szKey != 'VS_VERSION_INFO') return null;
649 - //console.log('getVersionInfo', r.wLength, r.wValueLength, r.wType, r.szKey.toString());
650 - if (r.wValueLength == 52) { r.fixedFileInfo = readFixedFileInfoStruct(buf, ptr + 40); }
651 - r.stringFiles = readStringFilesStruct(buf, ptr + 40 + r.wValueLength, r.wLength - 40 - r.wValueLength);
850 + //console.log('getVersionInfo', wLength, wValueLength, wType, r.szKey.toString());
851 + if (wValueLength == 52) { r.fixedFileInfo = readFixedFileInfoStruct(buf, ptr + 40); }
852 + r.stringFiles = readStringFilesStruct(buf, ptr + 40 + wValueLength, wLength - 40 - wValueLength);
853 return r;
854 }
855
@@ -678,30 +879,43 @@ function createAuthenticodeHandler(path) {
879 var t = [], startPtr = ptr;
880 while (ptr < (startPtr + len)) {
881 const r = {};
681 - r.wLength = buf.readUInt16LE(ptr);
682 - if (r.wLength == 0) return t;
683 - r.wValueLength = buf.readUInt16LE(ptr + 2);
684 - r.wType = buf.readUInt16LE(ptr + 4); // 1 = Text, 2 = Binary
685 - r.szKey = stringUntilNull(unicodeToString(buf.slice(ptr + 6, ptr + 6 + (r.wLength - 6)))); // String value
686 - //console.log('readStringFileStruct', r.wLength, r.wValueLength, r.wType, r.szKey.toString());
687 - if (r.szKey == 'StringFileInfo') { r.stringTable = readStringTableStruct(buf, ptr + 36 + r.wValueLength); }
688 - if (r.szKey == 'VarFileInfo$') { r.varFileInfo = {}; } // TODO
882 + const wLength = buf.readUInt16LE(ptr);
883 + if (wLength == 0) return t;
884 + const wValueLength = buf.readUInt16LE(ptr + 2);
885 + const wType = buf.readUInt16LE(ptr + 4); // 1 = Text, 2 = Binary
886 + r.szKey = unicodeToString(buf.slice(ptr + 6, ptr + 6 + (wLength - 6))); // String value
887 + //console.log('readStringFileStruct', wLength, wValueLength, wType, r.szKey);
888 + if (r.szKey == 'StringFileInfo') { r.stringTable = readStringTableStruct(buf, ptr + 36); }
889 + if (r.szKey == 'VarFileInfo') { r.varFileInfo = readVarFileInfoStruct(buf, ptr + 32); }
890 t.push(r);
690 - ptr += r.wLength;
891 + ptr += wLength;
892 ptr = padPointer(ptr);
893 }
894 return t;
895 }
896
897 + // VarFileInfo structure: https://docs.microsoft.com/en-us/windows/win32/menurc/var-str
898 + function readVarFileInfoStruct(buf, ptr) {
899 + const r = {};
900 + const wLength = buf.readUInt16LE(ptr);
901 + const wValueLength = buf.readUInt16LE(ptr + 2);
902 + const wType = buf.readUInt16LE(ptr + 4); // 1 = Text, 2 = Binary
903 + r.szKey = unicodeToString(buf.slice(ptr + 6, ptr + wLength)); // "VarFileInfo"
904 + r.value = buf.slice(ptr + wLength - wValueLength, ptr + wLength)
905 + //console.log('readVarFileInfoStruct', wLength, wValueLength, wType, r.szKey, r.value.toString('hex'));
906 + return r;
907 + }
908 +
909 // StringTable structure: https://docs.microsoft.com/en-us/windows/win32/menurc/stringtable
910 function readStringTableStruct(buf, ptr) {
911 const r = {};
699 - r.wLength = buf.readUInt16LE(ptr);
700 - r.wValueLength = buf.readUInt16LE(ptr + 2);
701 - r.wType = buf.readUInt16LE(ptr + 4); // 1 = Text, 2 = Binary
912 + const wLength = buf.readUInt16LE(ptr);
913 + const wValueLength = buf.readUInt16LE(ptr + 2);
914 + const wType = buf.readUInt16LE(ptr + 4); // 1 = Text, 2 = Binary
915 + //console.log('RStringTableStruct', buf.slice(ptr, ptr + wLength).toString('hex'));
916 r.szKey = unicodeToString(buf.slice(ptr + 6, ptr + 6 + 16)); // An 8-digit hexadecimal number stored as a Unicode string.
703 - //console.log('readStringTableStruct', r.wLength, r.wValueLength, r.wType, r.szKey);
704 - r.strings = readStringStructs(buf, ptr + 24 + r.wValueLength, r.wLength - 22);
917 + //console.log('readStringTableStruct', wLength, wValueLength, r.wType, r.szKey);
918 + r.strings = readStringStructs(buf, ptr + 24 + wValueLength, wLength - 22);
919 return r;
920 }
921
@@ -710,22 +924,30 @@ function createAuthenticodeHandler(path) {
924 var t = [], startPtr = ptr;
925 while (ptr < (startPtr + len)) {
926 const r = {};
713 - r.wLength = buf.readUInt16LE(ptr);
714 - if (r.wLength == 0) return t;
715 - r.wValueLength = buf.readUInt16LE(ptr + 2);
716 - r.wType = buf.readUInt16LE(ptr + 4); // 1 = Text, 2 = Binary
717 - r.key = unicodeToString(buf.slice(ptr + 6, ptr + (r.wLength - (r.wValueLength * 2)))); // Key
718 - r.value = unicodeToString(buf.slice(ptr + r.wLength - (r.wValueLength * 2), ptr + r.wLength)); // Value
719 - //console.log('readStringStruct', r.wLength, r.wValueLength, r.wType, r.key, r.value);
927 + const wLength = buf.readUInt16LE(ptr);
928 + if (wLength == 0) return t;
929 +
930 + //console.log('RStringStruct', buf.slice(ptr, ptr + wLength).toString('hex'));
931 +
932 + const wValueLength = buf.readUInt16LE(ptr + 2);
933 + const wType = buf.readUInt16LE(ptr + 4); // 1 = Text, 2 = Binary
934 +
935 + //console.log('R', buf.slice(ptr, ptr + wLength).toString('hex'));
936 +
937 + r.key = unicodeToString(buf.slice(ptr + 6, ptr + (wLength - (wValueLength * 2)) - 2)); // Key
938 + if (wType == 1) { r.value = unicodeToString(buf.slice(ptr + wLength - (wValueLength * 2), ptr + wLength - 2)); } // String value
939 + if (wType == 2) { r.value = buf.slice(ptr + wLength - (wValueLength * 2), ptr + wLength); } // Binary value
940 + //console.log('readStringStruct', wLength, wValueLength, wType, r.key, r.value);
941 t.push(r);
721 - ptr += r.wLength;
942 + ptr += wLength;
943 ptr = padPointer(ptr);
944 }
945 return t;
946 }
947
948 // Return the next 4 byte aligned number
728 - function padPointer(ptr) { return ptr + (ptr % 4); }
949 + function padPointer(ptr) { return ptr + (((ptr % 4) == 0) ? 0 : (4 - (ptr % 4))); }
950 + //function padPointer(ptr) { return ptr + (ptr % 4); }
951
952 // Hash the file using the selected hashing system
953 obj.getHash = function(algo) {
@@ -942,6 +1164,12 @@ function createAuthenticodeHandler(path) {
1164
1165 // Save the executable
1166 obj.writeExecutable = function (args) {
1167 + // Get version information from the resource
1168 + var versions = obj.getVersionInfo();
1169 + //versions['FileDescription'] = 'Mesh Agent Service';
1170 + obj.setVersionInfo(versions);
1171 + //var versions2 = obj.getVersionInfo();
1172 +
1173 // Open the file
1174 var output = fs.openSync(args.out, 'w');
1175 var tmp, written = 0;
webserver.js
+2 -2
@@ -7697,8 +7697,8 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
7697 xargs.autocomplete = (domain.autocomplete === false)?'x':'autocomplete'; // This option allows autocomplete to be turned off on the login page.
7698 if (typeof domain.hide == 'number') { xargs.hide = domain.hide; }
7699
7700 - // To mitigate any possible BREACH attack, we generate a random length string here.
7701 - xargs.randomlength = (args.webpagelengthrandomization !== false) ? parent.crypto.randomBytes(parent.crypto.randomInt(0, 256)).toString('base64') : '';
7700 + // To mitigate any possible BREACH attack, we generate a random 0 to 255 bytes length string here.
7701 + xargs.randomlength = (args.webpagelengthrandomization !== false) ? parent.crypto.randomBytes(parent.crypto.randomBytes(1)[0]).toString('base64') : '';
7702
7703 return xargs;
7704 }