Tấn công tiêm chích PHP là gì?

Tiếp nối bài đăng trước của tôi về kiểm tra lỗ hổng bảo mật PHP Composer, tôi nghĩ bài đăng này có thể hữu ích trong việc giúp tạo các ứng dụng an toàn hơn ngăn chặn việc tiêm mã PHP. Là nhà phát triển, chúng tôi xây dựng ứng dụng để giúp cuộc sống của người dùng cuối trở nên dễ dàng hơn. Có thể là ứng dụng giải trí, nơi làm việc hoặc mạng xã hội, mục tiêu cuối cùng là bảo vệ người dùng mà chúng tôi xây dựng cho bằng cách đảm bảo chúng tôi xây dựng tính bảo mật trong mã. Việc áp dụng các thực hành mã hóa an toàn không chỉ giúp giữ an toàn cho người dùng cuối mà còn tiết kiệm thời gian và chi phí phát triển bằng cách ngăn chặn việc làm lại.  

Tiêm mã là gì?

Chèn mã là một cuộc tấn công cung cấp tải trọng mã độc hại thông qua một vectơ tấn công dễ bị tấn công. Mục đích là để làm tổn hại đến tính toàn vẹn của ứng dụng mục tiêu dự kiến. Kẻ tấn công có thể gửi mã PHP hoặc JavaScript có thể thực thi được ở phía thời gian chạy của ứng dụng hoặc trong trình duyệt của người dùng cuối. Điều quan trọng cần lưu ý là PHP không cung cấp trình thoát dành riêng cho JavaScript, điều này cũng có thể gây ra sự cố. Lỗ hổng được xử lý trong thời gian chạy PHP, thực thi ở phía máy chủ hoặc trong trình duyệt của người dùng không nghi ngờ

Cách ngăn chặn tiêm mã trong PHP

Bảo mật phát triển mã bắt đầu từ đầu mã với việc áp dụng quy ước mã hóa an toàn. Hãy nhận biết các đầu vào phía trước và cách chúng được xử lý. Vệ sinh mọi thứ đến và nhận biết cách nó được lưu trữ trong ứng dụng của bạn.  

Theo nguyên tắc cơ bản, không bao giờ được phép thực thi mã động trong bất kỳ ứng dụng nào. Ví dụ: tránh sử dụng chức năng cốt lõi của PHP như shell_exec()exec() nếu có thể, chức năng này thực thi ở cấp hệ điều hành

Bạn nên luôn sử dụng công cụ quét bảo mật mã nguồn mở như Snyk Open Source. Công cụ này sẽ quét trình quản lý gói của bạn để xác định các lỗ hổng tiềm ẩn trong việc sử dụng thư viện và phụ thuộc. Một việc tôi cũng đang làm hàng ngày là kiểm tra cơ sở dữ liệu về lỗ hổng Snyk của nhà soạn nhạc để khám phá các kỹ thuật đang được sử dụng. Các trang báo cáo chi tiết sẽ cho phép bạn truy ngược lại các kho lưu trữ ở cấp mã để khám phá cách các lỗ hổng được xác định

5 cách ngăn chặn code injection trong phát triển ứng dụng PHP

  1. Tránh sử dụng exec(), shell_exec(), system() hoặc passthru()
  2. Tránh sử dụng strip_tags() để khử trùng
  3. tuần tự hóa mã
  4. Sử dụng một kẻ nói dối bảo mật PHP
  5. Sử dụng công cụ SAST để xác định các sự cố chèn mã

1. Tránh sử dụng exec(), shell_exec(), system() hoặc passthru()

Như câu nói “ở đây có rồng. ” Theo quy định, Tránh sử dụng bất kỳ thứ gì có thể gọi trực tiếp môi trường điều hành từ PHP khi có thể. Từ quan điểm vectơ tấn công, điều này có rất nhiều cơ hội để mở tất cả các loại vấn đề trực tiếp vào ngăn xếp của bạn.  

Theo truyền thống, các chức năng như exec(), shell_exec(), system()passthru() sẽ được sử dụng để thực hiện các chức năng như nén hoặc giải nén tệp, tạo công việc định kỳ và thậm chí điều hướng các tệp và thư mục của hệ điều hành. Tất cả những thứ này sẽ chạy mà không có bất kỳ quy trình khử trùng mã tích hợp nào, đó là nơi rắc rối bắt đầu khi sử dụng chúng, đặc biệt là với đầu vào trực tiếp của người dùng chưa được xác thực hoặc đã được làm sạch.  

PHP cung cấp một số toán tử chức năng với thoát đầu vào tích hợp, cụ thể là  exec()1 và exec()2, sẽ chuyển đầu vào qua một số mức thoát và làm sạch như một phần của lệnh gọi hàm. Có một vài cách an toàn hơn để tiếp cận chức năng tương tự

Kể từ PHP 7. 4, việc lưu trữ có thể được xử lý bởi lớp exec()3, được kích hoạt bằng cờ exec()4 như một phần của trình biên dịch PHP. Tuy nhiên, cần phải cẩn thận hơn với điều này vì nó vẫn có thể kích hoạt một cuộc tấn công ngang.  

Tiếp cận tương tác hệ thống tệp theo chương trình bằng cách giảm thiểu các cách mà nó có thể được tương tác trực tiếp thông qua đầu vào. PHP có các hàm tệp có thể được sử dụng mà không cần gọi trực tiếp HĐH. Lấy danh sách các tệp trong một thư mục cụ thể, chẳng hạn, có thể được thực hiện thông qua hàm exec()5, hàm này sẽ trả về một mảng các tệp có sẵn trong một thư mục, sau đó được mở hoặc tham chiếu trong chính mã đó. Hãy nhớ cẩn thận để không truy cập các tệp được tạo bởi đầu vào bị lộ và cả một số chức năng xung quanh các quyền dựa trên tệp như exec()6 và exec()7. Ngoài ra, điều quan trọng là không tin tưởng vào tiêu đề nội dung (có thể bị làm giả) và xác thực loại tệp.  

Tự động tạo các công việc định kỳ bằng thư viện Trình soạn thảo như cron. Điều này thực sự được chạy thông qua một cron, sau đó chạy các cron của chính nó như một phần của thời gian chạy cron tổng thể. Vẫn cần phải cẩn thận với những gì được chạy trong đó nhưng tiếp cận việc tạo quy trình theo chương trình nhiều hơn mà không để lộ quyền truy cập vào HĐH lõi.  

2. Tránh sử dụng strip_tags() để khử trùng

Phải luôn cẩn thận hơn với việc xử lý và vệ sinh đầu vào của người dùng. Mục tiêu ở đây là chấp nhận đầu vào hợp lệ của người dùng nhưng sau đó lưu trữ và xử lý nó theo đúng cách để ứng dụng của bạn không trở nên dễ bị tấn công. Hãy nhớ rằng, đầu vào là một vectơ tấn công mở để các tác nhân độc hại có thể tương tác với ứng dụng của bạn. Vì vậy, hãy đảm bảo dành thời gian để luôn xử lý dữ liệu đầu vào đúng cách.  

Hàm strip_tags() được thiết kế chủ yếu để chỉ xóa HTML và PHP khỏi đầu vào được cung cấp. Điều này có nghĩa là những thứ như JavaScript và SQL và đầu vào có khả năng độc hại khác sẽ được hàm coi là hợp lệ. exec()0 là một tùy chọn khác được sử dụng để làm sạch đầu vào, cũng cho phép các bộ ký tự UTF có thể xác định, hãy nhớ rằng điều này vẫn không làm sạch hoàn toàn đầu vào

Cũng có thể loại bỏ dữ liệu bằng cách sử dụng hàm regex như exec()1. Điều này sẽ chỉ trả lại văn bản và số từ đầu vào, đối với bộ ký tự UTF-8. Cũng nên cẩn thận với các chức năng như exec()2 khi xử lý việc dọn dẹp đầu vào của người dùng. Trước đây, chúng tôi đã thấy các trường hợp lỗ hổng xuất hiện trong một số hàm chuỗi nhiều byte (exec()3) như CVE-2020-7065, đây là lỗ hổng ghi ngoài giới hạn do mã hóa UTF-32LE gây ra. Điều này có thể dẫn đến sự cố bộ đệm ghi đè ngăn xếp và cho phép thực thi mã xảy ra.   

Thay vào đó, hãy chọn sử dụng thứ gì đó như exec()4 sẽ xác thực và khử trùng dựa trên các tùy chọn bộ lọc đã xác định. Ví dụ: exec()5, exec()6 được chuyển vào hàm exec()4 cùng với thông tin nhập của người dùng chẳng hạn sẽ xóa tất cả các thẻ HTML và tất cả các ký tự có giá trị ASCII exec()8

Ngoài ra còn có một vài thư viện Trình soạn thảo thường được sử dụng để khử trùng đầu vào. Một thư viện như bộ lọc HTML cung cấp khả năng khử trùng tuân thủ HTML với danh sách cho phép khá tốt cho phép bạn tùy chỉnh loại dữ liệu đầu vào mà bạn cần đưa vào ứng dụng của mình.  

3. Tránh exec()9 trong PHP

Toàn bộ phần này có thể dễ dàng trở thành toàn bộ bài đăng trên blog của riêng nó và nó đã là một chủ đề được tranh luận sôi nổi trong nhiều năm, ngay cả trong các nhà phát triển làm việc trên PHP. Hướng dẫn sử dụng PHP thực sự nêu bật những nguy hiểm khi sử dụng hàm exec()9. Đặc biệt là nó “không được thông qua đầu vào của người dùng không đáng tin cậy”, điều này có thể khiến “mã được tải và thực thi”.  

shell_exec()1 được dự định sử dụng để chuyển đổi một lớp thành một chuỗi có thể được lưu trữ và chuyển đến các chức năng khác hoặc được lưu vào bộ đệm để sử dụng sau. Bản thân nó nghe có vẻ tương đối vô hại cho đến khi bạn bắt đầu hiểu cách thức hoạt động của mã C cơ bản khi lưu trữ dữ liệu exec()9 trong bộ nhớ, đây là nơi mà hầu hết các sự cố của nó có thể xảy ra

Bạn nên sử dụng định dạng dữ liệu tiêu chuẩn như JSON qua shell_exec()3 và shell_exec()4. Điều này có thể cung cấp một phương thức vận chuyển an toàn và vệ sinh để gửi và nhận dữ liệu được đánh số nhiều kỳ đến và đi từ người dùng.  

4. Sử dụng một kẻ nói dối bảo mật PHP

Có sẵn các công cụ phù hợp như một phần trong quy trình phát triển của bạn giúp tạo mã an toàn và nhiều chức năng hơn ngay từ đầu. Linters là một cách tuyệt vời để giảm lỗi và các sự cố tiềm ẩn như là một phần của quá trình phát triển ứng dụng PHP và cũng giảm các lỗ hổng trong mã nguồn.  

Bạn cũng nên đảm bảo rằng lỗi hiển thị được tắt theo mặc định trong PHP. cấu hình ini. Vô hiệu hóa shell_exec()5, shell_exec()6 và shell_exec()7 sẽ xóa đầu ra lỗi có khả năng được sử dụng để xác định thông tin cấu hình và môi trường trong ứng dụng của bạn

Bản thân ngôn ngữ PHP đã tích hợp sẵn một trình nói dối sẽ hiển thị các thông báo lỗi rất dài dòng như một phần của quá trình xác thực của nó. Nó có thể được gọi tại CLI (hoặc là một phần của khung kiểm tra) bằng cách chạy shell_exec()8 theo sau là tệp để kiểm tra. Nhược điểm của việc sử dụng điều này như một kẻ nói dối là nó chỉ có thể kiểm tra một tệp tại một thời điểm, mặc dù nó có thể được sử dụng như một phần của vòng lặp để lặp lại nhiều tệp trong một lần chạy.  

PHPlint là một tùy chọn mạnh mẽ, được biết đến rộng rãi hơn để kiểm tra nhiều tệp một cách nhanh chóng. PHPLint có thể được sử dụng tại CLI hoặc như một thư viện khởi xướng của nhà soạn nhạc. Ngoài ra, nó có thể được gọi vào một hình ảnh docker khá dễ dàng. PHPLint có thể được sử dụng để kiểm tra PHP 7 và PHP 8, và mặc dù nó có đầu ra khá dài dòng, nhưng nó có thể được sử dụng để xác định các vấn đề thông qua một số quy trình linting cùng một lúc.  

Một kẻ nói dối phổ biến khác là PHP-Parallel-Lint, hỗ trợ PHP 5. 3 to PHP 8. 0 và cũng có thể chạy nhiều tiến trình linter nhanh hơn bạn có thể gõ shell_exec()9. PHP-Parallel-Lint có đầu ra chi tiết hơn các tùy chọn đã nói ở trên, mặc dù hiện tại nó chưa hỗ trợ tùy chọn CLI hoặc giải pháp Docker có sẵn.  

5. Sử dụng công cụ kiểm tra bảo mật ứng dụng tĩnh để xác định các sự cố chèn mã

Một trong những IDE được sử dụng rộng rãi hơn để phát triển PHP là PHPStorm có một số tính năng phân tích mã tĩnh thực sự tiện dụng được tích hợp ngay trong. Xây dựng dựa trên những phần bổ sung mà chúng ta đã khám phá ở trên, PHPStorm có các tùy chọn tích hợp cho Xdebug, rất phù hợp để linting, profiling và (như tên gợi ý) mã gỡ lỗi để giảm lỗi. Đối với quy trình mã hóa an toàn, PHPStorm cho phép thực thi các quy tắc mã hóa cụ thể và tiêu chuẩn PSR, điều này rất hữu ích, đặc biệt là khi làm việc trên các ứng dụng tuân thủ PCI.  

Để cải thiện bảo mật mã, Snyk có một plugin cho PHPStorm có thể giúp quét các vấn đề về chất lượng mã và các lỗ hổng trong mã và các thư viện trong mã của bạn. Thật dễ dàng để cài đặt, khởi động và chạy rất nhanh và có sẵn trong phần bổ trợ trong ứng dụng

Tấn công tiêm chích PHP là gì?

Một công cụ phát triển khác đang được các nhà phát triển và đặc biệt là các nhà phát triển PHP áp dụng rộng rãi hơn, đó là VSCode. Giống như PHPStorm, nó cũng có một trình nói dối tích hợp sẵn và khả năng thực thi các tiêu chuẩn PSR.  

Quét các lỗ hổng trong VSCode bằng Snyk cũng đơn giản như mở một thiết bị đầu cuối VSCode mới và sử dụng Snyk CLI để kiểm tra snyk hoặc sử dụng màn hình snyk để nhận các cảnh báo liên tục đến cơ sở mã. Để tìm hiểu thêm để bắt đầu với Snyk CLI và PHP, hãy xem bài đăng trên blog trước đây của tôi về việc kiểm tra các lỗ hổng bảo mật của Trình soạn thảo PHP với Snyk

Cập nhật. Gần đây, chúng tôi cũng đã phát hành hỗ trợ PHP cho mã Snyk, để đọc thêm và tự mình dùng thử, hãy xem bài đăng trên blog Hỗ trợ mã Snyk để quét lỗ hổng PHP bước vào giai đoạn thử nghiệm

Tóm lược

Là nhà phát triển, chúng tôi xây dựng các ứng dụng để trợ giúp người dùng cuối trong cuộc sống hàng ngày của họ. Đảm bảo những ứng dụng đó được giữ an toàn không chỉ đảm bảo cho người dùng rằng dữ liệu của họ được an toàn mà còn để họ có thể tin tưởng bạn.  

Việc đảm bảo bạn xác định các lỗ hổng chèn mã trong khi xây dựng các ứng dụng ở phía trước mã thật dễ dàng, cung cấp cho bạn các công cụ và quy trình làm việc phù hợp ngay từ đầu

Đăng ký Snyk

Bảo mật mã PHP của bạn ngay từ đầu với Snyk — miễn phí

Đăng kí miễn phí

Thảo luận về blog này trên Discord

Tham gia Cộng đồng DevSecOps trên Discord để thảo luận về chủ đề này và hơn thế nữa với các học viên tập trung vào bảo mật khác

Tấn công tiêm có nghĩa là gì?

Trong một cuộc tấn công tiêm chích, kẻ tấn công cung cấp đầu vào không đáng tin cậy cho chương trình . Đầu vào này được trình thông dịch xử lý như một phần của lệnh hoặc truy vấn. Đổi lại, điều này làm thay đổi việc thực hiện chương trình đó. Tiêm chích là một trong những cuộc tấn công lâu đời nhất và nguy hiểm nhất nhắm vào các ứng dụng web.

PHP có phải là rủi ro bảo mật không?

Nghiên cứu cho thấy rằng PHP có tỷ lệ mắc lỗi bảo mật cao nhất , khiến nó trở thành con mồi lý tưởng cho tội phạm mạng. Ngôn ngữ này có các lỗ hổng ở cấp độ ứng dụng khiến nó dễ bị tấn công bằng mã độc.

Các ví dụ về các cuộc tấn công tiêm chích là gì?

Các cuộc tấn công tiêm chích có thể bao gồm các cuộc gọi đến hệ điều hành thông qua các cuộc gọi hệ thống, việc sử dụng các chương trình bên ngoài thông qua các lệnh shell hoặc các cuộc gọi đến cơ sở dữ liệu phụ trợ bằng cách sử dụng SQL (i. e. , SQL injection) . Bất cứ khi nào một ứng dụng sử dụng trình thông dịch, sẽ có nguy cơ tạo ra lỗ hổng tiêm chích.

Ví dụ SQL injection trong PHP là gì?

PHP SQL injection là gì?