Vệ sinh quy trình con Python

Tiêm lệnh là một trong những cuộc tấn công tiêm chích ít phổ biến hơn so với các cuộc tấn công tiêm nhiễm SQL. Điều này thường là do việc phối hợp mất nhiều thời gian và cân nhắc hơn. Tuy nhiên, bỏ qua các cuộc tấn công chèn lệnh có thể khiến hệ thống hoặc ứng dụng của bạn dễ bị tổn thương trước một số mối đe dọa lớn. Và trong một số trường hợp, nó thậm chí có thể dẫn đến sự xâm phạm toàn bộ hệ thống.  

Vì vậy, trong bài đăng này, chúng tôi sẽ giúp bạn làm quen với lệnh tiêm qua các ví dụ cụ thể — chính xác hơn là lệnh tiêm trong Python.  

Tiêm lệnh là gì?

Chèn lệnh gửi dữ liệu độc hại vào một ứng dụng có thể dẫn đến thiệt hại nghiêm trọng khi được trình thông dịch mã đánh giá động. Nói một cách đơn giản, đây là khi kẻ tấn công có thể thực thi các lệnh trên máy chủ ứng dụng của bạn thông qua lỗ hổng trong mã ứng dụng của bạn. Chúng tôi cũng gọi đây là thực thi mã từ xa.  

Giống như các cuộc tấn công tiêm chích khác, đầu vào của người dùng không được vệ sinh khiến cho việc tiêm lệnh có thể xảy ra. Và điều này không phân biệt ngôn ngữ lập trình được sử dụng. Chúng tôi nói điều này bởi vì ngay cả mã được viết bằng Python, vốn nổi tiếng là ngôn ngữ lập trình an toàn, cũng có thể trở thành con mồi của các cuộc tấn công tiêm chích. Bạn có thể làm những việc rất không an toàn với các ngôn ngữ được thiết kế để bảo mật. Chúng ta sẽ thấy điều này rõ ràng hơn trong các ví dụ được đề cập trong bài viết.  

Ví dụ trong Python

Khai thác Eval[] và Exec[]

Hãy xem xét tập lệnh máy tính đơn giản này bằng Python lấy biểu thức từ người dùng và đánh giá đầu ra.  

con trăn

compute = input['\nYour expression? => ']
if not compute:
print ["No input"]
else:
print ["Result =", eval[comp]]

Nhập một biểu thức như 2 * 3 sẽ dẫn đến Kết quả = 6, đó là kết quả mong muốn. Mặt khác, một người dùng độc hại có thể nhập một cái gì đó như __import__['os']. system['rm –rf /'] làm đầu vào. Và điều này dẫn đến việc xóa tất cả các tệp và thư mục trong thư mục của tập lệnh nếu quy trình có đủ đặc quyền.  

Để ngăn điều đó xảy ra, chúng ta cần xác thực các biểu thức do người dùng nhập vào. Một cái gì đó như thế này.  

con trăn

compute = input['\nYour expression? => ']
if not compute :
print ["No input"]
else:
if validate[compute]:
print ["Result =", eval[comp]]
else:
print ["Error"]

Trong trường hợp cụ thể này, ứng dụng của chúng tôi chỉ mong đợi các số và biểu thức số học làm đầu vào. Việc triển khai tốt hàm validate[] sẽ chỉ cần kiểm tra tất cả đầu vào được cung cấp dựa trên danh sách trắng chỉ chứa các ký tự số và toán tử số học.  

Hãy cùng xem một ví dụ với hàm exec[]. Hãy xem xét tập lệnh sau, tạo ra một sân chơi cho phép người mới bắt đầu chơi với các lệnh Python đơn giản mà họ đã học.  

con trăn

code = input['What command[s] in python did you learn today?']
exec[code]

Nhập một cái gì đó như len[word] cho 4 và người dùng của chúng tôi rất vui. Mặt khác, một người dùng không mấy thân thiện cũng có thể gõ vào __import__['os'].system.listdir[] và xem tất cả các thư mục của bạn được liệt kê. Chúa biết những gì họ có thể làm từ đó. Nhưng chúng tôi hy vọng bạn hiểu được những thiệt hại tiềm tàng.  

Cũng giống như hàm

compute = input['\nYour expression? => ']
if not compute :
print ["No input"]
else:
if validate[compute]:
print ["Result =", eval[comp]]
else:
print ["Error"]
0, chúng ta có thể loại bỏ rủi ro đó bằng cách xác thực thông tin nhập của người dùng. Tất nhiên, việc triển khai tốt chức năng validate[] phù hợp với tập lệnh này sẽ đủ để khắc phục lỗ hổng này.  

Cũng giống như hàm

compute = input['\nYour expression? => ']
if not compute :
print ["No input"]
else:
if validate[compute]:
print ["Result =", eval[comp]]
else:
print ["Error"]
0, chúng ta có thể loại bỏ rủi ro đó bằng cách xác thực thông tin nhập của người dùng

Khai thác đầu vào[]

Hàm

compute = input['\nYour expression? => ']
if not compute :
print ["No input"]
else:
if validate[compute]:
print ["Result =", eval[comp]]
else:
print ["Error"]
3 là phương tiện mà tập lệnh Python có thể đọc đầu vào của người dùng thành một biến. Trong Python 2. x, hàm
compute = input['\nYour expression? => ']
if not compute :
print ["No input"]
else:
if validate[compute]:
print ["Result =", eval[comp]]
else:
print ["Error"]
3 tương đương với
compute = input['\nYour expression? => ']
if not compute :
print ["No input"]
else:
if validate[compute]:
print ["Result =", eval[comp]]
else:
print ["Error"]
5. Và như chúng ta vừa thấy, chúng ta phải cẩn thận khi làm việc với
compute = input['\nYour expression? => ']
if not compute :
print ["No input"]
else:
if validate[compute]:
print ["Result =", eval[comp]]
else:
print ["Error"]
0. Hãy xem xét kịch bản dưới đây. Nhập từ “mật khẩu” làm mật khẩu sẽ khiến điều kiện “nếu” được đánh giá là Đúng. Ngạc nhiên? .  

con trăn

admin_pass = get_user_pass["admin"]
if password == input["Please enter your password"]:
  login[]
else:
  print "Password is incorrect!"

Khi chúng ta nhập từ “mật khẩu” làm đầu vào, hàm

compute = input['\nYour expression? => ']
if not compute :
print ["No input"]
else:
if validate[compute]:
print ["Result =", eval[comp]]
else:
print ["Error"]
0 sẽ đánh giá từ này thành một biến ngẫu nhiên để khớp tên của biến với mật khẩu thực tế. Theo cách đó, bất kể mật khẩu là gì, ai đó đủ thông minh để thử từ “mật khẩu” sẽ luôn có quyền truy cập vào hệ thống.  

May mắn cho chúng tôi, Python 3. x sửa lỗi này và hàm

compute = input['\nYour expression? => ']
if not compute :
print ["No input"]
else:
if validate[compute]:
print ["Result =", eval[comp]]
else:
print ["Error"]
3 sẽ luôn chuyển đổi giá trị được cung cấp cho nó thành một chuỗi.  

Lệnh hệ điều hành

Tiếp theo, chúng ta sẽ xem xét một tập lệnh đơn giản khác ping địa chỉ được cung cấp. Nó có thể là một tên miền hoặc một địa chỉ IP.  

con trăn

address = request.args.get["address"]
cmd = "ping -c 1 %s" % address
subprocess.Popen[cmd, shell=True]

Kẽ hở rất rõ ràng và bất kỳ lệnh nào chúng tôi nhập dưới dạng địa chỉ đều được thực thi trên máy chủ ứng dụng. Tất cả những gì kẻ tấn công phải làm là thêm một nửa cột và sau đó nhập bất kỳ lệnh nào họ muốn. Ví dụ: google. com ; . Tuy nhiên, việc khắc phục điều này rất dễ dàng vì Python cung cấp các hàm tích hợp để khắc phục điều này.  

con trăn

address = request.args.get["address"]
command = "ping -c 1 {}".format[address]
args = shlex.split[command]
subprocess.Popen[args]

Hàm

compute = input['\nYour expression? => ']
if not compute :
print ["No input"]
else:
if validate[compute]:
print ["Result =", eval[comp]]
else:
print ["Error"]
9 tách chuỗi lệnh thành một mảng trước khi chạy nó. Theo cách này, nếu có bất kỳ đầu vào độc hại nào, việc thực thi lệnh sẽ không thành công.  

Ngăn chặn lệnh tiêm trong Python

Nguyên tắc chung là tránh sử dụng đầu vào của người dùng trong mã được đánh giá động. Nếu điều này là không thể tránh khỏi, việc xác thực đầu vào của người dùng nghiêm ngặt phải được thực hiện để giảm thiểu rủi ro. Tuy nhiên, chúng ta chỉ có thể làm được rất nhiều điều trong số này, với tư cách là con người như chúng ta. Do đó, cần có các phương pháp thiết thực hơn để giữ cho các ứng dụng của chúng ta an toàn khỏi việc tiêm lệnh trong Python. Bất kỳ ai coi trọng tính bảo mật của ứng dụng của họ đều áp dụng các phương pháp đơn giản và có cấu trúc này.  

Nguyên tắc chung là tránh sử dụng đầu vào của người dùng trong mã được đánh giá động

Sử dụng Python3

Điều này có vẻ giống như một số người thích, nhưng bạn có thể ngạc nhiên bởi số lượng ứng dụng Python trong sản xuất vẫn chạy phiên bản 2. 7. Với những thay đổi mà phiên bản 3 mang lại [như sửa lỗi chức năng

compute = input['\nYour expression? => ']
if not compute :
print ["No input"]
else:
if validate[compute]:
print ["Result =", eval[comp]]
else:
print ["Error"]
3, chúng tôi đã đề cập ở trên], việc nâng cấp không phải là nhiệm vụ dễ dàng nhất, nhưng rất đáng để nỗ lực. Đó là lý do tại sao đây là cách thực hành an toàn đơn giản nhưng hữu ích nhất để xây dựng trong Python.  

Đánh giá mã bảo mật

Những đánh giá này tập trung vào tính bảo mật chung của mã nguồn ứng dụng và bao gồm các lỗ hổng tiêm chích. Chúng là một bước quan trọng trong vòng đời phát triển phần mềm an toàn và chúng tôi thường gọi quy trình này là Kiểm tra bảo mật ứng dụng tĩnh [SAST].  

Kiểm tra bảo mật ứng dụng động [DAST]

Sau Kiểm tra bảo mật ứng dụng tĩnh, chúng tôi có Kiểm tra bảo mật ứng dụng động. Đây là một hình thức kiểm tra bảo mật hiện đại, tự động hóa hơn và thường được sử dụng như một phần của quy trình CI/CD. Có một số công cụ hiện có cho phép bạn làm điều này, chẳng hạn như công cụ chúng tôi đang xây dựng ở đây tại StackHawk và các công cụ khác. Điều quan trọng nhất là bạn chọn giải pháp phù hợp với nhu cầu của mình và quan trọng hơn là giải pháp giúp bạn tìm và khắc phục các lỗ hổng nhanh hơn.  

Cập nhật các lỗ hổng

Điều này có vẻ như là một điều không thể. Hầu hết các dự án sử dụng rất nhiều dự án và gói nguồn mở và thực tế là không thể được thông báo về tất cả các lỗ hổng được phát hiện trong mỗi gói. Một lần nữa, bạn không đơn độc, vì có những công cụ như Snyk cho phép điều này. Những công cụ này rất bổ sung cho DAST và bạn nên sử dụng cả hai. Bằng cách đó, có chức năng quét mã ứng dụng bảo mật 360 độ.  

kết thúc

Bây giờ bạn đã hiểu rõ hơn về command injection trong Python, hãy thử xem. Nếu bạn là người mới bắt đầu, hãy thực hiện một số Kiểm tra bảo mật ứng dụng tĩnh đối với một số mã bạn đã viết gần đây và xem mức độ hiệu quả của bạn. Đối với những người dùng cao cấp hơn, hãy chọn một công cụ kiểm tra bảo mật ứng dụng tự động và tìm hiểu về nó. StackHawk cung cấp gói miễn phí với số lần quét và môi trường không giới hạn mà bạn có thể sử dụng. Hy vọng rằng điều này sẽ thêm một số trưởng thành cho các dự án của bạn.  

Bài đăng này được viết bởi Boris Bambo. Boris là một kỹ sư phụ trợ đam mê các ứng dụng hỗ trợ đám mây và thích sử dụng công nghệ để biến ý tưởng thành hiện thực

Shell True trong quy trình con Python là gì?

Việc đặt đối số hệ vỏ thành giá trị thực khiến quy trình con sinh ra một quy trình hệ vỏ trung gian và yêu cầu nó chạy lệnh . Nói cách khác, sử dụng trình bao trung gian có nghĩa là các biến, mẫu hình cầu và các tính năng trình bao đặc biệt khác trong chuỗi lệnh được xử lý trước khi lệnh được chạy.

preexec_fn là gì?

preexec_fn là hàm được gọi trước khi phần tử con bắt đầu . universal_newlines mở đầu vào và đầu ra của trẻ bằng tính năng xuống dòng chung của Python.

Hệ điều hành Popen là gì?

Phương thức Python popen[] mở một đường dẫn đến hoặc từ lệnh . Giá trị trả về là một đối tượng tệp mở được kết nối với đường ống, có thể đọc hoặc ghi tùy thuộc vào chế độ là 'r' [mặc định] hay 'w'.

Quy trình con trong Python là gì?

Quy trình con trong Python là mô-đun được sử dụng để chạy mã và ứng dụng mới bằng cách tạo quy trình mới . Nó cho phép bạn bắt đầu các ứng dụng mới ngay từ chương trình Python mà bạn hiện đang viết. Vì vậy, nếu bạn muốn chạy các chương trình bên ngoài từ kho lưu trữ git hoặc mã từ chương trình C hoặc C++, bạn có thể sử dụng quy trình con trong Python.

Chủ Đề