จะเป็น 'ถ้ารหัสผ่าน == XXXXXXX' เพียงพอสำหรับความปลอดภัยขั้นต่ำหรือไม่


20

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

if(enteredPassword == verifiedPassword)
     SendToRestrictedArea();
else
     DisplayPasswordUnknownMessage();

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

อัปเดต:โครงการเฉพาะที่เกิดขึ้นเป็นบริการเว็บการตรวจสอบเป็นฝั่งเซิร์ฟเวอร์ทั้งหมดและไม่ใช่โอเพ่นซอร์ส โดเมนเปลี่ยนวิธีจัดการกับสิ่งนี้หรือไม่?


3
มันขึ้นอยู่กับที่ validPassword มาจากไหน? หากเป็นฮาร์ดโค้ดคุณจะไม่สามารถกำหนดค่า / เปลี่ยนรหัสผ่านได้โดยไม่ต้องเปลี่ยนรหัส หากมาจากไฟล์กำหนดค่าจะปรากฏแก่ทุกคนที่เข้าถึงไฟล์นั้น
Alb

1
"เป็นการตรวจสอบคอมโบของชื่อผู้ใช้ / รหัสผ่านเพียงพอ" เพื่อทำอะไร
คริส

3
@opinion: ดูเหมือนว่าไม่น่าเป็นไปได้มากกว่าที่จะไม่มีการเข้าสู่ระบบ โปรดให้เหตุผลบางอย่างสำหรับการเรียกร้องที่แข็งแกร่งดังกล่าว
Morgan Herlocker

1
คำศัพท์ของคุณไม่ถูกต้องเมื่อคุณเปรียบเทียบรหัสผ่านของคุณกับการตรวจสอบว่าไม่ถูกต้อง โปรดสละเวลาเพื่อทำความเข้าใจความแตกต่าง
billy.bob

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

คำตอบ:


26

ไม่ใช้ SSL

สิ่งนี้ไม่ปลอดภัยหากรหัสผ่านถูกส่งผ่านเครือข่ายเป็นข้อความธรรมดา การใส่รหัสผ่านในฝั่งเซิร์ฟเวอร์ก็ไม่ปลอดภัยเช่นกันหากรหัสผ่านถูกส่งผ่านเครือข่ายในรูปแบบข้อความล้วน

เนื่องจาก<input type="password"/>แท็กHTML จะส่งเนื้อหาเป็นข้อความธรรมดาปัญหานี้จะเกิดขึ้นไม่ว่าคุณจะเก็บรหัสผ่านไว้บนเซิร์ฟเวอร์ได้อย่างไรเว้นแต่เว็บไซต์ของคุณจะใช้ SSL เพื่อส่งรหัสผ่าน

(การพิสูจน์ตัวตน HTTP ซึ่งปรากฏขึ้นในกล่องโต้ตอบในเบราว์เซอร์เพื่อขอรหัสผ่านอาจหรือไม่อาจเป็นข้อความที่ชัดเจนขึ้นอยู่กับกลไกการตรวจสอบสิ่งที่เซิร์ฟเวอร์และเบราว์เซอร์มีเหมือนกันดังนั้นอาจเป็นวิธีที่จะหลีกเลี่ยงปัญหานี้ SSL.)

ไม่ใช่หากผู้ดูแลไซต์สงสัย

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

วิธีที่ทำให้รหัสผ่านปลอดภัยจากผู้ดูแลระบบ

วิธีหนึ่งที่ปลอดภัยในการจัดเก็บและตรวจสอบรหัสผ่านมีดังนี้:

def change_password user, new_password
  salt = random(65536).to_s(16) #will be 4 characters long
  password_hash = salt + hash(salt + new_password)
  store(user,password_hash)
end

def does_password_match? user, entered_password
  correct_password_hash = retrieve(user)
  salt = correct_password_hash[0...4]
  entered_password_hash = salt + hash(salt + entered_password)
  return correct_password_hash == entered_password_hash
end

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

ความแปรปรวนในเวลาแฝงเครือข่ายของคุณและไม่ว่าชื่อผู้ใช้จะได้รับการเปิดเผยสู่สาธารณะหรือไม่คุณอาจต้องการให้มีการคำนวณเส้นทางของรหัสอื่นhash('0000'+entered_password)หากผู้ใช้ไม่มีอยู่เพื่อป้องกันผู้โจมตีจาก กำหนดชื่อผู้ใช้ที่ถูกต้องตามเวลาที่ใช้ตรวจสอบว่ารหัสผ่านไม่ถูกต้อง


1
คำแนะนำที่ดี :) เกี่ยวกับ SSL เราจำเป็นต้องออกแบบสิ่งที่จะทำงานในป่าและเพียงแค่ใช้การเข้ารหัสแบบไม่สมมาตรเพื่อเข้ารหัสรหัสผ่าน (ต้องใช้ Javascript) แล้วถอดรหัสบนเซิร์ฟเวอร์ จากนั้นเกลือและแฮชจะเกิดขึ้นตามปกติ นอกจากนี้เนื่องจากรหัสสาธารณะจะถูกส่งไปพร้อมกับหน้าเว็บจึงสามารถเปลี่ยนได้บ่อยครั้ง
Matthieu M.

1
@Matthieu อืม: เมื่อมีคนสามารถปลอมหน้าเว็บของคุณเขายังสามารถเปลี่ยนรหัสสาธารณะที่นั่นเป็นหนึ่งในที่ที่เขารู้รหัสส่วนตัวที่สอดคล้องกัน ดังนั้นความคิดของคุณจะช่วยป้องกันการโจมตีจากการอ่านแฝงไม่ใช่กับคนกลาง
Paŭlo Ebermann

@ พอลโล: ใช่ฉันยอมรับว่า SSL ไม่เพียง แต่เกี่ยวกับการเข้ารหัส แต่ยังเกี่ยวกับใบรับรองโชคไม่ดีที่ฉันไม่ได้โทรหาที่นี่และเมื่อมีคนบอกว่าพวกเขาต้องการใช้เว็บเพจที่มีการhttp://เชื่อมต่อปกติ... มันน่าหงุดหงิด: /
Matthieu M.

@ Matatieu: นั่นหมายความว่าคุณกำลังส่ง public_key เป็นส่วนหนึ่งของหน้าเว็บสาธารณะประมวลผลencrypt(entered_password, public_key)บนไคลเอนต์และส่งผลลัพธ์นั้นไปยังเซิร์ฟเวอร์ซึ่งมีประสิทธิภาพdoes_password_match?(user, decrypt(encrypted_password, private_key))หรือไม่
Ken Bloom

@Ken: มากกว่าหรือน้อยกว่าคุณได้รับการเข้ารหัสที่ถูกต้อง สำหรับการจับคู่รหัสผ่านมันมีมากขึ้นdoes_password_match(user, salt, decrypt(encrypted, key))ด้วยเกลือขึ้นอยู่กับผู้ใช้ ดังที่ฉันได้กล่าวไปแล้วปัญหาที่ชัดเจนคือการขาดการปกป้องจากคนกลาง
Matthieu M.

52

ที่จะแนะนำให้คุณเก็บรหัสผ่านในข้อความเปิดซึ่งเป็น no-no แม้ในสถานการณ์ความปลอดภัยต่ำ

คุณควรจะมี:

if(hash(enteredPassword) == storedHash)

คุณสามารถใช้แฮชธรรมดาได้เช่น MD5


22
+1 สำหรับการไขรหัสผ่าน แต่อย่างน้อยฉันก็ควรเพิ่มเกลือด้วย ไม่เช่นนั้นเนื่องจากผู้ใช้จะใช้ชื่อผู้ใช้และรหัสผ่านระหว่างระบบซ้ำการละเมิดแอปความปลอดภัยต่ำของคุณอาจทำให้ผู้โจมตีละเมิดแอปความปลอดภัยที่สูงขึ้นมาก ยกตัวอย่างเช่นการแฮ็ก HBGary ล่าสุดจัดการกับระบบ CMS ที่ใช้งานเว็บไซต์ของพวกเขาและเปลี่ยนเป็นการเข้าถึงรูทไปยังเซิร์ฟเวอร์ของพวกเขาในบางส่วนเนื่องจากระบบ CMS ที่มีความปลอดภัยต่ำไม่ได้เพิ่มเกลือลงในแฮชarstechnica.com/tech-policy/ news / 2011/02 / …
Justin Cave

1
ยอมรับ ... พิจารณาสิ่งต่อไปนี้ .. "สตริง JavaFile.class | grep -i password"
Bill

ปัญหาในการมีรหัสผ่านเป็นข้อความธรรมดาหากใช้เพียงครั้งเดียวคืออะไร?

10
@Tim เนื่องจากผู้ใช้จะไม่ใช้รหัสผ่านเพียงครั้งเดียว การศึกษาอย่างต่อเนื่องแสดงให้เห็นว่าผู้ใช้ใช้รหัสผ่านซ้ำหลายครั้ง (เช่นtheregister.co.uk/2011/02/10/password_re_use_study ) ไม่ว่าจะถูกบอกว่าไม่กี่ครั้งก็ตาม
สกอตต์

3
@Tim: นอกจากนี้ให้เปิด exe, dll และอื่น ๆ ในเท็กซ์เอดิเตอร์และคุณอาจเห็นรหัสผ่านของคุณตรงนั้น
Gus Cavalcanti

14

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


ฉันเพิ่งค้นพบผู้ให้บริการสมาชิก ASP.Net เท่านั้น แต่ฉันมองพวกเขาคิดว่า "ฉันเสียเวลาไปกับการทำอะไรแบบนี้มากี่ครั้งแล้วเหรอ?"
glenatron

8

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

isSecuritySufficient = effortToBreak > rewardForBreaking

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

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

หลักการทั่วไปสำหรับการป้องกันรหัสผ่าน

  • อย่าเก็บรหัสผ่านเป็นข้อความธรรมดา
  • แฮชที่ใช้ฟังก์ชันแฮชที่ปลอดภัยเช่น SHA-1 หรือแม้แต่ SHA-512 (แม้แต่ MD5 ก็ง่ายเกินไปที่จะหาแฮชที่ตรงกัน)
  • ใช้ค่าเกลือของแอปพลิเคชัน เกลือจะถูกสุ่มไบต์เพิ่มให้กับรหัสผ่านเพื่อให้เดาได้ยากขึ้น เกลือควรถูกสร้างขึ้นในเวลาทำงานและใช้ข้อมูลเกี่ยวกับเครื่องเป็นค่าเมล็ดแทนที่จะเก็บและอ้างอิงในทางใดทางหนึ่ง
  • ใช้ค่าเกลือเฉพาะของผู้ใช้ ใช้สิ่งนี้ร่วมกับเกลือใบสมัครของคุณ
  • เข้ารหัสการร้องขอการรับรองความถูกต้องทั้งหมดที่ข้ามเครือข่าย นั่นหมายถึงใช้ SSL สำหรับเว็บแอปพลิเคชัน

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

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


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

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

อ่าฉันเข้าใจเอาเกลือบางส่วนออกจากฐานข้อมูล นั่นทำให้รู้สึก ขอขอบคุณ.
David Conrad

ฉันไม่เห็นปัญหาในการเก็บเกลือต่อแถวตราบใดที่มีความเป็นเอกลักษณ์ต่อแถว นี่คือแฮช: "fd84235a55bbfeb1585a3dd069d48127989c9753058b51b6ba2056fd6c5a0a91" (SHA256) นี่คือเกลือ: "671254bdf7944f8fa88e6c99139999999999896" คิดว่าคุณจะได้รับรหัสผ่าน? ไม่มีโต๊ะรุ้งสำหรับเกลือนั้น (แม้ว่าคุณจะได้รับเกลือ) คุณก็ติดอยู่กับสัตว์เดรัจฉาน
ไบรอัน Boettcher

3

ไม่เป็นไรเว้นแต่จะใช้รหัสผ่านเพื่อสิ่งอื่นใด ยังคงมีความเสี่ยงที่ผู้ใช้ตัดสินใจว่าเขาสามารถใช้รหัสผ่านซ้ำได้ดังนั้นจะดียิ่งขึ้นเมื่อ:

if(hash(enteredPassword) == hashOfValidPassword)

หากเป็นของคุณเองหรือคนที่รู้ว่ารหัสผ่านนั้นถูกเก็บไว้ในรูปแบบข้อความธรรมดาก็ถือว่าใช้ได้


1
ในฐานะที่เป็นความคิดเห็นของ Justin Cave ต่อคำตอบของ vartec ให้ใช้เกลือดังนั้นif (hash (enteredPassword + salt) == hashOfValidSaltedPassword)- และโปรดทราบว่า+อาจจะเป็นการต่อกัน นี่เป็นอุปสรรคต่อการใช้ตารางสายรุ้งซึ่งเป็นตารางแฮชของรหัสผ่านที่เป็นไปได้
David Thornley

หากสิ่งที่คุณกำลังตรวจสอบคือแฮชพวกเขาจะไม่เพียงแค่วิ่งวนไปตามสายอักขระที่เป็นไปได้จนกว่าจะสร้างแฮชแบบเดียวกับแฮชที่เก็บไว้หรือไม่? มีสตริงจำนวนมากที่สามารถสอดคล้องกับแฮชเดียวกันหลังจากทั้งหมด
Morgan Herlocker

@Prof Plum: มันเป็นเรื่องยากมากที่จะหาการชนถ้าอัลกอริทึมการแปลงแป้นพิมพ์เป็นสิ่งที่ดี นี่คือพื้นฐานของการเข้ารหัสสมัยใหม่: มันเป็นฟังก์ชันทางเดียว

3

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

อย่ามองข้ามความปลอดภัยแม้ว่าความคิดเห็นของคุณจะไม่สำคัญมากนัก


2
ใช่เป็นความคิดที่ไม่ดีถ้าเป็นโครงการโอเพ่นซอร์ส :)

-1 - ถ้าคุณคิดว่าการมีแหล่งที่มาสร้างความแตกต่างคุณไม่รู้อะไรเลยเกี่ยวกับความปลอดภัย
mattnz

1

ไม่ได้อย่างแน่นอน. มีการอ่านสิ่งนี้อธิบายถึงวิธีที่แฮกเกอร์แฮ็คเว็บไซต์ความปลอดภัย คุณวางแผนที่จะให้คุณเป็นลิงค์ที่อ่อนแอที่สุดในห่วงโซ่


0

มันถูกบันทึกไว้ในสองคำตอบที่คุณไม่ควรเก็บรหัสผ่านของตัวเอง แต่เป็นแฮช - และคุณควรใช้ SSL

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

และเพียงแค่ hashing รหัสผ่านไม่เพียงพอ คุณต้องสับมันด้วยเกลือ แฮกเกอร์มีตารางแฮชย้อนกลับดังนั้นสำหรับแฮชที่ระบุพวกเขาสามารถค้นหารหัสผ่านที่ตรงกันได้

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


-2

ตราบใดที่นี่คือฝั่งเซิร์ฟเวอร์ .. จากนั้นก็ใช่

หากคุณต้องการความปลอดภัยเพิ่มขึ้นอีกเล็กน้อยให้ไปที่ https และเข้ารหัส \ hash รหัสผ่านในฐานข้อมูล


3
ทำไมนี่เป็นเว็บแอป
คริส

จุดดี! ฉันแค่ทำ
Morons

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