ทำไมรัฐบาลสหรัฐไม่อนุญาตให้ใช้ภาษาแบบไดนามิกสำหรับโครงการที่ปลอดภัย?


120

ฉันรู้ว่าบางคนกำลังทำงานในโครงการสำหรับกองทัพสหรัฐฯ (ระดับความปลอดภัยต่ำข้อมูลประเภททรัพยากรมนุษย์ที่ไม่ต่อสู้)

สถานะเริ่มต้นของรหัสโครงการถูกส่งไปยังทหารเพื่อตรวจสอบและพวกเขาก็เรียกใช้โปรแกรมผ่านเครื่องมือวิเคราะห์ความปลอดภัยบางประเภท จะส่งคืนรายงานปัญหาความปลอดภัยที่ทราบในรหัสและการเปลี่ยนแปลงที่จำเป็นซึ่งจำเป็นต้องนำไปใช้ก่อนส่งมอบผลิตภัณฑ์ขั้นสุดท้าย

หนึ่งในรายการที่จำเป็นต้องได้รับการแก้ไขคือการลบส่วนหนึ่งของโครงการที่เขียนในRubyเนื่องจากเป็นภาษาแบบไดนามิก

พื้นหลัง / เหตุผลในการไม่อนุญาตให้ใช้ภาษาไดนามิกในการตั้งค่าความปลอดภัยคืออะไร นี่เป็นรัฐบาลที่นำเทคโนโลยีใหม่มาใช้ช้าหรือไม่? หรือภาษาไดนามิกมีความเสี่ยงด้านความปลอดภัยเพิ่มเติมเมื่อเทียบกับภาษาแบบคงที่ (ala C ++หรือJava ) หรือไม่


56
วิธีเดียวที่จะทราบได้อย่างแน่นอนคือถ้าคนรู้จักของคุณถามนายจ้างด้วยเหตุผล แต่ฉันอาจเสี่ยงต่อการเดา: การตรวจสอบประเภทคงที่เป็นอีกชั้นหนึ่งที่ช่วยให้ความถูกต้องของซอฟต์แวร์ที่มีความสำคัญต่อภารกิจ แน่นอนว่ามันจะไม่กำจัดข้อผิดพลาด แต่เป็นขั้นตอนในทิศทางที่ถูกต้อง: คอมพิวเตอร์กำลังทำงานให้คุณ (ใช่ฉันรู้ว่านี่เป็นดินแดนสงครามศักดิ์สิทธิ์)
Andres F.

4
อาจเกี่ยวข้อง: williamedwardscoder.tumblr.com/post/42912076785/…
Robert Harvey

75
คุณไม่ต้องการซอฟต์แวร์ควบคุมขีปนาวุธเขียนใน PHP + JavaScript
Tulains Córdova

16
ข้อมูล HR ไม่ใช่ "ระดับความปลอดภัยต่ำ" ฉันคาดหวังว่า บริษัท จะรักษาข้อมูลการจ้างงานและข้อมูลส่วนบุคคลของฉันให้ปลอดภัยที่สุดเท่าที่จะทำได้
gbjbaanb

5
@gbjbaanb ฉันเดาว่า OP หมายถึงการสูญเสียชีวิตไม่ใช่สถานการณ์กรณีที่เลวร้ายที่สุดที่นี่
Andres F.

คำตอบ:


126

มีหลายสิ่งที่ 'เรียบร้อย' ที่สามารถทำได้ในภาษาแบบไดนามิกที่สามารถซ่อนอยู่ในส่วนของรหัสที่ไม่ชัดเจนในทันทีสำหรับโปรแกรมเมอร์หรือผู้ตรวจสอบบัญชีคนอื่น ๆ เกี่ยวกับการทำงานของรหัสที่กำหนด

พิจารณาลำดับนี้ใน irb (เปลือกทับทิมแบบโต้ตอบ):

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!"

เกิดอะไรขึ้นฉันพยายามโทรหาเมธอดfooในค่าคงที่สตริง สิ่งนี้ล้มเหลว ฉันเปิดคลาส String ขึ้นมาแล้วกำหนดเมธอดfooo คืนค่า"foobar!"แล้วเรียกมันว่า สิ่งนี้ใช้ได้ผล

สิ่งนี้เรียกว่าคลาสเปิดและทำให้ฉันฝันร้ายทุกครั้งที่ฉันคิดว่าการเขียนโค้ดด้วยทับทิมซึ่งมีความปลอดภัยหรือความสมบูรณ์แบบใด ๆ แน่นอนว่ามันช่วยให้คุณทำสิ่งต่าง ๆ ได้อย่างรวดเร็ว ... แต่ฉันสามารถทำให้มันทุกครั้งที่มีคนเก็บสายมันเก็บไว้ในไฟล์หรือส่งมันผ่านเครือข่าย และการนิยามใหม่ของ String เล็กน้อยนี้สามารถซ่อนไว้ที่ใดก็ได้ในรหัส

ภาษาไดนามิกอื่น ๆ อีกมากมายมีสิ่งที่คล้ายกันที่สามารถทำได้ Perl มีเน็คไท :: สเกลาร์ที่อยู่เบื้องหลังสามารถเปลี่ยนวิธีการทำงานของสเกลาร์ได้ (นี่ค่อนข้างชัดเจนและต้องใช้คำสั่งเฉพาะที่คุณสามารถเห็นได้ แต่สเกลาร์ที่ผ่านเข้ามาจากที่อื่นอาจเป็นปัญหา) หากคุณสามารถเข้าถึง Perl Cookbook ได้ให้ค้นหาสูตร 13.15 - การสร้างตัวแปรวิเศษพร้อมเน็คไท

เนื่องจากสิ่งเหล่านี้ (และอื่น ๆ มักเป็นส่วนหนึ่งของภาษาแบบไดนามิก) หลายวิธีในการวิเคราะห์แบบคงที่ของการรักษาความปลอดภัยในรหัสไม่ทำงาน Perl และ Undecidabilityแสดงให้เห็นว่านี่เป็นกรณีและชี้ให้เห็นแม้ปัญหาเล็กน้อยกับการเน้นไวยากรณ์ ( whatever / 25 ; # / ; die "this dies!";poses ความท้าทายเพราะwhateverสามารถกำหนดให้ใช้อาร์กิวเมนต์หรือไม่ที่รันไทม์อย่างสมบูรณ์เอาชนะไฮไลท์ไวยากรณ์หรือวิเคราะห์แบบคงที่)


สิ่งนี้จะน่าสนใจยิ่งขึ้นใน Ruby ด้วยความสามารถในการเข้าถึงสภาพแวดล้อมที่กำหนดไว้ในการปิด (ดูYouTube: การรักษา Ruby ที่เหมาะสมจาก RubyConf 2011 โดย Joshua Ballanco) ผมก็เกิดความตระหนักในวิดีโอนี้จากความคิดเห็น Ars Technica โดย MouseTheLuckyDog

พิจารณารหัสต่อไปนี้:

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

รหัสนี้สามารถมองเห็นได้อย่างสมบูรณ์ แต่malวิธีการอาจเป็นที่อื่น ... และด้วยคลาสที่เปิดแน่นอนว่ามันสามารถนิยามใหม่ได้ที่อื่น

ใช้รหัสนี้:

~ / $ ruby ​​foo.rb 
บาร์
> :)
qux
บาร์
b.rb: 20: ใน `qux ': MWHWAHAW! (การทำงานผิดพลาด)
    จาก b.rb: 30: ใน `'
~ / $ ruby ​​foo.rb 
บาร์
> :)
qux
b.rb: 20: ใน `บาร์ ': MWHWAHAW! (การทำงานผิดพลาด)
    จาก b.rb: 29: ใน `'

ในรหัสนี้ปิดก็สามารถที่จะเข้าถึงทุกวิธีการและการผูกอื่น ๆ ที่กำหนดไว้ในระดับที่ขอบเขตที่ มันเลือกวิธีการแบบสุ่มและกำหนดใหม่เพื่อเพิ่มข้อยกเว้น (ดูคลาสBindingใน Ruby เพื่อรับทราบว่าวัตถุนี้เข้าถึงอะไรได้บ้าง)

ตัวแปรวิธีการค่าของตัวเองและบล็อกตัววนซ้ำที่สามารถเข้าถึงได้ในบริบทนี้จะถูกเก็บรักษาไว้ทั้งหมด

เวอร์ชันที่สั้นกว่าที่แสดงการกำหนดค่าใหม่ของตัวแปร:

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

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

ซึ่งเมื่อเรียกใช้ผลิต:

42
1
43

นี่เป็นมากกว่าโอเพ่นคลาสที่ฉันกล่าวถึงข้างต้นซึ่งทำให้การวิเคราะห์แบบคงที่เป็นไปไม่ได้ สิ่งที่แสดงให้เห็นข้างต้นคือการปิดที่ถูกส่งไปที่อื่นดำเนินการกับสภาพแวดล้อมแบบเต็มตามที่กำหนดไว้สิ่งนี้เรียกว่าสภาพแวดล้อมระดับเฟิร์สคลาส (เช่นเดียวกับเมื่อคุณสามารถผ่านฟังก์ชันต่างๆได้ นี่คือสภาพแวดล้อมและการเชื่อมโยงทั้งหมดที่มีในเวลานั้น) หนึ่งสามารถกำหนดตัวแปรใด ๆที่กำหนดไว้ในขอบเขตของการปิด

ดีหรือไม่ดีบ่นเกี่ยวกับทับทิมหรือไม่ (มีการใช้งานที่ใคร ๆ ก็ต้องการที่จะได้รับในสภาพแวดล้อมของวิธีการ (ดูปลอดภัยใน Perl)) คำถาม "ทำไมทับทิมจะถูก จำกัด ในโครงการของรัฐบาล "ได้รับคำตอบจริงๆในวิดีโอที่ลิงก์ด้านบน

ระบุว่า:

  1. ทับทิมอนุญาตให้หนึ่งแยกสภาพแวดล้อมจากการปิดใด ๆ
  2. Ruby รวบรวมการเชื่อมทั้งหมดในขอบเขตของการปิด
  3. Ruby รักษาการเชื่อมโยงทั้งหมดเป็นแบบสดและไม่แน่นอน
  4. Ruby มีการเชื่อมใหม่แบบเงาการเชื่อมแบบเก่า (แทนการโคลนสภาพแวดล้อมหรือการห้ามไม่ให้เชื่อมต่อ)

ด้วยความหมายของตัวเลือกการออกแบบทั้งสี่นี้จึงเป็นไปไม่ได้ที่จะรู้ว่าโค้ดใดบ้างที่ทำ

เพิ่มเติมเกี่ยวกับเรื่องนี้สามารถอ่านได้ที่บทคัดย่อนอกรีตบล็อก โพสต์เฉพาะเป็นเรื่องเกี่ยวกับโครงการที่มีการอภิปรายดังกล่าว (เกี่ยวข้องกับ SO: ทำไม Scheme ถึงไม่สนับสนุนสภาพแวดล้อมระดับเฟิร์สคลาส )

อย่างไรก็ตามเมื่อเวลาผ่านไปฉันก็ตระหนักว่ามีความยากลำบากมากขึ้นและใช้พลังงานน้อยลงในสภาพแวดล้อมระดับเฟิร์สคลาสกว่าที่ฉันคิดไว้ ณ จุดนี้ฉันเชื่อว่าสภาพแวดล้อมระดับเฟิร์สคลาสนั้นไร้ประโยชน์ที่สุดและอันตรายที่สุด

ฉันหวังว่าส่วนนี้แสดงให้เห็นถึงแง่มุมที่เป็นอันตรายของสภาพแวดล้อมชั้นหนึ่งและทำไมมันจะถูกขอให้ลบทับทิมออกจากโซลูชั่นที่ให้ไว้ ไม่ใช่แค่ว่า Ruby เป็นภาษาไดนามิก (ดังที่ได้กล่าวไว้อีกคำตอบภาษาไดนามิกอื่น ๆ ได้รับอนุญาตในโครงการอื่น ๆ ) แต่มีปัญหาเฉพาะที่ทำให้บางภาษาไดนามิกยิ่งยากที่จะให้เหตุผล


3
ฉันไม่เข้าใจประเด็นนี้ คุณพูดถึงคลาส Perl ที่อนุญาตให้เปลี่ยนพฤติกรรมของสเกลาร์ อย่างไรก็ตาม Perl ใช้กันอย่างแพร่หลายรวมถึงในสภาพแวดล้อมที่ปลอดภัย เพียงแค่มีความสามารถเหล่านี้ในภาษาไม่ได้หมายความว่าไม่สามารถใช้ภาษาได้ ในกรณีเฉพาะของ Ruby อาจเป็นไปได้ว่าสภาพแวดล้อมเป้าหมายไม่สนับสนุน Ruby โดยส่วนตัวฉันไม่เคยเห็น Ruby สำหรับการใช้งานในระบบใด ๆ และฉันก็ไม่แน่ใจด้วยซ้ำว่ามันเป็นรายการซอฟต์แวร์ที่ได้รับการอนุมัติ
Thomas Owens

17
@ThomasOwens - ความเข้าใจของฉันเกี่ยวกับคำตอบนี้คือกุญแจสำคัญ"many approaches to static analysis of security in code doesn't work"ดังนั้นจึงถูกปฏิเสธเนื่องจากไม่สามารถวิเคราะห์ได้ (โดยกลุ่มนี้อย่างน้อย) ไม่ว่าฉันจะตีความถูกต้องหรือว่าเป็นเหตุผลที่ถูกต้องในการปฏิเสธฉันก็ไม่รู้
Bobson

21
ไม่มีข้อมูลเกี่ยวกับรายชื่อซอฟต์แวร์ที่ได้รับการอนุมัติฉันสามารถเดาได้เฉพาะปัญหาเกี่ยวกับภาษาไดนามิก อย่างไรก็ตามฉันพบปัญหาที่คล้ายกันกับซอฟต์แวร์ทางการเงินและการตรวจสอบอุตสาหกรรมบัตรชำระเงินล้มเหลวเนื่องจากภาษาไม่สามารถทำการวิเคราะห์แบบคงที่สำหรับปัญหาด้านความปลอดภัย ฉันสาธิตสองตัวอย่างในภาษาไดนามิกที่ธรรมชาติของภาษาอนุญาตให้ล้มล้างการวิเคราะห์แบบสแตติก ฉันยังชี้ให้เห็นว่าทำไมสิ่งนี้ถึงแม้ว่าในทางทฤษฎีจะไม่ถูกต้อง อาจเป็นได้ว่า Perl อนุญาตในบางสถานที่เท่านั้นและไม่ใช่ที่อื่น ๆ ฉันสามารถเดาได้เฉพาะเหตุผลเท่านั้น

2
คุณสามารถกำหนดฟังก์ชันไลบรารีมาตรฐานในภาษาอื่น ๆ ได้เช่นกัน (เช่น Obj-C, C, C ++)
Martin Wickman

12
วิธีการขยาย. NET นั้นไม่เหมือนกับ Ruby ด้านบน พวกเขาเพียงสร้างวิธีที่ง่ายกว่าในการพิมพ์คลาสแบบสแตติก พวกเขาไม่ได้เพิ่มวิธีการในชั้นเรียนจริง
เกรแฮม

50

สมมติว่าการประเมินผลเป็นเพียงการรักษาความปลอดภัยเท่านั้นไม่ใช่เพียงแค่การสแกนการยอมรับ (กล่าวคือพวกเขาไม่ยอมรับ Ruby เพราะพวกเขาไม่ต้องการสนับสนุน Ruby) จากนั้น:

เครื่องมือการวิเคราะห์ความปลอดภัยมักมีเวลาไม่ดีกับพฤติกรรมแบบไดนามิก

ตัวอย่างเช่น:

เรียกใช้โครงการ. NETใด ๆ ที่เขียนด้วยคุณสมบัติที่ทันสมัยเช่นASP.NET MVCและEntity Frameworkผ่านVeracodeและดูว่ารายการเท็จใดที่คุณได้รับจากรายงานของคุณ

Veracode ยังแสดงรายการเทคนิคพื้นฐานมากมายภายใน. NET 4 core library ว่า "frameworks ที่ไม่สนับสนุน" เป็น unsupported หรือ beta เท่านั้นแม้ว่าส่วนใหญ่จะมีอายุหลายปี ณ จุดนี้

หากคุณกำลังเผชิญกับหน่วยงานที่มีความเชื่อมั่นอย่างสูงต่อเครื่องมือดังกล่าวพวกเขาเกือบถูกบังคับให้พิจารณาสิ่งที่ไม่ปลอดภัยหากพวกเขาไม่มีความเชี่ยวชาญด้านเทคนิคและทรัพยากรเพื่อประเมินโครงการด้วยตนเองและดูว่ามันถูกเขียนอย่างถูกต้องหรือไม่ ปลอดภัย

ในการปฏิบัติการของพลเรือนที่ระบบคอมพิวเตอร์โดยทั่วไปไม่ได้ควบคุมสิ่งที่เป็นอันตรายหรือมีราคาแพงมากการลดหย่อนคือการที่คุณพูดคุยเกี่ยวกับผลบวกที่ผิดพลาดและเป็นที่ยอมรับกันโดยทั่วไป

ในการดำเนินการธนาคารคุณยังคงมีโอกาสที่จะได้รับผลกระทบเชิงบวกอย่างผิด ๆ แต่คุณจะใช้เวลามากขึ้นในการพูดคุยเกี่ยวกับข้อผิดพลาดของแต่ละรายการ สิ่งนี้กลายเป็นสิ่งต้องห้ามอย่างรวดเร็วและคุณเริ่มใช้วิธีการแบบดั้งเดิมมากขึ้น

ในทางทหาร, การบิน, อุตสาหกรรมหนักและอื่น ๆ ระบบสามารถควบคุมสิ่งต่าง ๆ ที่มีความล้มเหลวอย่างรุนแรงในระบบเหล่านั้นดังนั้นพวกเขาจึงอาจมีกฎที่เข้มงวดมากเกี่ยวกับภาษาคอมไพเลอร์และอื่น ๆ

โดยทั่วไปแล้วองค์กรต่าง ๆ จะเขียนนโยบายความปลอดภัยเพื่อกรณีที่เลวร้ายที่สุดที่พวกเขารู้ดังนั้นแม้ว่าคุณจะเขียนอะไรที่ไม่สำคัญถ้าคุณกำลังเขียนให้กับองค์กรที่ไม่มีระบบที่ไม่น่ารำคาญ มาตรฐานที่สูงกว่ายกเว้นบางคนร้องขอข้อยกเว้นเฉพาะ


4
และนั่นเป็นเพียงผลบวกที่ผิดพลาด สิ่งที่น่าเป็นห่วงคือศักยภาพของฟิล์มเนกาทีฟ
สตีเฟนซี

3
จริงๆแล้วประสบการณ์ของฉันกับเครื่องมือเหล่านี้แย่มาก อาจมีบางสิ่งบางอย่างในอัตรา 1/200 ถึง 1/1000 ของการค้นหาสิ่งที่ควรพูดถึง นอกจากนี้เมื่อฉันได้รับค่าบวกผิด ๆ ที่ฉันรู้ว่าเป็นสิ่งที่ใช้ในหลายพันจุดใน codebase หรือกรอบและมันระบุเพียงไม่กี่ครั้งที่ฉันไม่เต็มไปด้วยความมั่นใจ ปัญหาคือคุณกำลังใช้การพิสูจน์เชิงลบอย่างมีประสิทธิภาพเมื่อคุณสร้างหนึ่งในเครื่องมือเหล่านี้เว้นแต่ว่าคุณจะเริ่มด้วยภาษาทางการเช่น spec #
Bill

33

ภาษาไดนามิกสามารถใช้ในการป้องกันและการทหาร ฉันใช้และส่ง Perl และ Python ในแอปพลิเคชัน DoD เป็นการส่วนตัว ฉันเคยเห็น PHP และ JavaScript ที่ใช้และปรับใช้ จากประสบการณ์ของฉันโค้ดที่ไม่ได้รวบรวมส่วนใหญ่ที่ฉันได้เห็นเป็นเชลล์สคริปต์และ Perl เพราะสภาพแวดล้อมที่ต้องการได้รับการอนุมัติและติดตั้งในระบบเป้าหมายที่เป็นไปได้ที่หลากหลาย

ความจริงที่ว่าภาษาเหล่านี้เป็นแบบไดนามิกส่วนใหญ่ไม่ได้เป็นปัญหา ล่ามสำหรับภาษาเหล่านี้จะต้องได้รับอนุมัติให้ใช้กับระบบเป้าหมาย หากล่ามไม่ได้รับการอนุมัติให้ใช้ (หรืออาจเป็น แต่มันไม่ได้ถูกนำไปใช้กับระบบเป้าหมาย) แสดงว่าไม่สามารถใช้ภาษาได้ การใช้ล่ามที่กำหนด (หรือแอปพลิเคชันใด ๆ ) บนระบบความปลอดภัยต้องใช้จำนวนของอุปสรรคการรักษาความปลอดภัยใด ๆ : การวิเคราะห์แหล่งความสามารถในการรวบรวมจากแหล่งที่มาสำหรับสภาพแวดล้อมเป้าหมายการวิเคราะห์เพิ่มเติมของไบนารี


32

ฉันใช้เวลาสัมภาษณ์กับ DOD (กระทรวงกลาโหม) สำหรับรหัสตำแหน่งการเขียนสำหรับF-16 ของ MMU โดยไม่ละเมิดการไม่เปิดเผยข้อมูล: MMU เป็นหน่วยคอมพิวเตอร์ที่ควบคุมฟังก์ชั่นของ F-16 เกือบทั้งหมด เป็นสิ่งสำคัญอย่างยิ่งที่ไม่มีข้อผิดพลาดเช่นข้อบกพร่องในการทำงานเกิดขึ้นระหว่างการบิน มันสำคัญอย่างเท่าเทียมกันที่ระบบดำเนินการคำนวณแบบเรียลไทม์

สำหรับวันนี้และเหตุผลทางประวัติศาสตร์อื่น ๆ ทุกรหัสสำหรับระบบนี้ถูกเขียนในหรือรวบรวมเพื่อADA, เชิงวัตถุภาษาการเขียนโปรแกรมแบบคงที่

เพราะคุณสมบัติการสนับสนุนด้านความปลอดภัยที่สำคัญของ Ada จึงถูกนำมาใช้ไม่เพียง แต่สำหรับการใช้งานทางทหาร แต่ยังอยู่ในโครงการเชิงพาณิชย์ที่ข้อบกพร่องของซอฟต์แวร์อาจมีผลกระทบรุนแรงเช่น avionics และการควบคุมการจราจรทางอากาศจรวดเชิงพาณิชย์ (เช่น Ariane 4 และ 5) ดาวเทียมและระบบอวกาศอื่น ๆ การขนส่งทางรถไฟและการธนาคาร ตัวอย่างเช่นซอฟต์แวร์ระบบ fly-by-wire ใน Boeing 777 เขียนขึ้นใน Ada

ฉันเกลียดที่จะพูดมากเกินไป แต่สิ่งนี้อธิบายได้ดีว่าทำไมภาษาแบบคงที่ (เช่น ADA) จึงถูกนำมาใช้สำหรับโครงการเช่นนี้:

การตรวจสอบเวลาคอมไพล์จำนวนมากได้รับการสนับสนุนเพื่อช่วยหลีกเลี่ยงข้อผิดพลาดที่จะไม่สามารถตรวจพบได้จนกว่าจะถึงเวลาใช้งานในภาษาอื่นหรือจะต้องเพิ่มการตรวจสอบอย่างชัดเจนในซอร์สโค้ด ตัวอย่างเช่นไวยากรณ์ต้องการชื่อการปิดบล็อกอย่างชัดเจนเพื่อป้องกันข้อผิดพลาดเนื่องจากโทเค็นสิ้นสุดไม่ตรงกัน การยึดติดกับการพิมพ์ที่รัดกุมช่วยให้สามารถตรวจจับข้อผิดพลาดทั่วไปของซอฟต์แวร์ (พารามิเตอร์ที่ไม่ถูกต้องการละเมิดช่วงการอ้างอิงที่ไม่ถูกต้องประเภทที่ไม่ตรงกัน ฯลฯ ) ในระหว่างการรวบรวมเวลาหรืออื่น ๆ ในระหว่างการทำงาน เนื่องจากการทำงานพร้อมกันเป็นส่วนหนึ่งของข้อกำหนดภาษาคอมไพเลอร์สามารถในบางกรณีตรวจพบการหยุดชะงักที่อาจเกิดขึ้น คอมไพเลอร์ยังตรวจสอบตัวระบุที่สะกดผิดการมองเห็นแพ็กเกจการประกาศซ้ำซ้อน ฯลฯ และสามารถให้คำเตือนและคำแนะนำที่เป็นประโยชน์เกี่ยวกับวิธีการแก้ไขข้อผิดพลาด

Ada ยังสนับสนุนการตรวจสอบแบบรันไทม์เพื่อป้องกันการเข้าถึงหน่วยความจำที่ไม่ได้ปันส่วนข้อผิดพลาดการโอเวอร์โฟลว์บัฟเฟอร์การละเมิดช่วงข้อผิดพลาดแบบหนึ่งต่อหนึ่งข้อผิดพลาดการเข้าถึงอาร์เรย์และข้อบกพร่องที่ตรวจพบอื่น ๆ การตรวจสอบเหล่านี้สามารถปิดการใช้งานเพื่อประโยชน์ของประสิทธิภาพรันไทม์ แต่สามารถรวบรวมได้อย่างมีประสิทธิภาพ นอกจากนี้ยังมีสิ่งอำนวยความสะดวกเพื่อช่วยในการตรวจสอบโปรแกรม ด้วยเหตุผลเหล่านี้ Ada ถูกนำมาใช้อย่างกว้างขวางในระบบที่สำคัญซึ่งความผิดปกติใด ๆ อาจนำไปสู่ผลกระทบร้ายแรงเช่นการเสียชีวิตจากอุบัติเหตุการบาดเจ็บหรือการสูญเสียทางการเงินอย่างรุนแรง ตัวอย่างของระบบที่ใช้ Ada ได้แก่ avionics, รถไฟ, ธนาคาร, ทหารและเทคโนโลยีอวกาศ

การจัดการหน่วยความจำแบบไดนามิกของ Ada นั้นมีระดับสูงและปลอดภัย Ada ไม่มี "พอยน์เตอร์" ทั่วไป (และคลุมเครือ); และไม่ได้ประกาศประเภทตัวชี้ใด ๆ การจัดสรรหน่วยความจำแบบไดนามิกทั้งหมดและการจัดสรรคืนจะต้องเกิดขึ้นผ่านประเภทการเข้าถึงที่ประกาศไว้อย่างชัดเจน การเข้าถึงแต่ละประเภทมีพูลหน่วยเก็บข้อมูลที่เชื่อมโยงซึ่งจัดการรายละเอียดระดับต่ำของการจัดการหน่วยความจำ โปรแกรมเมอร์สามารถใช้พูลหน่วยเก็บข้อมูลเริ่มต้นหรือกำหนดรายการใหม่ (ซึ่งเกี่ยวข้องกับการเข้าถึงหน่วยความจำแบบไม่สม่ำเสมอ) เป็นไปได้ที่จะประกาศประเภทการเข้าถึงที่แตกต่างกันหลายประเภทซึ่งทั้งหมดกำหนดประเภทเดียวกัน แต่ใช้พูลหน่วยเก็บข้อมูลที่แตกต่างกัน นอกจากนี้ภาษายังมีการตรวจสอบการช่วยสำหรับการเข้าถึงทั้งในเวลาคอมไพล์และเวลารันไทม์เพื่อให้แน่ใจว่าค่าการเข้าถึงไม่สามารถอยู่ได้นานกว่าประเภทของวัตถุที่ชี้ไป


3
“ เนื่องจากคุณสมบัติการสนับสนุนที่สำคัญต่อความปลอดภัยของ Ada ตอนนี้จึงใช้ [จรวดจรวดพาณิชย์] (เช่น Ariane 4 และ 5)”แน่นอนAriane 5 ระเบิดครั้งแรกเนื่องจากข้อผิดพลาดของซอฟต์แวร์จึงไม่มีกระสุนเงิน
แอนดรูมาร์แชลล์

5
@AndrewMarshall: "แม้ว่ารายงานระบุข้อผิดพลาดซอฟต์แวร์เป็นสาเหตุโดยตรงผู้ตรวจสอบคนอื่น ๆ มองเห็นสาเหตุของความล้มเหลวในการออกแบบระบบและปัญหาการจัดการ" - ฉันสงสัยอย่างจริงจังว่ารหัสที่เขียนในภาษาอื่น (เช่น Java หรือ C ++) จรวดสู่วงโคจร
Martin Schröder

@ MartinSchröderโอ้ฉันไม่ได้สงสัยเลยว่า Ada ยังคงเหนือกว่าคนอื่น ๆ สำหรับแอปพลิเคชันนี้เพียงแค่สังเกตว่ามันไม่ใช่ข้อพิสูจน์ที่โง่เขลา ภาษาอื่นอาจทำให้เกิดข้อผิดพลาดนับไม่ถ้วนซึ่งไม่อาจเกิดขึ้นได้ใน Ada
แอนดรูมาร์แชลล์

13

ทั้งกระทรวงและองค์การนาซ่ามีประวัติยาวนานด้วยการเขียนโปรแกรมล้มเหลวซึ่งมีค่าใช้จ่ายหลายพันล้านดอลลาร์ ทั้งสองสถาบันยอมรับกระบวนการที่ควรป้องกันไม่ให้เกิดข้อผิดพลาดซ้ำ ๆ กัน

Is this the government being slow to adopting new technologies?

นี่เป็นความเข้าใจผิด - ภาษาไดนามิกไม่ได้เป็นเทคโนโลยีใหม่พวกเขาค่อนข้างเก่า ปัญหาคือถ้าคุณเคยมีปัญหาที่เกิดจากภาษาไดนามิก (เช่นการพิมพ์ที่อ่อนแอ / ไดนามิก) และปัญหานั้นทำให้คุณเสียเงินเป็นจำนวนมากคุณสามารถยอมรับนโยบายที่จะป้องกันไม่ให้คุณทำผิดพลาดอีกครั้งเช่น - ห้ามการใช้ภาษาไดนามิกในระบบที่ละเอียดอ่อน

ภาษาแบบไดนามิกมักจะ "กลืน" ข้อบกพร่องและจะจบลงด้วยพฤติกรรมที่ไม่คาดคิด นี่เป็นอันตรายอย่างยิ่งในระบบที่มีความละเอียดอ่อน หากมีสิ่งผิดปกติเกิดขึ้นคุณต้องการทราบโดยเร็วที่สุด

หากกังวลเรื่องความปลอดภัยก็จำเป็นต้องดูกรณีการใช้งานจริง ตัวอย่างเช่นฉันไม่คิดว่าหน้าเว็บ Ruby on Rails จะปลอดภัยน้อยกว่าเว็บเพจ Java โดยอัตโนมัติ


2
ข้อผิดพลาด IMHO มากขึ้นได้รับการ "กลืน" โดยบัฟเฟอร์ล้นตรวจพบกว่าสิ่งอื่นซึ่งเป็นสิ่งที่แม่นยำว่าภาษาแบบไดนามิกส่วนใหญ่จะไม่อนุญาตในตอนแรก ... เพียงแค่พูด
miraculixx

@miraculixx จริงมีเหตุผลทำไม Java / C # และภาษาที่คล้ายกันถูกใช้มากกว่า Ruby พวกเขาป้องกัน - พวกเขาตรวจสอบทุกอย่าง ใน C / C ++ นั้นการบังคับใช้การป้องกันสามารถทำได้โดยใช้มาตรฐานการเข้ารหัสที่ดี คุณยังสามารถบังคับใช้การตรวจสอบสำหรับทุกสิ่ง แต่คุณสามารถจินตนาการถึงการเขียนแอปพลิเคชันที่ละเอียดอ่อนใน ruby ​​หรือ javascript ได้หรือไม่? ความเป็นไปได้สำหรับข้อบกพร่องที่ซ่อนอยู่นั้นยอดเยี่ยม
Sulthan

แน่นอนฉันทำได้ เราน่าจะเห็นด้วยว่าต้องมีการทดสอบซอฟต์แวร์อย่างละเอียดโดยไม่ขึ้นกับภาษาการเขียนโปรแกรม เพื่อหลีกเลี่ยงการถดถอยการทดสอบจึงเป็นแบบอัตโนมัติที่ดีที่สุดโดยใช้เช่นการทดสอบหน่วย BDD และคณะ สันนิษฐานว่าเป็นวิธีการที่เป็นมืออาชีพ (แอพพลิเคชั่นที่ละเอียดอ่อนใช่ไหม) การได้รับความคุ้มครองการทดสอบที่เพียงพอนั้นเป็นกระบวนการที่มีการจัดการไม่ใช่เป็นเรื่องบังเอิญ ด้วยเหตุนี้ฉันจึงสงสัยว่า C / C ++, Java มีข้อได้เปรียบมากกว่า ruby ​​หรือ javascript ในแง่ของข้อบกพร่องที่ซ่อนอยู่ ทักษะโปรแกรมเมอร์? มีแนวโน้มทางเทคนิคมากขึ้นกับ C ++, สงสัยเกี่ยวกับ Java, แต่ไม่ค่อยมีปัญหาภาษา ทางเทคนิคเพิ่มเติม! = คุณภาพของผลิตภัณฑ์
miraculixx

6

ฉันต้องการเพิ่มคำตอบที่มีอยู่โดยอธิบายSA-CORE-2014-005 ของ Drupalซึ่งเป็นช่องโหว่ที่สำคัญอย่างยิ่งซึ่งเปิดใช้งานการฉีด SQL และการใช้รหัสโดยอำเภอใจในที่สุด มันเกิดจากการพิมพ์แบบไดนามิกของ PHP และกฎการพิมพ์แบบหละหลวมรันไทม์

แพทช์ทั้งหมดสำหรับปัญหานี้คือ:

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

รหัสนี้เป็นส่วนหนึ่งของชั้น abstraction SQL ที่ออกแบบมาเพื่อป้องกันการฉีด SQL ใช้แบบสอบถาม SQL กับพารามิเตอร์ที่มีชื่อและอาร์เรย์ที่เชื่อมโยงซึ่งมีค่าสำหรับแต่ละพารามิเตอร์ที่มีชื่อ ค่าที่ได้รับอนุญาตให้เป็นอาร์เรย์สำหรับกรณีเช่นWHERE x IN (val1, val2, val3)นี้โดยที่ทั้งสามค่าสามารถส่งผ่านเป็นค่าอาร์เรย์เดียวสำหรับพารามิเตอร์ที่มีชื่อเดียว

ช่องโหว่ที่เกิดขึ้นเนื่องจากรหัสสันนิษฐานว่า$iใน$i => $valueต้องเป็นจำนวนเต็มของดัชนีค่า มันไปและเชื่อม "ดัชนี" นี้เข้ากับการสืบค้น SQL โดยตรงซึ่งเป็นส่วนหนึ่งของชื่อพารามิเตอร์เพราะจำนวนเต็มไม่ต้องการการหลบหนีใช่ไหม?

น่าเสียดายสำหรับ Drupal PHP ไม่ได้ให้การรับประกันดังกล่าว เป็นไปได้ที่จะส่งผ่านอาเรย์แบบเชื่อมโยงอื่นซึ่งมีคีย์เป็นสตริงและการวนซ้ำนี้จะเชื่อมโยงคีย์สตริงเข้ากับคิวรีได้อย่างมีความสุขตามที่เป็นอยู่ (จำรหัสคิดว่ามันจะเป็นจำนวนเต็มเท่านั้น)

ในขณะที่มีวิธีการที่จะมีข้อผิดพลาดที่คล้ายกันในภาษาที่พิมพ์แบบคงที่พวกเขาไม่น่าเป็นไปได้ ผู้พัฒนาที่ดีจะพิจารณาว่ามีสิ่งใดที่เป็นไป$iได้ก่อนที่จะทำการเชื่อมโยงกับการสืบค้น ด้วยภาษาที่พิมพ์แบบสแตติกมันง่ายมากที่จะบังคับใช้ซึ่ง$iต้องเป็นจำนวนเต็มและในโค้ดที่ไวต่อความปลอดภัยเช่นนี้

นอกจากนี้รหัสจะตรวจสอบว่าค่าเป็นอาร์เรย์ก่อนที่จะวนซ้ำรายการหรือไม่ และในที่นี้อยู่ส่วนที่สองของการล้มเหลวที่ช่วยให้ช่องโหว่นี้ทั้งอาเรย์และ "ปกติ" is_arrayอาร์เรย์กลับจริงสำหรับ แม้ว่ามันจะเป็นความจริงเช่นกันใน C # ทั้งพจนานุกรมและอาร์เรย์IEnumerableเป็นเรื่องยากที่จะสร้างรหัสซึ่งจะทำให้คีย์พจนานุกรมกับดัชนีอาร์เรย์เช่นนี้แม้โดยเจตนาจงใจทำอย่างเดียวโดยไม่ตั้งใจ


2

ไม่ว่าจะเป็น codebase นั้นปลอดภัยหรือไม่นั้นขึ้นอยู่กับว่าคุณเขียนรหัสของคุณอย่างไรคุณทดสอบและตรวจสอบและตรวจสอบกระบวนการพัฒนาและการปรับใช้ของคุณอย่างไร ภาษาไม่ปลอดภัยหรือไม่ปลอดภัยเป็นวิธีที่คุณใช้รหัส

เหตุการณ์ด้านความปลอดภัยส่วนใหญ่เกิดจากอินพุตที่เป็นอันตราย (การฉีด sql, บัฟเฟอร์ล้น), ไวรัส, รูทคิทและโทรจัน ไม่มีภาษาใดที่สามารถปกป้องคุณได้

ดังนั้นการห้ามการใช้ภาษาในการ "ไม่ปลอดภัย" นั้นไม่ใช่เหตุผลที่ถูกต้อง

ฉันสงสัยว่ามีใครบางคนไม่ว่าด้วยเหตุผลใดก็ตาม - ได้รับแจ้งหรือไม่ - ตัดสินใจที่จะห้ามภาษาเหล่านี้ หลังจากที่ในขณะมันก็กลายเป็นความจริงขององค์กร มันอาจเป็นจริง ณ เวลานั้นสำหรับบางโครงการ แต่วัฒนธรรมการควบคุมไม่กระตือรือร้นในการตัดสินใจที่เปลี่ยนแปลง (ยอมรับว่าพวกเขาผิด) และชอบกฎง่าย ๆ มากกว่า พวกเขาเจริญเติบโตในกฎและข้อบังคับและมันไม่สำคัญว่าพวกเขาทำให้รู้สึกหรือไม่มันเป็นความปลอดภัยที่รับรู้ที่นับ

สิ่งนี้เกิดขึ้นตลอดเวลาในวัฒนธรรมการควบคุม ฉันเห็นมันมากขึ้นหรือน้อยลงทุกวัน มันไม่มีเหตุผล แต่นั่นเป็นวิธี หากคุณต้องการอ่านเพิ่มเติมเกี่ยวกับหัวข้อที่มีความเกี่ยวข้องสูงฉันขอแนะนำหนังสือของ Schneider " The Reengineering Alternative " นี่คือแผนภาพวัฒนธรรมของ Michael Sahoto / Agilitrixจากหนังสือของ Schneider: ป้อนคำอธิบายรูปภาพที่นี่


18
-1 มีเหตุผลทางเทคนิคที่ถูกต้องมากมายว่าทำไมภาษาจะได้รับการเลือกมากกว่าภาษาอื่น (การตรวจสอบแบบเรียลไทม์การพิมพ์แบบคงที่เวลาทำงาน) สำหรับระบบที่สำคัญด้านความปลอดภัย คุณหมายความว่าเหตุผลคือวัฒนธรรม 100% เราเทียบกับพวกเขาและโดยพลการซึ่ง IMO นั้นไม่ถูกต้องทั้งหมดในกรณีนี้
Michael Jasper

8
"ภาษาจะไม่ปลอดภัยหรือไม่ปลอดภัย" - ดูstackoverflow.com/a/14313277/602554 บางภาษามีความปลอดภัยมากกว่าภาษาอื่น ๆ
Michael Jasper

2
อัปเดตคำตอบของฉันอาจจะชอบคุณ ฉันยังเชื่อว่าระบบที่ปลอดภัยนั้นขึ้นอยู่กับรหัสที่คุณเขียนมากกว่าภาษาที่คุณใช้แม้ว่าภาษาบางภาษาจะช่วยหลีกเลี่ยงปัญหาบางอย่าง (ในขณะที่อาจแนะนำอื่น ๆ )
Martin Wickman

2
@MartinWickman: a) การฉีด SQL / HTML และบัฟเฟอร์โอเวอร์โฟลว์ได้รับการแก้ไขโดยระบบประเภทบางประเภท - คุณมีประเภทที่แตกต่างกันสำหรับอินพุตที่ใช้ Escape และไม่ใช้ Escape เพื่อให้คุณรู้ว่าควรใช้วิธีใด b) ไม่ใช่ปัญหาด้านความปลอดภัยทั้งหมดใน 'โครงการที่ปลอดภัย' หมายถึงการประนีประนอม ฉันไม่ต้องการให้ซอฟต์แวร์ที่ใช้งานบนเครื่องบินมีข้อบกพร่องใด ๆ แม้ว่าจะไม่ใช่ปัญหา 'ความปลอดภัย' (เช่นไม่สามารถใช้เพื่อครอบครองระบบ)
Maciej Piechotka

5
-1 สำหรับปัญหาความแม่นยำที่เป็นข้อเท็จจริง การหาช่องโหว่บัฟเฟอร์ล้นเป็นปัญหาที่เฉพาะเจาะจงกับภาษา C คุณไม่เคยได้ยินเกี่ยวกับพวกเขาในภาษาที่ไม่อนุญาตให้คุณจัดสรรบัฟเฟอร์สตริงบนสแต็ก และไม่ใช่เรื่องยากเลยที่จะจินตนาการว่าภาษาถิ่น SQL สมมุติฐานซึ่งการใช้พารามิเตอร์ไม่ได้รับอนุญาตเพียง แต่จำเป็นเท่านั้น การฉีด SQL จะเป็นไปไม่ได้ในภาษานี้ ใช่แล้วภาษาที่ถูกออกแบบมาอย่างเหมาะสมสามารถปกป้องคุณจากการโจมตีหลายประเภท
Mason Wheeler

2

เท่าที่ฉันสามารถบอกได้นโยบายกระทรวงกลาโหมโดยทั่วไปไม่ได้ห้ามภาษาแบบไดนามิก

มาตรฐานสำหรับซอฟต์แวร์ที่พัฒนาหรือจัดหาโดยกระทรวงมีการประกาศใช้โดยสำนักงานระบบข้อมูลกลาโหม (DISA) ความปลอดภัยของแอปพลิเคชัน -คู่มือการใช้งานด้านเทคนิคความปลอดภัยของแอพพลิเคชั่น (STIG) ไม่ได้ห้ามภาษาใด ๆ โดยเฉพาะ มันไม่ได้พูดถึง Ruby แต่พูดถึง Perl และ Python ที่มีพลังคล้ายกัน มันกล่าวถึงพวกเขาในบริบทของหัวข้อต่าง ๆ (ตามมาตรฐานการเข้ารหัสที่จัดตั้งขึ้นหลีกเลี่ยงช่องโหว่การฉีดคำสั่ง ฯลฯ )

อาจเป็นสิ่งที่คุณเห็นเป็นเครื่องมือสแกนที่เข้มงวดเกินไป (มีหลายสิ่งที่กล่าวถึงใน STIG แต่ละอันอาจมีการตีความกฎของตนเอง) และ / หรือการตีความผลลัพธ์ที่เข้มงวดเกินไป

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.