Tại sao chính phủ Hoa Kỳ không cho phép các ngôn ngữ động cho các dự án an toàn?


120

Tôi biết một số người hiện đang làm việc trong một dự án cho quân đội Hoa Kỳ (mức độ bảo mật thấp, dữ liệu loại nhân lực không chiến đấu).

Một trạng thái ban đầu của mã dự án đã được gửi cho quân đội để xem xét và họ đã chạy chương trình thông qua một số công cụ phân tích bảo mật. Nó đã trả về một báo cáo về các vấn đề bảo mật đã biết trong mã và yêu cầu thay đổi cần được thực hiện trước khi giao sản phẩm cuối cùng.

Một trong những mục cần giải quyết là loại bỏ một phần của dự án được viết bằng Ruby vì đây là một ngôn ngữ động.

Bối cảnh / lý do không cho phép sử dụng ngôn ngữ động trong cài đặt an toàn là gì? Đây có phải là chính phủ chậm được áp dụng công nghệ mới? Hoặc các ngôn ngữ động có gây ra rủi ro bảo mật bổ sung so với các ngôn ngữ tĩnh (ala C ++ hoặc Java ) không?


56
Cách duy nhất để biết chắc chắn là nếu người quen của bạn hỏi nhà tuyển dụng của họ cho lý do. Nhưng tôi có thể mạo hiểm đoán: kiểm tra kiểu tĩnh là một lớp khác giúp tính chính xác của phần mềm quan trọng. Tất nhiên, nó sẽ không thoát khỏi lỗi, nhưng đó là một bước đi đúng hướng: máy tính đang thực hiện một số công việc cho bạn. (Vâng, tôi biết đây là lãnh thổ chiến tranh thánh).
Andres F.


75
Bạn không muốn phần mềm điều khiển tên lửa được viết bằng PHP + JavaScript.
Tulains Córdova

16
Dữ liệu nhân sự không phải là "mức độ bảo mật thấp". Tôi hy vọng một công ty sẽ giữ an toàn cho việc làm và dữ liệu cá nhân của tôi.
gbjbaanb

5
@gbjbaanb Tôi đoán OP có nghĩa là mất mạng không phải là trường hợp xấu nhất ở đây.
Andres F.

Câu trả lời:


126

Có một số điều 'gọn gàng' có thể được thực hiện bằng các ngôn ngữ động có thể được giấu trong các phần của mã không rõ ràng ngay lập tức đối với một lập trình viên hoặc kiểm toán viên khác về chức năng của một đoạn mã nhất định.

Xem xét chuỗi này trong irb (vỏ ruby ​​tương tác):

irb(main):001:0> "bar".foo
NoMethodError: undefined method `foo' for "bar":String
        from (irb):1
        from /usr/bin/irb:12:in `<main>'
irb(main):002:0> class String
irb(main):003:1> def foo
irb(main):004:2> "foobar!"
irb(main):005:2> end
irb(main):006:1> end
=> nil
irb(main):007:0> "bar".foo
=> "foobar!"

Điều gì đã xảy ra là tôi đã cố gắng gọi phương thức footrong hằng chuỗi. Điều này thất bại. Sau đó tôi đã mở lớp String và định nghĩa phương thức fooo return "foobar!", và sau đó gọi nó. Điều này đã làm việc.

Đây được biết đến như một lớp học mở và mang đến cho tôi những cơn ác mộng mỗi khi tôi nghĩ về việc viết mã bằng ruby ​​có bất kỳ loại bảo mật hoặc tính toàn vẹn nào. Chắc chắn rằng nó cho phép bạn thực hiện một số thứ gọn gàng khá nhanh ... nhưng tôi có thể làm nó để mỗi khi ai đó lưu trữ một chuỗi, nó sẽ lưu nó vào một tệp hoặc gửi nó qua mạng. Và một chút định nghĩa lại Chuỗi này có thể được giấu ở bất cứ đâu trong mã.

Nhiều ngôn ngữ động khác có những điều tương tự có thể được thực hiện. Perl có Tie :: Scalar có thể thay đổi cách hoạt động của một vô hướng cụ thể (điều này rõ ràng hơn một chút và yêu cầu một lệnh cụ thể mà bạn có thể nhìn thấy, nhưng một vô hướng được truyền từ một nơi khác có thể là một vấn đề). Nếu bạn có quyền truy cập vào Perl Cookbook, hãy tìm Recipe 13.15 - Tạo các biến ma thuật bằng cà vạt.

Do những điều này (và những thứ khác thường là một phần của ngôn ngữ động), nhiều cách tiếp cận để phân tích tĩnh về bảo mật trong mã không hoạt động. Perl và Undecidability cho thấy đây là trường hợp và chỉ ra ngay cả những vấn đề tầm thường như vậy với việc làm nổi bật cú pháp ( whatever / 25 ; # / ; die "this dies!";đặt ra thách thức bởi vì whatevercó thể được định nghĩa để lấy đối số hoặc không trong thời gian chạy đánh bại hoàn toàn bộ phân tích cú pháp hoặc bộ phân tích tĩnh).


Điều này thậm chí còn thú vị hơn với Ruby với khả năng truy cập vào môi trường mà việc đóng cửa được xác định trong (xem YouTube: Giữ Ruby Reasonable từ RubyConf 2011 của Joshua Ballanco). Tôi đã nhận ra video này từ một bình luận Ars Technica của MouseTheLuckyDog .

Hãy xem xét các mã sau đây:

def mal(&block)
    puts ">:)"
    block.call
    t = block.binding.eval('(self.methods - Object.methods).sample')
    block.binding.eval <<-END
        def #{t.to_s}
          raise 'MWHWAHAW!'
        end
    END
end

class Foo
    def bar
        puts "bar"
    end

    def qux
        mal do
            puts "qux"
        end
    end
end

f = Foo.new
f.bar
f.qux

f.bar
f.qux

Mã này hoàn toàn có thể nhìn thấy, nhưng malphương thức có thể ở một nơi khác ... và với các lớp mở, tất nhiên, nó có thể được định nghĩa lại ở một nơi khác.

Chạy mã này:

~ / $ ruby ​​foo.rb 
quán ba
> :)
qux
quán ba
b.rb: 20: trong `qux ': MWHWAHAW! (Lỗi runtime)
    từ b.rb: 30: trong `'
~ / $ ruby ​​foo.rb 
quán ba
> :)
qux
b.rb: 20: trong 'thanh': MWHWAHAW! (Lỗi runtime)
    từ b.rb: 29: trong `'

Trong mã này, bao đóng có thể truy cập tất cả các phương thức và các ràng buộc khác được định nghĩa trong lớp ở phạm vi đó. Nó chọn một phương thức ngẫu nhiên và xác định lại nó để đưa ra một ngoại lệ. (xem lớp Binding trong Ruby để có ý tưởng về những gì đối tượng này có quyền truy cập)

Các biến, phương thức, giá trị của bản thân và có thể là một khối lặp có thể được truy cập trong ngữ cảnh này đều được giữ lại.

Một phiên bản ngắn hơn cho thấy định nghĩa lại của một biến:

def mal(&block)
    block.call
    block.binding.eval('a = 43')
end

a = 42
puts a
mal do 
  puts 1
end
puts a

Mà, khi chạy sản xuất:

42
1
43

Điều này còn hơn cả lớp mở mà tôi đã đề cập ở trên khiến cho việc phân tích tĩnh không thể thực hiện được. Điều được chứng minh ở trên là một bao đóng được chuyển qua một nơi khác, mang trong nó toàn bộ môi trường mà nó được định nghĩa. Đây được gọi là môi trường hạng nhất (giống như khi bạn có thể chuyển qua các hàm, chúng là các hàm hạng nhất, đây là môi trường và tất cả các ràng buộc có sẵn tại thời điểm đó). Người ta có thể định nghĩa lại bất kỳ biến nào được xác định trong phạm vi đóng.

Tốt hay xấu, phàn nàn về ruby ​​hay không (có những cách sử dụng mà người ta muốn có thể có được ở môi trường của một phương thức (xem Safe in Perl)), câu hỏi "tại sao ruby ​​sẽ bị hạn chế trong một dự án của chính phủ "Thực sự được trả lời trong video đó được liên kết ở trên.

Cho rằng:

  1. Ruby cho phép một người trích xuất môi trường từ bất kỳ đóng cửa
  2. Ruby nắm bắt tất cả các ràng buộc trong phạm vi đóng cửa
  3. Ruby duy trì tất cả các ràng buộc như sống và biến đổi
  4. Ruby có các ràng buộc mới phủ bóng các ràng buộc cũ (thay vì nhân bản môi trường hoặc cấm rebinding)

Với ý nghĩa của bốn lựa chọn thiết kế này, không thể biết bất kỳ bit mã nào làm gì.

Thông tin thêm về điều này có thể được đọc tại blog Tóm tắt Heresies . Bài đăng cụ thể là về Đề án nơi đã có một cuộc tranh luận như vậy. (liên quan đến SO: Tại sao Scheme không hỗ trợ môi trường hạng nhất? )

Tuy nhiên, theo thời gian, tôi nhận ra rằng có nhiều khó khăn hơn và ít sức mạnh hơn với môi trường hạng nhất so với tôi nghĩ ban đầu. Tại thời điểm này tôi tin rằng môi trường hạng nhất là vô dụng và nguy hiểm nhất là tồi tệ nhất.

Tôi hy vọng phần này cho thấy khía cạnh nguy hiểm của môi trường hạng nhất và lý do tại sao nó sẽ được yêu cầu loại bỏ Ruby khỏi giải pháp được cung cấp. Ruby không chỉ là một ngôn ngữ động (như đã trả lời khác, các ngôn ngữ động khác đã được cho phép trong các dự án khác), nhưng có những vấn đề cụ thể khiến một số ngôn ngữ động thậm chí còn khó giải thích hơn.


3
Tôi không hiểu ý của vấn đề này. Bạn đề cập đến một lớp Perl cho phép thay đổi hành vi của vô hướng. Tuy nhiên, Perl được sử dụng rộng rãi, kể cả trong môi trường an toàn. Đơn giản chỉ cần có những khả năng này trong ngôn ngữ không có nghĩa là ngôn ngữ không thể được sử dụng. Trong trường hợp cụ thể của Ruby, có khả năng môi trường đích không hỗ trợ Ruby. Cá nhân tôi chưa bao giờ thấy Ruby có sẵn để sử dụng trên bất kỳ hệ thống nào và tôi thậm chí không chắc nó có trong bất kỳ danh sách phần mềm nào được phê duyệt hay không.
Thomas Owens

17
@ThomasOwens - Sự hiểu biết của tôi về câu trả lời này là chìa khóa "many approaches to static analysis of security in code doesn't work", vì vậy nó bị từ chối vì không thể phân tích được (ít nhất là bởi nhóm này). Cho dù tôi đang giải thích nó đúng hay thậm chí đó là lý do hợp lệ để từ chối nó, tôi không biết.
Bobson

21
Thiếu thông tin về danh sách phần mềm được phê duyệt, tôi chỉ có thể đoán được những khó khăn với ngôn ngữ động. Tuy nhiên, tôi đã thấy các vấn đề tương tự với phần mềm tài chính và kiểm tra ngành thẻ thanh toán không thành công vì ngôn ngữ không thể có phân tích tĩnh được xử lý trước về vấn đề bảo mật. Tôi đã chứng minh hai ví dụ trong các ngôn ngữ động trong đó bản chất của ngôn ngữ cho phép nó lật đổ phân tích tĩnh. Tôi cũng chỉ ra lý do tại sao điều này, thậm chí về mặt lý thuyết, không bao giờ có thể chính xác. Nó có thể là perl được cho phép ở một số nơi chứ không phải những nơi khác, tôi chỉ có thể đoán như lý do.

2
Bạn cũng có thể xác định lại các chức năng thư viện tiêu chuẩn bằng nhiều ngôn ngữ khác (ví dụ Obj-C, C, C ++).
Martin Wickman

12
Vâng, các phương thức mở rộng .NET KHÔNG giống như Ruby ở trên. Họ chỉ tạo ra một cách dễ dàng hơn để gõ một lớp tĩnh. Họ không thực sự thêm một phương thức vào một lớp.
Graham

50

Giả sử đánh giá là chỉ bảo mật và không chỉ là quét chấp nhận (nghĩa là họ không chấp nhận Ruby vì họ không muốn hỗ trợ Ruby):

Các công cụ phân tích bảo mật thường có một thời gian xấu với các hành vi năng động.

Ví dụ:

Chạy bất kỳ dự án .NET nào được viết bằng các tính năng hiện đại như ASP.NET MVCEntity Framework thông qua một cái gì đó như Veracode và xem loại danh sách giặt giả nào bạn nhận được trong báo cáo của mình.

Veracode thậm chí liệt kê nhiều kỹ thuật cơ bản trong các thư viện lõi .NET 4 là "các khung không được hỗ trợ" là không được hỗ trợ hoặc chỉ beta mặc dù hầu hết chúng đều đã vài năm tuổi.

Nếu bạn đang làm việc với một thực thể có sự phụ thuộc mạnh mẽ vào một công cụ như vậy, họ gần như bị buộc phải xem xét những điều không an toàn đó nếu họ không có chuyên môn kỹ thuật và tài nguyên, để đánh giá thủ công một dự án và xem liệu nó có được viết đúng không và đảm bảo.

Trong các hoạt động dân sự nơi các hệ thống máy tính thường không kiểm soát bất cứ điều gì nguy hiểm hoặc cực kỳ tốn kém, việc giảm thiểu là bạn thảo luận về các mặt tích cực giả và chúng thường được chấp nhận như vậy với số lượng lớn.

Trong hoạt động ngân hàng, bạn vẫn có cơ hội giảm thiểu dương tính giả, nhưng bạn sẽ dành nhiều thời gian hơn để thảo luận về các chi tiết vụn vặt của từng mặt hàng. Điều này nhanh chóng trở thành chi phí cấm và bạn bắt đầu sử dụng các phương pháp truyền thống hơn.

Trong quân đội, hàng không, công nghiệp nặng và tương tự, các hệ thống có thể kiểm soát những thứ có chế độ thất bại khủng khiếp đó để chúng có thể có các quy tắc rất nghiêm ngặt về ngôn ngữ, trình biên dịch, v.v.

Các tổ chức cũng thường viết chính sách bảo mật của họ cho trường hợp xấu nhất mà họ biết, vì vậy ngay cả khi bạn đang viết một cái gì đó tầm thường, nếu bạn đang viết nó cho một tổ chức có hệ thống không tầm thường, thì mặc định thường sẽ giữ nó một tiêu chuẩn cao hơn trừ khi ai đó yêu cầu một ngoại lệ cụ thể.


4
Và đó chỉ là những mặt tích cực giả. Điều thực sự đáng lo ngại là tiềm năng cho những tiêu cực giả.
Stephen C

3
Thành thật mà nói, kinh nghiệm của tôi với các công cụ này nói chung là khủng khiếp. Có lẽ một cái gì đó dọc theo tỷ lệ 1/200 đến 1/1000 của việc tìm kiếm một cái gì đó thực sự đáng để thảo luận. Ngoài ra, khi tôi nhận được một dương tính giả mà tôi biết là thứ gì đó được sử dụng trong hàng ngàn điểm trong cơ sở mã hoặc khung và nó chỉ xác định được một vài lần tôi không thực sự tin tưởng. Vấn đề là bạn đang triển khai một cách hiệu quả bằng chứng phủ định khi bạn xây dựng một trong những công cụ này trừ khi bạn bắt đầu với một ngôn ngữ chính thức như spec #.
Hóa đơn

33

Ngôn ngữ động có thể được sử dụng trong các ứng dụng quốc phòng và quân sự. Cá nhân tôi đã sử dụng và phân phối Perl và Python trong các ứng dụng DoD. Tôi cũng đã thấy PHP và JavaScript được sử dụng và triển khai. Theo kinh nghiệm của tôi, hầu hết các mã không được biên dịch mà tôi đã thấy là các tập lệnh shell và Perl vì các môi trường cần thiết được phê duyệt và cài đặt trên nhiều hệ thống đích có thể.

Thực tế là các ngôn ngữ này rất năng động không phải là vấn đề. Thông dịch viên cho các ngôn ngữ này phải được phê duyệt để sử dụng trên các hệ thống đích. Nếu trình thông dịch không được phê duyệt để sử dụng (hoặc, có lẽ, nhưng nó không được triển khai trên các hệ thống đích), thì ngôn ngữ không thể được sử dụng. Sử dụng một trình thông dịch nhất định (hoặc bất kỳ ứng dụng nào) trên hệ thống bảo mật yêu cầu bất kỳ số rào cản bảo mật nào: phân tích nguồn, khả năng biên dịch từ nguồn cho môi trường đích, phân tích bổ sung các nhị phân, đảm bảo không có xung đột với cơ sở hạ tầng hiện có, v.v.


32

Tôi đã dành một chút thời gian để phỏng vấn với Bộ Quốc phòng (Bộ Quốc phòng), cho một vị trí viết mã cho MMU của F-16 . Không vi phạm bất kỳ tiết lộ nào: MMU là đơn vị máy tính điều khiển gần như tất cả các chức năng của F-16. Rõ ràng là không có lỗi nào, chẳng hạn như lỗi thời gian chạy, xảy ra trong chuyến bay. Điều quan trọng không kém là hệ thống thực hiện các hoạt động điện toán thời gian thực.

Vì lý do này và các lý do lịch sử khác, tất cả mã cho hệ thống này được viết hoặc biên dịch sang ADA, một ngôn ngữ lập trình hướng đối tượng tĩnh .

Do các tính năng hỗ trợ quan trọng về an toàn của Ada, giờ đây nó không chỉ được sử dụng cho các ứng dụng quân sự mà còn trong các dự án thương mại nơi lỗi phần mềm có thể gây hậu quả nghiêm trọng, ví dụ như hệ thống điện tử hàng không và kiểm soát không lưu, tên lửa thương mại (ví dụ Ariane 4 và 5), vệ tinh và các hệ thống không gian khác, vận tải đường sắt và ngân hàng. Ví dụ, phần mềm hệ thống fly-by-wire trong Boeing 777 được viết bằng Ada.

Tôi ghét trích dẫn quá nhiều, nhưng điều này giải thích rất rõ tại sao chính xác các ngôn ngữ tĩnh (như ADA) được sử dụng cho các dự án như thế này:

Một số lượng lớn kiểm tra thời gian biên dịch được hỗ trợ để giúp tránh các lỗi không thể phát hiện được cho đến khi hết thời gian trong một số ngôn ngữ khác hoặc sẽ yêu cầu kiểm tra rõ ràng được thêm vào mã nguồn. Ví dụ: cú pháp yêu cầu đóng các khối được đặt tên rõ ràng để ngăn lỗi do các mã thông báo kết thúc không khớp. Việc tuân thủ gõ mạnh cho phép phát hiện nhiều lỗi phần mềm phổ biến (tham số sai, vi phạm phạm vi, tham chiếu không hợp lệ, loại không khớp, v.v.) trong thời gian biên dịch hoặc trong thời gian chạy. Vì đồng thời là một phần của đặc tả ngôn ngữ, trong một số trường hợp, trình biên dịch có thể phát hiện các bế tắc tiềm ẩn. Trình biên dịch cũng thường kiểm tra các định danh sai chính tả, khả năng hiển thị của các gói, khai báo dự phòng, v.v. và có thể cung cấp các cảnh báo và đề xuất hữu ích về cách sửa lỗi.

Ada cũng hỗ trợ kiểm tra thời gian chạy để bảo vệ chống truy cập vào bộ nhớ chưa được phân bổ, lỗi tràn bộ đệm, vi phạm phạm vi, lỗi tắt, lỗi truy cập mảng và các lỗi có thể phát hiện khác. Các kiểm tra này có thể bị vô hiệu hóa vì lợi ích của hiệu quả thời gian chạy, nhưng thường có thể được biên dịch hiệu quả. Nó cũng bao gồm các cơ sở để giúp xác minh chương trình. Vì những lý do này, Ada được sử dụng rộng rãi trong các hệ thống quan trọng, trong đó bất kỳ sự bất thường nào cũng có thể dẫn đến hậu quả rất nghiêm trọng, ví dụ như tử vong do tai nạn, thương tích hoặc tổn thất tài chính nghiêm trọng. Ví dụ về các hệ thống sử dụng Ada bao gồm hệ thống điện tử hàng không, đường sắt, ngân hàng, quân sự và công nghệ vũ trụ.

Quản lý bộ nhớ động của Ada là cấp độ cao và an toàn. Ada không có "con trỏ" chung chung (và mơ hồ); Nó cũng không ngầm tuyên bố bất kỳ loại con trỏ. Thay vào đó, tất cả việc cấp phát và phân bổ bộ nhớ động phải diễn ra thông qua các loại truy cập được khai báo rõ ràng. Mỗi loại truy cập có một nhóm lưu trữ liên quan xử lý các chi tiết cấp thấp của quản lý bộ nhớ; lập trình viên có thể sử dụng nhóm lưu trữ mặc định hoặc xác định nhóm lưu trữ mới (điều này đặc biệt phù hợp với Truy cập bộ nhớ không đồng nhất). Thậm chí có thể khai báo một số loại truy cập khác nhau mà tất cả chỉ định cùng loại nhưng sử dụng các nhóm lưu trữ khác nhau. Ngoài ra, ngôn ngữ cung cấp cho kiểm tra khả năng truy cập, cả về thời gian biên dịch và thời gian chạy, đảm bảo rằng giá trị truy cập không thể tồn tại lâu hơn loại đối tượng mà nó trỏ đến.


3
Vì các tính năng hỗ trợ quan trọng về an toàn của Ada, giờ đây nó đã được sử dụng trong các tên lửa thương mại (ví dụ Ariane 4 và 5) , dĩ nhiên Ariane 5 đầu tiên phát nổ do lỗi phần mềm , do đó không có viên đạn bạc.
Andrew Marshall

5
@AndrewMarshall: "Mặc dù báo cáo xác định lỗi phần mềm là nguyên nhân trực tiếp, các nhà điều tra khác xem nguyên nhân là do lỗi thiết kế hệ thống và các vấn đề quản lý" - Tôi thực sự nghi ngờ rằng mã được viết bằng ngôn ngữ khác (ví dụ Java hoặc C ++) sẽ nhận được tên lửa lên quỹ đạo.
Martin Schröder

@ MartinSchröder Oh Tôi không nghi ngờ rằng Ada vẫn có khả năng vượt trội so với những người khác cho ứng dụng này, chỉ lưu ý rằng nó không phải là bằng chứng ngu ngốc. Một ngôn ngữ khác có thể đã vượt qua vô số lỗi mà Ada không thể có được.
Andrew Marshall

13

Cả DoD và NASA đều có một lịch sử lâu dài với việc lập trình thất bại khiến họ phải trả hàng tỷ đô la. Cả hai tổ chức đã chấp nhận các quy trình sẽ bảo vệ họ khỏi lặp lại sai lầm tương tự.

Is this the government being slow to adopting new technologies?

Đây là một quan niệm sai lầm - ngôn ngữ động không phải là một công nghệ mới, chúng khá cũ. Vấn đề là nếu bạn từng gặp vấn đề do ngôn ngữ động gây ra (ví dụ do gõ yếu / động) và vấn đề đó khiến bạn tốn rất nhiều tiền, bạn có thể chấp nhận chính sách ngăn bạn mắc lại lỗi tương tự - ví dụ: cấm sử dụng các ngôn ngữ động trong các hệ thống nhạy cảm.

Các ngôn ngữ động thường sẽ "nuốt" các lỗi và sẽ kết thúc với một số hành vi không mong muốn. Điều này rất nguy hiểm trong các hệ thống nhạy cảm. Nếu một cái gì đó sai đang xảy ra, bạn muốn biết nó càng sớm càng tốt.

Nếu bảo mật có liên quan, cần phải xem trường hợp sử dụng thực tế. Ví dụ: tôi không nghĩ rằng trang web Ruby on Rails sẽ tự động kém an toàn hơn trang web Java.


2
IMHO nhiều lỗi đã bị "nuốt chửng" bởi bộ đệm không bị phát hiện tràn hơn bất kỳ thứ gì khác, đó chính xác là điều mà hầu hết các ngôn ngữ động sẽ không cho phép ở nơi đầu tiên ... chỉ cần nói
miraculixx

@miraculixx Đúng, có một lý do tại sao Java / C # và các ngôn ngữ tương tự đang được sử dụng nhiều hơn Ruby. Họ phòng thủ - họ kiểm tra mọi thứ. Trong C / C ++, khả năng phòng thủ có thể được thực thi bằng cách sử dụng một tiêu chuẩn mã hóa tốt. Bạn cũng có thể thực thi kiểm tra cho tất cả mọi thứ. Nhưng bạn có thể tưởng tượng việc viết một ứng dụng nhạy cảm trong ruby ​​hoặc javascript không? Khả năng cho các lỗi ẩn là rất lớn.
Sulthan

Thật vậy, tôi có thể. Chúng tôi có thể đồng ý rằng phần mềm cần phải được kiểm tra kỹ lưỡng, độc lập với ngôn ngữ lập trình. Để tránh hồi quy, kiểm tra được tự động hóa tốt nhất bằng cách sử dụng thử nghiệm đơn vị, BDD et al. Giả định một cách tiếp cận chuyên nghiệp (ứng dụng nhạy cảm, phải không?), Đạt được phạm vi kiểm tra đầy đủ là một quy trình được quản lý, không để lại cơ hội. Cùng với đó, tôi nghi ngờ rằng C / C ++, Java có lợi thế hơn so với ruby ​​hoặc javascript về các lỗi ẩn. Kỹ năng lập trình viên? Có khả năng kỹ thuật hơn với C ++, nghi ngờ với Java, nhưng hầu như không phải là vấn đề ngôn ngữ. Thêm kỹ thuật! = Chất lượng sản phẩm.
miraculixx

6

Tôi muốn thêm vào các câu trả lời hiện có bằng cách mô tả SA-CORE-2014-005 của Drupal , đây là một lỗ hổng rất nghiêm trọng cho phép tiêm SQL và cuối cùng là thực thi mã tùy ý. Nó được gây ra bởi các quy tắc gõ động và gõ lỏng lẻo của PHP.

Toàn bộ bản vá cho vấn đề này là:

-      foreach ($data as $i => $value) {
+      foreach (array_values($data) as $i => $value) {

Mã này là một phần của lớp trừu tượng SQL được thiết kế để ngăn chặn việc tiêm SQL. Nó nhận một truy vấn SQL với các tham số được đặt tên và một mảng kết hợp cung cấp một giá trị cho mỗi tham số được đặt tên. Giá trị được phép là một mảng, trong các trường hợp như WHERE x IN (val1, val2, val3), trong đó cả ba giá trị có thể được truyền vào dưới dạng một giá trị mảng cho một tham số có tên duy nhất.

Lỗ hổng xảy ra vì mã giả định rằng $itrong $i => $valuephải là một chỉ số nguyên của giá trị. Nó tiếp tục và nối trực tiếp "chỉ mục" này vào truy vấn SQL như một phần của tên tham số, bởi vì các số nguyên không cần bất kỳ thoát nào, phải không?

Thật không may cho Drupal, PHP không cung cấp một sự đảm bảo như vậy. Bạn có thể chuyển vào một mảng kết hợp khác, có các khóa là các chuỗi và vòng lặp này sẽ vui vẻ nối chuỗi khóa vào truy vấn, như vậy (hãy nhớ rằng mã nghĩ rằng nó chỉ có thể là một số nguyên).

Mặc dù có nhiều cách để có một lỗi tương tự trong một ngôn ngữ gõ tĩnh, nhưng chúng không có khả năng. Một nhà phát triển giỏi sẽ xem xét những gì có $ithể có trước khi kết hợp nó vào truy vấn. Với một ngôn ngữ được nhập tĩnh, rất dễ thực thi $iphải là một số nguyên và trong mã nhạy cảm bảo mật như thế này, điều đó chắc chắn sẽ được thực hiện.

Hơn nữa, mã thực sự kiểm tra xem giá trị có phải là một mảng hay không trước khi lặp qua các mục. Và đây là một phần thứ hai của sự thất bại cho phép lỗ hổng này: cả mảng kết hợp và mảng "bình thường" đều trả về đúng is_array. Mặc dù trong C #, cả từ điển và mảng đều đúng IEnumerable, rất khó để xây dựng mã có thể kết hợp các khóa từ điển với các chỉ số mảng như thế này thậm chí là vô tình.


2

Việc một cơ sở mã có an toàn hay không phụ thuộc vào cách bạn viết mã, cách bạn kiểm tra mã và cách bạn xác nhận và giám sát quá trình phát triển và triển khai của mình. Ngôn ngữ không an toàn cũng không an toàn, đó là cách bạn viết mã.

Phần lớn các sự cố bảo mật do đầu vào độc hại (tiêm sql, tràn bộ đệm), vi rút, rootkit và trojan. Không có ngôn ngữ có thể bảo vệ bạn khỏi điều đó.

Vì vậy, việc cấm các lớp ngôn ngữ là "không an toàn" không phải là một lý do hợp lệ.

Tôi nghi ngờ rằng ai đó, vì bất kỳ lý do gì - có thông báo hay không - đã quyết định cấm các ngôn ngữ này. Sau một thời gian nó đã trở thành một sự thật tổ chức . Có thể đúng vào thời điểm đó đối với một số dự án, nhưng các nền văn hóa kiểm soát không quan tâm đến việc thay đổi quyết định (thừa nhận họ đã sai) và thích các quy tắc đơn giản. Họ phát triển mạnh về các quy tắc và quy định và không quan trọng họ có ý nghĩa hay không, đó là sự an toàn được nhận thức .

Điều này xảy ra tất cả các thời gian trong nền văn hóa kiểm soát. Tôi thấy nó ít nhiều hàng ngày. Nó không có ý nghĩa, nhưng đó là cách nó đi. Nếu bạn muốn đọc thêm về chủ đề rất phù hợp này, tôi khuyên bạn nên đọc cuốn sách " Phương án tái cấu trúc " của Schneider . Đây là sơ đồ văn hóa của Michael Sahoto / Agilitrix , dựa trên cuốn sách của Schneider: nhập mô tả hình ảnh ở đây


18
-1 Có nhiều lý do kỹ thuật hợp lệ tại sao một ngôn ngữ sẽ được chọn trên một ngôn ngữ khác (kiểm tra thời gian thực, gõ tĩnh, kiểm tra thời gian chạy) cho các hệ thống quan trọng an toàn. Bạn ngụ ý rằng các lý do là văn hóa 100%, chúng tôi so với chúng và tùy ý, mà IMO hoàn toàn không chính xác trong trường hợp này.
Michael Jasper

8
"Ngôn ngữ là không an toàn hoặc không an toàn" - xem stackoverflow.com/a/14313277/602554 . Một số ngôn ngữ chắc chắn là "an toàn" hơn những ngôn ngữ khác.
Michael Jasper

2
Cập nhật câu trả lời của tôi, có thể theo ý thích của bạn. Tôi vẫn tin rằng hệ thống an toàn đến mức nào, nó phụ thuộc nhiều vào mã bạn viết hơn ngôn ngữ bạn sử dụng, mặc dù một số ngôn ngữ giúp tránh một số vấn đề nhất định (trong khi, có thể giới thiệu khác).
Martin Wickman

2
@MartinWickman: a) Việc tiêm SQL / HTML và tràn bộ đệm được giải quyết bằng một số hệ thống loại - bạn có các loại khác nhau để nhập và thoát khỏi đầu vào để bạn biết nên xử lý theo cách nào. b) không phải tất cả các vấn đề bảo mật trong 'dự án an toàn' nhất thiết có nghĩa là thỏa hiệp. Tôi không muốn phần mềm chạy máy bay có bất kỳ lỗi nào ngay cả khi đó không phải là vấn đề 'bảo mật' (nghĩa là không thể sử dụng để chiếm quyền hệ thống).
Maciej Piechotka

5
-1 cho các vấn đề chính xác thực tế. Khai thác tràn bộ đệm là một vấn đề đặc biệt cao đối với ngôn ngữ C; bạn không bao giờ nghe về chúng trong các ngôn ngữ không cho phép bạn phân bổ bộ đệm chuỗi trên ngăn xếp. Và hoàn toàn không khó để tưởng tượng một phương ngữ SQL giả định trong đó việc sử dụng Tham số không chỉ đơn giản là cho phép mà là bắt buộc . SQL tiêm sẽ là không thể trong ngôn ngữ này. Vì vậy, có, một ngôn ngữ được thiết kế đúng có thể bảo vệ bạn khỏi một số loại tấn công phổ biến.
Mason Wheeler

2

Theo như tôi có thể nói, chính sách của Bộ Quốc phòng nói chung không cấm các ngôn ngữ động.

Các tiêu chuẩn cho phần mềm do DoD phát triển hoặc mua sắm được Cơ quan Hệ thống Thông tin Quốc phòng (DISA) ban hành . Bảo mật ứng dụng của họ - Hướng dẫn triển khai kỹ thuật bảo mật và bảo mật ứng dụng (STIG) không cấm bất kỳ ngôn ngữ cụ thể nào. Nó không đề cập đến Ruby, nhưng nó đề cập đến Perl và Python có tính năng động tương tự nhau. Nó đề cập đến chúng trong bối cảnh của các chủ đề khác nhau (tuân theo các Tiêu chuẩn mã hóa đã được thiết lập, tránh các lỗ hổng tiêm lệnh, v.v.).

Có lẽ những gì bạn đang thấy là một công cụ quét quá nghiêm ngặt (có một số công cụ khác nhau được đề cập trong STIG, mỗi công cụ có thể có cách giải thích riêng về các quy tắc) và / hoặc diễn giải quá nghiêm ngặt về đầu ra của nó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.