Hướng dẫn này giải thích cách di chuyển sang các phương thức xây dựng
const buf = new Buffer[notNumber, encoding];
3 an toàn. Quá trình di chuyển khắc phục cảnh báo không dùng nữa sau đâyCác hàm tạo Buffer[] và new Buffer[] không được khuyến nghị sử dụng do lo ngại về tính bảo mật và khả năng sử dụng. Vui lòng sử dụng Bộ đệm mới. cấp phát [], Bộ đệm. allocUnsafe[] hoặc Bộ đệm. from[] phương pháp xây dựng thay thế
- [khuyến khích]
Tìm các đoạn mã có vấn đề bằng cách sử dụng const buf = new Buffer[notNumber, encoding];
4
const buf = new Buffer[notNumber, encoding];
Chỉ cần chạy
const buf = new Buffer[notNumber, encoding];
0Nó sẽ tìm thấy tất cả những nơi có khả năng không an toàn trong mã của riêng bạn [với một số trường hợp ngoại lệ đáng kể]
Tìm các bit mã có vấn đề bằng Node. js 8
Nếu bạn đang sử dụng Nút. js ≥ 8. 0. 0 [được khuyến nghị], Nút. js hiển thị nhiều tùy chọn giúp tìm các đoạn mã có liên quan
1 sẽ tạo Nút. js hiển thị dấu vết ngăn xếp cho cảnh báo này và các cảnh báo khác được in bởi Node. jsconst buf = new Buffer[notNumber, encoding];
2 làm điều tương tự, nhưng chỉ dành cho các cảnh báo không dùng nữaconst buf = new Buffer[notNumber, encoding];
3 sẽ hiển thị nhiều loại cảnh báo không dùng nữa. Cụ thể, nó sẽ hiển thị cảnh báo ngừng sử dụngconst buf = new Buffer[notNumber, encoding];
4, ngay cả trên Node. js 8const buf = new Buffer[notNumber, encoding];
Bạn có thể đặt các cờ này bằng các biến môi trường
$ export NODE_OPTIONS='--trace-warnings --pending-deprecation'
$ cat example.js
'use strict';
const foo = new Buffer['foo'];
$ node example.js
[node:7147] [DEP0005] DeprecationWarning: The Buffer[] and new Buffer[] constructors are not recommended for use due to security and usability concerns. Please use the new Buffer.alloc[], Buffer.allocUnsafe[], or Buffer.from[] construction methods instead.
at showFlaggedDeprecation [buffer.js:127:13]
at new Buffer [buffer.js:148:3]
at Object. [/path/to/example.js:2:13]
[.. more stack trace lines ...]
Tìm các bit mã có vấn đề bằng cách sử dụng linters
Các quy tắc của ESLint không có trình xây dựng bộ đệm hoặc nút/không bị phản đối-api cũng tìm thấy các lệnh gọi đến API
const buf = new Buffer[notNumber, encoding];
4 không dùng nữa. Những quy tắc đó được bao gồm trong một số cài đặt trướcTuy nhiên, có một nhược điểm là không phải lúc nào
const buf = new Buffer[notNumber, encoding];
3 cũng bị ghi đè. g. với một polyfill, vì vậy nên kết hợp phương pháp này với một số phương pháp khác được mô tả ở trênBiến thể 1. Bỏ hỗ trợ cho Node. js ≤ 4. 4. x và 5. 0. 0 — 5. 9. x
Đây là giải pháp được đề xuất hiện nay có nghĩa là chỉ có chi phí tối thiểu
nút. js 5. x đã không được hỗ trợ kể từ tháng 7 năm 2016 và Node. js 4. x sắp hết hạn sử dụng vào tháng 4 năm 2018 [→ ]. Điều này có nghĩa là các phiên bản Node này. js sẽ không nhận được bất kỳ bản cập nhật nào, ngay cả trong trường hợp có vấn đề về bảo mật, vì vậy nên tránh sử dụng các dòng phát hành này, nếu có thể
Những gì bạn sẽ làm trong trường hợp này là chuyển đổi tất cả các cuộc gọi
const buf = new Buffer[notNumber, encoding];
7 hoặc const buf = new Buffer[notNumber, encoding];
4 để sử dụng const buf = new Buffer[notNumber, encoding];
6 hoặc const buf = new Buffer[notNumber, encoding];
7, theo cách sau- Đối với
1, hãy thay thế nó bằnglet buf; if [Buffer.from && Buffer.from !== Uint8Array.from] { buf = Buffer.from[notNumber, encoding]; } else { if [typeof notNumber === 'number'] { throw new Error['The "size" argument must be not of type number.']; } buf = new Buffer[notNumber, encoding]; }
2let buf; if [Buffer.from && Buffer.from !== Uint8Array.from] { buf = Buffer.from[notNumber, encoding]; } else { if [typeof notNumber === 'number'] { throw new Error['The "size" argument must be not of type number.']; } buf = new Buffer[notNumber, encoding]; }
- Đối với
3 [hoặclet buf; if [Buffer.from && Buffer.from !== Uint8Array.from] { buf = Buffer.from[notNumber, encoding]; } else { if [typeof notNumber === 'number'] { throw new Error['The "size" argument must be not of type number.']; } buf = new Buffer[notNumber, encoding]; }
4], hãy thay thế bằnglet buf; if [Buffer.from && Buffer.from !== Uint8Array.from] { buf = Buffer.from[notNumber, encoding]; } else { if [typeof notNumber === 'number'] { throw new Error['The "size" argument must be not of type number.']; } buf = new Buffer[notNumber, encoding]; }
5 [hoặclet buf; if [Buffer.from && Buffer.from !== Uint8Array.from] { buf = Buffer.from[notNumber, encoding]; } else { if [typeof notNumber === 'number'] { throw new Error['The "size" argument must be not of type number.']; } buf = new Buffer[notNumber, encoding]; }
6]let buf; if [Buffer.from && Buffer.from !== Uint8Array.from] { buf = Buffer.from[notNumber, encoding]; } else { if [typeof notNumber === 'number'] { throw new Error['The "size" argument must be not of type number.']; } buf = new Buffer[notNumber, encoding]; }
- Đối với tất cả các kết hợp đối số khác [những thứ này hiếm hơn nhiều], cũng thay thế
7 bằnglet buf; if [Buffer.from && Buffer.from !== Uint8Array.from] { buf = Buffer.from[notNumber, encoding]; } else { if [typeof notNumber === 'number'] { throw new Error['The "size" argument must be not of type number.']; } buf = new Buffer[notNumber, encoding]; }
8let buf; if [Buffer.from && Buffer.from !== Uint8Array.from] { buf = Buffer.from[notNumber, encoding]; } else { if [typeof notNumber === 'number'] { throw new Error['The "size" argument must be not of type number.']; } buf = new Buffer[notNumber, encoding]; }
Lưu ý rằng
const buf = new Buffer[notNumber, encoding];
6 cũng nhanh hơn trên Nút hiện tại. js cao hơn const buf = new Buffer[notNumber, encoding];
70, đây là những gì bạn cần để đảm bảo không điềnNên bật quy tắc ESLint no-buffer-constructor hoặc nút/no-deprecated-api để tránh tình cờ sử dụng API
const buf = new Buffer[notNumber, encoding];
3 không an toànNgoài ra còn có một hàm tạo tự động di chuyển
const buf = new Buffer[notNumber, encoding];
3 sang const buf = new Buffer[notNumber, encoding];
6 hoặc const buf = new Buffer[notNumber, encoding];
7. Lưu ý rằng nó hiện chỉ hoạt động với các trường hợp đối số là chữ hoặc khi hàm tạo được gọi với hai đối sốNếu bạn hiện đang hỗ trợ những Node cũ hơn. js và không thể bỏ hỗ trợ cho chúng hoặc nếu bạn hỗ trợ các nhánh cũ hơn trong gói của mình, hãy cân nhắc sử dụng hoặc trên các nhánh cũ hơn, vì vậy những người sử dụng các nhánh cũ hơn đó cũng sẽ nhận được bản sửa lỗi. Bằng cách đó, bạn sẽ loại bỏ các sự cố tiềm ẩn do sử dụng API
const buf = new Buffer[notNumber, encoding];
3 không được bảo vệ và người dùng của bạn sẽ không nhận thấy cảnh báo không dùng nữa trong thời gian chạy khi chạy mã của bạn trên Node. js 10Biến thể 2. Sử dụng một polyfill
Có ba polyfill khác nhau có sẵn
bộ đệm an toàn hơn là một sự thay thế thả xuống cho toàn bộ API
3, sẽ ném khi sử dụngconst buf = new Buffer[notNumber, encoding];
7const buf = new Buffer[notNumber, encoding];
Bạn sẽ thực hiện chính xác các bước tương tự như trong , nhưng với một
78 polyfill trong tất cả các tệp mà bạn sử dụng APIconst buf = new Buffer[notNumber, encoding];
3 mớiconst buf = new Buffer[notNumber, encoding];
Không sử dụng API
7 cũ. Trong bất kỳ tệp nào có thêm dòng ở trên, sử dụng APIconst buf = new Buffer[notNumber, encoding];
7 cũ sẽ némconst buf = new Buffer[notNumber, encoding];
buffer-from và/hoặc buffer-alloc là các ponyfill cho phần tương ứng của chúng trong API
3. Bạn chỉ cần thêm [các] gói tương ứng với API bạn đang sử dụngconst buf = new Buffer[notNumber, encoding];
Bạn sẽ nhập mô-đun cần thiết với một tên thích hợp, e. g.
23 và sau đó sử dụng nó thay vì gọi tớiconst buf = new Buffer[notNumber, encoding];
7, e. g.const buf = new Buffer[notNumber, encoding];
25 trở thànhconst buf = new Buffer[notNumber, encoding];
26const buf = new Buffer[notNumber, encoding];
Nhược điểm của cách tiếp cận này là có nhiều thay đổi mã hơn một chút để di chuyển khỏi chúng [như bạn sẽ sử dụng e. g.
7 dưới một tên khác]const buf = new Buffer[notNumber, encoding];
bộ đệm an toàn cũng là một sự thay thế thả xuống cho toàn bộ API
3, nhưng sử dụngconst buf = new Buffer[notNumber, encoding];
7 sẽ vẫn hoạt động như trướcconst buf = new Buffer[notNumber, encoding];
Một nhược điểm của phương pháp này là nó sẽ cho phép bạn cũng sử dụng API
7 cũ hơn trong mã của mình, điều này có vấn đề vì nó có thể gây ra sự cố trong mã của bạn và sẽ bắt đầu đưa ra cảnh báo không dùng nữa trong thời gian chạy bắt đầu với Node. js 10 []const buf = new Buffer[notNumber, encoding];
Lưu ý rằng trong cả hai trường hợp, điều quan trọng là bạn cũng phải xóa tất cả lệnh gọi đến API
const buf = new Buffer[notNumber, encoding];
3 cũ theo cách thủ công — chỉ thêm vào const buf = new Buffer[notNumber, encoding];
82 không tự khắc phục được sự cố, nó chỉ cung cấp một polyfill cho API mới. Tôi đã thấy mọi người làm sai lầm đóNên bật quy tắc ESLint no-buffer-constructor hoặc nút/no-deprecated-api
Đừng quên bỏ sử dụng polyfill sau khi bạn bỏ hỗ trợ cho Node. js < 4. 5. 0
Biến thể 3 — Phát hiện thủ công, có biện pháp bảo vệ
Điều này hữu ích nếu bạn chỉ tạo các phiên bản
const buf = new Buffer[notNumber, encoding];
3 ở một vài nơi [e. g. một] hoặc bạn có trình bao bọc của riêng mình xung quanh chúngconst buf = new Buffer[notNumber, encoding];
84
const buf = new Buffer[notNumber, encoding];
Trường hợp đặc biệt này để tạo bộ đệm trống có thể được thay thế một cách an toàn bằng
const buf = new Buffer[notNumber, encoding];
85, trả về kết quả tương tự cho đến tận Nút. js 0. 8. xconst buf = new Buffer[notNumber, encoding];
86
const buf = new Buffer[notNumber, encoding];
Trước
const buf = new Buffer[notNumber, encoding];
Sau
let buf;
if [Buffer.from && Buffer.from !== Uint8Array.from] {
buf = Buffer.from[notNumber, encoding];
} else {
if [typeof notNumber === 'number'] {
throw new Error['The "size" argument must be not of type number.'];
}
buf = new Buffer[notNumber, encoding];
}
const buf = new Buffer[notNumber, encoding];
87 là tùy chọnLưu ý rằng bắt buộc phải có
const buf = new Buffer[notNumber, encoding];
88 trước const buf = new Buffer[notNumber, encoding];
7 [đối với các trường hợp khi đối số const buf = new Buffer[notNumber, encoding];
70 không được mã hóa cứng] và không phải do hàm tạo const buf = new Buffer[notNumber, encoding];
3 không được dùng nữa - đó chính xác là lý do hàm tạo const buf = new Buffer[notNumber, encoding];
3 không được dùng nữa. Các gói hệ sinh thái thiếu tính năng kiểm tra loại này đã gây ra nhiều sự cố bảo mật — các tình huống khi đầu vào của người dùng không được vệ sinh có thể kết thúc trong const buf = new Buffer[notNumber, encoding];
73 tạo ra các sự cố từ DoS đến rò rỉ thông tin nhạy cảm cho kẻ tấn công từ bộ nhớ tiến trìnhKhi đối số
const buf = new Buffer[notNumber, encoding];
70 được mã hóa cứng [e. g. nghĩa đen là const buf = new Buffer[notNumber, encoding];
75 hoặc const buf = new Buffer[notNumber, encoding];
76], có thể bỏ qua dấu kiểm const buf = new Buffer[notNumber, encoding];
77Ngoài ra, lưu ý rằng việc sử dụng TypeScript không khắc phục được sự cố này cho bạn — khi các lib được viết bằng
const buf = new Buffer[notNumber, encoding];
78 được sử dụng từ JS hoặc khi đầu vào của người dùng kết thúc ở đó — nó hoạt động chính xác như JS thuần túy, vì tất cả các kiểm tra loại chỉ là thời gian dịch và const buf = new Buffer[notNumber, encoding];
79
const buf = new Buffer[notNumber, encoding];
Đối với nút. js 0. 10. hỗ trợ x [và bên dưới]
const buf = new Buffer[notNumber, encoding];
7Mặt khác [Nút. js ≥ 0. 12. x]
const buf = new Buffer[notNumber, encoding];
2Về const buf = new Buffer[notNumber, encoding];
60
const buf = new Buffer[notNumber, encoding];
Hãy hết sức thận trọng khi sử dụng
const buf = new Buffer[notNumber, encoding];
60- Đừng sử dụng nó nếu bạn không có lý do chính đáng để
- e. g. bạn có thể sẽ không bao giờ thấy sự khác biệt về hiệu suất đối với các bộ đệm nhỏ, trên thực tế, những bộ đệm đó có thể còn nhanh hơn với
6,const buf = new Buffer[notNumber, encoding];
- nếu mã của bạn không nằm trong đường dẫn mã nóng — bạn cũng có thể sẽ không nhận thấy sự khác biệt,
- lưu ý rằng việc không lấp đầy sẽ giảm thiểu các rủi ro tiềm ẩn
- e. g. bạn có thể sẽ không bao giờ thấy sự khác biệt về hiệu suất đối với các bộ đệm nhỏ, trên thực tế, những bộ đệm đó có thể còn nhanh hơn với
- Nếu bạn sử dụng nó, hãy đảm bảo rằng bạn không bao giờ trả về bộ đệm ở trạng thái đầy một phần,
- nếu bạn đang viết nó theo trình tự - luôn cắt ngắn nó theo độ dài viết thực tế
Lỗi khi xử lý bộ đệm được phân bổ bằng
const buf = new Buffer[notNumber, encoding];
60 có thể dẫn đến nhiều sự cố khác nhau, từ hành vi không xác định của mã đến dữ liệu nhạy cảm [thông tin nhập của người dùng, mật khẩu, chứng chỉ] bị rò rỉ cho kẻ tấn công từ xaLưu ý rằng điều tương tự cũng áp dụng cho việc sử dụng
const buf = new Buffer[notNumber, encoding];
7 mà không cần điền số 0, tùy thuộc vào Nút. js [và việc thiếu kiểm tra loại cũng thêm DoS vào danh sách các sự cố tiềm ẩn]Câu hỏi thường gặp
Có gì sai với hàm tạo const buf = new Buffer[notNumber, encoding];
3?
const buf = new Buffer[notNumber, encoding];
Hàm tạo
const buf = new Buffer[notNumber, encoding];
3 có thể được sử dụng để tạo bộ đệm theo nhiều cách khác nhau
67 tạo mộtconst buf = new Buffer[notNumber, encoding];
3 trong số 42 byte. Trước nút. js 8, bộ đệm này chứa bộ nhớ tùy ý vì lý do hiệu suất, có thể bao gồm mọi thứ từ mã nguồn chương trình đến mật khẩu và khóa mã hóaconst buf = new Buffer[notNumber, encoding];
69 tạo mộtconst buf = new Buffer[notNumber, encoding];
3 chứa phiên bản được mã hóa UTF-8 của chuỗiconst buf = new Buffer[notNumber, encoding];
31. Đối số thứ hai có thể chỉ định mã hóa khác. ví dụ:const buf = new Buffer[notNumber, encoding];
32 có thể được sử dụng để chuyển đổi chuỗi Base64 thành chuỗi byte ban đầu mà nó đại diệnconst buf = new Buffer[notNumber, encoding];
- Có một số kết hợp khác của các đối số
Điều này có nghĩa là trong mã như
const buf = new Buffer[notNumber, encoding];
33, không thể biết chính xác nội dung của bộ đệm được tạo là gì nếu không biết loại const buf = new Buffer[notNumber, encoding];
34Đôi khi, giá trị của
const buf = new Buffer[notNumber, encoding];
34 đến từ một nguồn bên ngoài. Ví dụ: chức năng này có thể được hiển thị dưới dạng dịch vụ trên máy chủ web, chuyển đổi chuỗi UTF-8 thành dạng Base64 của nóconst buf = new Buffer[notNumber, encoding];
8Lưu ý rằng mã này không xác thực loại
const buf = new Buffer[notNumber, encoding];
36
36 dự kiến là một chuỗi. Nếu đây là trường hợp, tất cả diễn ra tốt đẹpconst buf = new Buffer[notNumber, encoding];
36 được kiểm soát bởi khách hàng gửi yêu cầuconst buf = new Buffer[notNumber, encoding];
- Nếu
36 là sốconst buf = new Buffer[notNumber, encoding];
40, thìconst buf = new Buffer[notNumber, encoding];
41 sẽ làconst buf = new Buffer[notNumber, encoding];
40 byteconst buf = new Buffer[notNumber, encoding];
- Trước nút. js 8, nội dung sẽ không được khởi tạo
- Sau nút. js 8, nội dung sẽ là
40 byte với giá trịconst buf = new Buffer[notNumber, encoding];
44const buf = new Buffer[notNumber, encoding];
Do kiểm tra loại bị thiếu, kẻ tấn công có thể cố tình gửi một số như một phần của yêu cầu. Sử dụng điều này, họ có thể
- Đọc bộ nhớ chưa khởi tạo. Điều này sẽ làm rò rỉ mật khẩu, khóa mã hóa và các loại thông tin nhạy cảm khác. [Rò rỉ thông tin]
- Buộc chương trình phân bổ một lượng lớn bộ nhớ. Ví dụ: khi chỉ định
45 làm giá trị đầu vào, mỗi yêu cầu sẽ phân bổ 500MB bộ nhớ. Điều này có thể được sử dụng để làm cạn kiệt hoàn toàn bộ nhớ khả dụng của một chương trình và làm cho chương trình gặp sự cố hoặc làm chậm đáng kể. [Từ chối dịch vụ]const buf = new Buffer[notNumber, encoding];
Cả hai trường hợp này đều được coi là sự cố bảo mật nghiêm trọng trong bối cảnh máy chủ web trong thế giới thực
Thay vào đó, khi sử dụng
const buf = new Buffer[notNumber, encoding];
46, việc chuyển một số sẽ luôn đưa ra một ngoại lệ, đưa ra một hành vi được kiểm soát mà chương trình luôn có thể xử lýHàm tạo const buf = new Buffer[notNumber, encoding];
4 đã không được dùng nữa trong một thời gian. Đây thực sự là một vấn đề?
const buf = new Buffer[notNumber, encoding];
Các khảo sát về mã trong hệ sinh thái
const buf = new Buffer[notNumber, encoding];
48 đã chỉ ra rằng hàm tạo const buf = new Buffer[notNumber, encoding];
4 vẫn được sử dụng rộng rãi. Điều này bao gồm mã mới và việc sử dụng tổng thể mã đó đã thực sự tăng lên