guest@websec ~ % man 14-deserialization-and-xxe
14 · Deserialization และ XXE
รูปแบบข้อมูลบางแบบสร้าง object อะไรก็ได้ อ่านไฟล์ได้ หรือขยายเป็นหลายกิกะไบต์ ถ้า parse จากคนแปลกหน้า input จะเป็นคนกำหนดว่าเซิร์ฟเวอร์ทำอะไร
14.1 Deserialization ที่ไม่ปลอดภัย
JSON สร้างได้แค่ข้อมูลธรรมดา แต่ Marshal ของ Ruby และ YAML ที่มีแท็ก object สร้าง class อะไรก็ได้
ผู้โจมตีจึงเลือกได้ว่าจะสร้าง object อะไร ร้อย class ธรรมดาไม่กี่ตัวเข้าด้วยกัน ก็รันโค้ดได้จาก request เดียว
Rails โดนเรื่องนี้ในปี 2013: POST เดียวยึดแอป Rails ตัวไหนบนอินเทอร์เน็ตก็ได้
YAML.unsafe_load
YAML.load (Psych 4+, Ruby 3.1+)
JSON.parse
วิธีป้องกัน:
- ใช้ JSON กับทุกอย่างที่มาจากภายนอก
- ต้องรับ YAML จากผู้ใช้? ใช้
YAML.safe_load - ห้าม
Marshal.loadข้อมูลที่ไม่น่าเชื่อถือ
Rails สมัยใหม่ปลอดภัยโดยค่าเริ่มต้น: คุกกี้แบบ JSON ไม่ parse XML params และ YAML แบบปลอดภัย ตรวจแอปเก่า ว่ามี cookie serializer แบบ
:marshal หรือ Marshal.load ไหม# safe by default on Ruby 3.1+ (Psych 4) YAML.load(user_yaml) # plain types only YAML.safe_load(user_yaml, permitted_classes: [Date, Symbol]) JSON.parse(user_json) YAML.unsafe_load(user_yaml) # arbitrary objects Marshal.load(Base64.decode64(params[:state])) # RCE # config/initializers/cookies_serializer.rb (older apps: check this!) Rails.application.config.action_dispatch.cookies_serializer = :json
// JS: JSON.parse is data-only. Danger comes from libraries that revive objects JSON.parse(body); // plain data require("node-serialize").unserialize(body); // has executed functions (CVE-2017-5941) yaml.load(text) // js-yaml 3.x: can build functions (4.x is safe)
14.2 XML External Entities (XXE)
XML ชี้ไปยังไฟล์ภายนอกได้ parser ที่ไม่ระวังจะอ่าน /etc/passwd แล้วส่งกลับมา หรือขยายไฟล์ 1 KB เป็นหลายกิกะไบต์
XML ซ่อนอยู่ใน SAML, RSS, SVG และไฟล์ Office
Nokogiri ปลอดภัยโดยค่าเริ่มต้น แค่อย่าส่ง
noent หรือ dtdloaddoc = Nokogiri::XML(upload.read) # safe defaults doc = Nokogiri::XML(upload.read) { |c| c.strict.nonet } Nokogiri::XML(xml) { |c| c.noent.dtdload } # enables XXE Nokogiri::XML(xml, nil, nil, Nokogiri::XML::ParseOptions::NOENT)