เกิดอะไรขึ้นถ้า JWT ถูกขโมย?


203

ฉันพยายามใช้การพิสูจน์ตัวตนแบบไร้รัฐกับ JWT สำหรับ RESTful API ของฉัน

AFAIK, JWT นั้นเป็นสตริงเข้ารหัสที่ส่งผ่านเป็นส่วนหัว HTTP ในระหว่างการเรียกใช้ REST

แต่ถ้ามีคนดักฟังที่เห็นคำขอและขโมยโทเค็นล่ะ? จากนั้นเขาจะสามารถปลอมแปลงคำขอด้วยตัวตนของฉันได้อย่างไร

อันที่จริงความกังวลนี้ใช้กับทุกการตรวจสอบ token-based

จะป้องกันได้อย่างไร ช่องทางที่ปลอดภัยเช่น HTTPS


1
นี่คือเหตุผลที่โทเค็นมักจะใช้ได้เพียงช่วงเวลาสั้น ๆ เท่านั้น และใช่คุณควรใช้ HTTPS หากคุณกังวลเกี่ยวกับความลับของข้อมูลของคุณ
Jonathon Reinhart

4
@ JonathonReinhart แต่ถ้าโทเค็นหมดอายุในไม่ช้าลูกค้าของฉันจะต้องได้รับโทเค็นใหม่โดยการตรวจสอบตัวเองใหม่เป็นครั้งคราว มันน่าเบื่อใช่ไหม
smwikipedia

@ JonathonReinhart ฉันคิดว่าฉันเข้าใจว่าทำไมโทเค็นจึงมีอายุสั้น เนื่องจากวิธีการนี้เซิร์ฟเวอร์ไม่จำเป็นต้องติดตามการหมดอายุของโทเค็นจึงทำให้สามารถปรับขยายได้ มันเป็นชนิดของtrade-offระหว่างและhaving finer control of token expiration having better scalability
smwikipedia

2
สิ่งนี้สามารถช่วยได้หรือไม่? - "กลไกความปลอดภัยทั่วไปในการตรวจจับการขโมยโทเค็นคือการติดตามคำขอที่อยู่ IP ต้นทาง" - อธิบายโดยละเอียดในส่วนสุดท้ายที่นี่ - firebase.google.com/docs/auth/admin/manage-sessions
Ula

3
ตามทฤษฎีแล้วมันเป็นไปไม่ได้ที่จะป้องกันการขโมยโทเค็น สิ่งที่ดีที่สุดที่เราทำได้คือตรวจจับสิ่งที่เกิดขึ้นแล้วยกเลิกเซสชั่นเร็วที่สุด วิธีที่ดีที่สุดสำหรับการตรวจจับคือการใช้โทเค็นการรีเฟรชแบบหมุน (แนะนำโดย RFC 6819) นี่คือบล็อกที่อธิบายรายละเอียดนี้: supertokens.io/blog/…
Rishabh Poddar

คำตอบ:


287

ฉันเป็นผู้เขียนของไลบรารี่โหนดที่จัดการกับการพิสูจน์ตัวตนในเชิงลึก, express-stormpath , ดังนั้นฉันจะพูดสอดกับข้อมูลบางอย่างที่นี่

ก่อนอื่น JWT มักไม่มีการเข้ารหัส ในขณะที่มีวิธีการเข้ารหัส JWTs (ดู: JWEs ) สิ่งนี้ไม่ได้เป็นเรื่องธรรมดาในทางปฏิบัติด้วยเหตุผลหลายประการ

ถัดไปขึ้นไปการตรวจสอบความถูกต้องทุกรูปแบบ (โดยใช้ JWT หรือไม่ก็ตาม) ขึ้นอยู่กับการโจมตีของ MitM (การโจมตีแบบกึ่งกลาง) การโจมตีเหล่านี้เกิดขึ้นเมื่อผู้โจมตีสามารถดูทราฟฟิกเครือข่ายของคุณเมื่อคุณทำการร้องขอผ่านอินเทอร์เน็ต นี่คือสิ่งที่ ISP ของคุณสามารถมองเห็นได้ NSA ฯลฯ

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

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

ตอนนี้นี่คือที่มาของโปรโตคอล

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

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

สิ่งที่ทำให้คำถามของคุณน่าสนใจยิ่งขึ้นคือโปรโตคอลที่ใช้งานอยู่

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

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

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

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

หวังว่านี่จะช่วยได้ ^^


3
ผู้เขียนบทความต่อไปนี้ระบุว่าข้อเสียของ JWT คือวิธีเดียวที่จะกู้คืนจาก JWT ที่ถูกขโมยคือการสร้างคู่คีย์ใหม่และล็อกผู้ใช้ทั้งหมดอย่างมีประสิทธิภาพ ในขณะที่รหัสเซสชันเก็บอยู่ในฐานข้อมูลเว็บไซต์สามารถลบเฉพาะเซสชันของผู้ใช้ที่ได้รับผลกระทบและออกจากระบบของอุปกรณ์ทั้งหมด ฉันไม่แน่ใจว่า OAuth2 เหมาะสมกับภาพในที่นี้หรือไม่ว่าจะช่วยลดข้อเสียที่นำเสนอได้หรือไม่ medium.com/@rahulgolwalkar/…
Marcel

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

1
@ ข้อเสนอแนะกรุณาบอกฉันว่า JWT เป็นความคิดที่ไม่ดีสำหรับการตรวจสอบ? และฉันจะใช้คุกกี้เซสชันที่คุณพูดถึงในความคิดเห็นของคุณด้านบนได้อย่างไร
nufu tufail

6
นี่เป็นวิธีที่ยาวเกินไปในการพิมพ์คำตอบเดียว หากคุณต้องการเรียนรู้เพิ่มเติมฉันได้พูดคุยอย่างละเอียดเกี่ยวกับเรื่องนี้ คุณสามารถตรวจสอบสไลด์ของฉันออนไลน์ได้ที่: speakerdeck.com/rdegges/jwts-suck-and-are-stupid
rdegges

2
ตามทฤษฎีแล้วมันเป็นไปไม่ได้ที่จะป้องกันการขโมยโทเค็น สิ่งที่ดีที่สุดที่เราทำได้คือตรวจจับสิ่งที่เกิดขึ้นแล้วยกเลิกเซสชั่นเร็วที่สุด วิธีที่ดีที่สุดสำหรับการตรวจจับคือการใช้โทเค็นการรีเฟรชแบบหมุน (แนะนำโดย RFC 6819) นี่คือบล็อกที่อธิบายรายละเอียดนี้: supertokens.io/blog/…
Rishabh Poddar

31

ฉันรู้ว่านี่เป็นคำถามเก่า แต่ฉันคิดว่าฉันสามารถวาง $ 0.50 ของฉันที่นี่อาจมีใครบางคนสามารถปรับปรุงหรือให้ข้อโต้แย้งเพื่อปฏิเสธแนวทางของฉันโดยสิ้นเชิง ฉันใช้ JWT ใน RESTful API ผ่าน HTTPS (ofc)

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

สำหรับauthentication serviceในการทำให้โทเค็นเป็นโมฆะฉันชอบที่จะใช้เลเยอร์แคชในหน่วยความจำ ( redisในกรณีของฉัน) เป็นJWT blacklist/ ban-listในหน้าขึ้นอยู่กับเกณฑ์บางอย่าง: (ฉันรู้ว่ามันทำลายปรัชญาสงบ แต่เอกสารที่เก็บไว้เป็น สั้นมากจริง ๆ เพราะฉันขึ้นบัญชีดำสำหรับเวลาที่เหลืออยู่ของพวกเขา - การเรียกร้อง - ttl)

หมายเหตุ: โทเค็นที่อยู่ในบัญชีดำจะไม่สามารถรีเฟรชอัตโนมัติ

  • หากuser.passwordหรือuser.emailได้รับการปรับปรุง (ต้องมีการยืนยันรหัสผ่าน) บริการรับรองความถูกต้องจะส่งคืนโทเค็นที่รีเฟรชและทำให้ใช้งานไม่ได้ (บัญชีดำ) ก่อนหน้านี้ดังนั้นหากลูกค้าของคุณตรวจพบว่าตัวตนของผู้ใช้นั้นถูกโจมตี . หากคุณไม่ต้องการใช้บัญชีดำคุณสามารถ (แต่ฉันไม่สนับสนุนให้คุณ) ตรวจสอบการiatอ้างสิทธิ์ (ออกเมื่อ) กับuser.updated_atฟิลด์ (ถ้าjwt.iat < user.updated_atJWT นั้นไม่ถูกต้อง)
  • ผู้ใช้ออกจากระบบโดยเจตนา

ในที่สุดคุณตรวจสอบโทเค็นตามปกติเหมือนทุกคน

หมายเหตุ 2:แทนที่จะใช้โทเค็นเอง (ซึ่งมีความยาวจริง ๆ ) เป็นคีย์ของแคชฉันแนะนำให้สร้างและใช้โทเค็น UUID สำหรับการjtiอ้างสิทธิ์ ซึ่งเป็นสิ่งที่ดีและฉันคิดว่า (ไม่แน่ใจตั้งแต่เพิ่งมาในใจของฉัน) คุณสามารถใช้ UUID เดียวกันนี้เป็นโทเค็น CSRF ได้เช่นกันโดยส่งคืนsecure/ non-http-onlyคุกกี้ด้วยและใช้X-XSRF-TOKENส่วนหัวอย่างเหมาะสมโดยใช้ js วิธีนี้คุณหลีกเลี่ยงการคำนวณการสร้างโทเค็นอื่นสำหรับการตรวจสอบ CSRF


9
ไม่สายเกินไปที่จะสนับสนุนความคิดของคุณ ขอบคุณสำหรับการตอบกลับของคุณ.
smwikipedia

2
หากคุณเก็บบัญชีดำไว้ในเซิร์ฟเวอร์ที่ต้องตรวจสอบทุกคำขอทำไมไม่ใช้เซสชันเก่าแบบธรรมดา
แฟรงคลินหยู

@ FranklinYu บัญชีดำมีวิธี "ราคาถูก" มากกว่าร้านค้าเซสชั่นเต็มรูปแบบ เนื่องจากคุณกำลังจัดเก็บวัตถุคีย์ - ค่าสั้น ๆ (ขึ้นอยู่กับเวลาที่เหลืออยู่ซึ่งควรสั้น) และเกิดขึ้นเฉพาะสำหรับการออกจากระบบและการกระทำที่โทเค็นโทเค็นไม่ถูกต้อง เก็บไว้ ofc
Frondor

2
มันราคาถูกแค่ไหน? ก่อนอื่นถ้าคุณยังคงเก็บอะไรไว้ฝั่งเซิร์ฟเวอร์คุณจะไม่ได้รับประโยชน์จาก "scalability" ที่ JWT อ้างไว้เพราะยังมีบัญชีดำกลางที่เซิร์ฟเวอร์แอปพลิเคชันทั้งหมดต้องพูดคุยก่อนจะทำอะไร หากคุณต้องการเก็บบัญชีดำ 1k เนื่องจากการหมดอายุอย่างรวดเร็วคุณสามารถทำเช่นเดียวกันสำหรับเซสชันและดังนั้นจึงจำเป็นต้องเก็บเซสชัน 1k เท่านั้น
แฟรงคลินหยู

3
ฉันชอบวิธีนี้ คุณไม่จำเป็นต้องตรวจสอบบัญชีดำในแต่ละคำขอเฉพาะในคำขอที่เกิดขึ้นหลังจาก JWT หมดอายุแล้ว (ซึ่งคุณสามารถอ่านได้จากโทเค็นตัวเอง) และจนถึงระยะเวลาหลังจาก TTL ในกรณีที่ใช้ "มาตรฐาน" ที่ควรเกิดขึ้นอย่างมากหนึ่งครั้งในช่วงอายุของโทเค็นที่กำหนด เมื่อรีเฟรชแล้วคุณอาจปฏิเสธคำขอรีเฟรชใด ๆ ในอนาคต ขอบคุณ @Frondor
John Ackerman

7

ขออภัยที่มาสายเล็กน้อย แต่มีข้อกังวลที่คล้ายกันและตอนนี้ต้องการมีส่วนร่วมในสิ่งเดียวกัน

1) rdeggesเพิ่มจุดที่ยอดเยี่ยมว่า JWT ไม่มีส่วนเกี่ยวข้องกับ "ความปลอดภัย" และเพียงแค่ตรวจสอบความถูกต้องถ้าใครมี messed กับ payload หรือไม่ (ลงนาม); ssl ช่วยป้องกันการรั่วไหล

2) ทีนี้ถ้า ssl นั้นถูกบุกรุก eavesdropper ใด ๆ สามารถขโมยโทเค็นผู้ถือ (JWT) ของเราและปลอมตัวเป็นผู้ใช้ของแท้ขั้นตอนต่อไปที่จะทำคือค้นหา"หลักฐานการครอบครอง"ของ JWT จากลูกค้า .

3) ในตอนนี้ด้วยวิธีนี้ผู้นำเสนอของ JWT มีคีย์ Proof-Of-Possession (POP) ซึ่งผู้รับสามารถยืนยันการเข้ารหัสว่าคำขอนั้นมาจากผู้ใช้จริงหรือไม่

ฉันเรียกหลักฐานการพิสูจน์ของบทความเรื่องนี้และเชื่อมั่นกับ apporach

ฉันจะยินดีถ้าสามารถมีส่วนร่วมอะไร

ไชโย (y)


0

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


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