#100DaysOfPyCon2018 Day5: Oops! I Committed My Password To GitHub!
Key takeaway
- คนที่เคย commit password ลง Git มีอยู่ 2 ประเภท ประเภทแรกคือเผลอพลาดจริงๆ อีกประเภทคือบอกว่า commit สิแต่ไม่เป็นไรเพราะ… ซึ่งเพราะนี่มีหลายคนที่บอกว่า เพราะมันเป็น private repo แต่เราไม่ควรมองอย่างงั้นเพราะว่า Private Repo มันไม่ได้ encrypt เพราะฉะนั้นคนที่อยู่ GitHub ก็ยังดูข้อมูลเราได้อยู่ รวมถึงถ้าวันนึงคนในทีมออกจากบริษัทไป คนๆ นั้นก็ยังมี password นั้นอยู่ อีกเหตุผลคือ ไม่เป็นไรเพราะ password เราใช้ใน internal service แนวคิดนี้มาจากการจำกัดบริเวณความเสียหาย ซึ่งก็ยังไม่ตอบโจทย์อยู่ดี
- วิธีการ (ไม่) แก้ password ที่เผลอ commit ไปคือ สร้าง commit ใหม่ที่จะลบ password ถ้าเราใช้ git เป็นประจำเราจะรู้ว่าเราสามารถดู history ได้ซึ่งวิธีนี้ก็ไม่ได้แก้ปัญหาอะไร อีกวิธีที่บางคนคิดว่าแก้ปัญหาคือ rebase commit แต่มันไม่ได้แก้ปัญหาถึงแม้ว่า history จะเปลี่ยนไป แต่ git เก็บทุกอย่างแล้ว commit นี้ยังอยู่ใน ref log แต่เป็น orphant อยู่จนกว่าจะโดน garbage collect ไป รวมถึงถ้าในเคสที่คนที่ลาออกไปก่อนที่เราจะ rebase สุดท้ายเค้ายังมี password อยู่ดี เพราะมันไม่ได้แก้ทุกเครื่อง
- วิธีแก้ที่ดีสุดคือ Revoke password ซะ นี่เป็นสิ่งแรกที่เราควรทำเมื่อรู้ตัวว่า password เราเผลอ commit ไปแล้ว สิ่งต่อมาที่ควรทำคือ เราควรจะเก็บ password / secret ไว้ใน environment variable ซึ่งวิธีการ access มันใน Python เราสามารถใช้ module os.environ ในการเรียกได้ โดย module นี้จะเก็บ environment variable ทั้งหมดที่ OS ป้อนให้ process เราในรูปแบบ Dictionary
- วิธีการเก็บ password ใน environment variable เราสามารถเก็บผ่าน .profile หรือ .bashrc สำหรับทุกโปรเจ็ค แต่ถ้าเป็นโปรเจ็คเดี่ยวๆ จะแนะนำ .env มากกว่า และสำคัญที่สุดคือ อย่าพิมพ์ password ใน shell เพราะ shell เก็บ history ทุกอย่างที่พิมพ์ และไฟล์ .env ก็อย่า commit ลง git แต่ให้เขียน .gitignore กันไว้จะดีที่สุด
- Python มี Package ชื่อ python-dotenv เอาไว้ใช้สำหรับ load environment variable โดยเฉพาะ ซึ่งแค่แปะฟังก์ชั่น load_dotenv() ก่อนจะใช้ค่าใน env ก็ใช้ได้แล้วสะดวกมาก ไม่ต้องมานั่ง export env เอง ก่อนรัน app
- ถ้า environment variable ยังไม่ปลอดภัยพอ เรายังมีตัวเลือกอีกมากเช่น Vault (Hashicorp) / Parameter Store (AWS) / Secret Object (K8S) / Vault (Ansible) ซึ่งพวกนี้นอกจากจะเก็บ secret ให้เราแล้วยัง encrypt ให้ด้วย
DO and DON’T
- อย่าเขียน password / token ไว้ใน code
- จงเรียก Password / token จาก environment variable หรือ secret store
- จง Revoke ตัว secret เราที่เผลอเปิดเผยไปแล้ว
- อย่าใช้ service ที่ไม่มี option ในการ revoke access token
- อย่าใช้ password เดียวกันหลาย service
- อย่าใช้ credential เดียวกันทุก Users
Original Post on: https://yothinix.medium.com/100daysofpycon2018-day5-oops-i-committed-my-password-to-github-300fd7704a34