ฉันจะสร้างและเข้าถึงไฟล์ temp จาก shell script ได้อย่างปลอดภัยได้อย่างไร?


14

ฉันได้อ่านแล้วว่าการเปลี่ยนเส้นทางเอาต์พุตไปยังไฟล์ชื่อคงที่/tmpอาจเป็นความเสี่ยงด้านความปลอดภัยเพราะหากผู้โจมตี (หรือผู้กระทำความผิด) สังเกตเห็นว่าไฟล์/tmp/tmpfileformyscript.tmpถูกสร้างขึ้นเมื่อฉันเรียกใช้สคริปต์ของฉัน (แม้ว่าเขาจะไม่สามารถเข้าถึงการอ่านของฉัน สคริปต์) ตัวอย่างเช่นเขาสามารถสร้าง symlink ln -s ~wildcard/.bashrc /tmp/tmpfileformyscript.tmpซึ่งจะทำให้ฉันทำลาย.bashrcไฟล์ของฉันเมื่อฉันเรียกใช้สคริปต์ของฉัน

ดังนั้นฉันสามารถใช้สิ่งที่ชอบfilename="tmpfile.tmp.$RANDOM" ; echo outputtext > "$filename"แทน

อย่างไรก็ตามฉันต้องการใช้ไฟล์ tmp สำหรับการแคชในบางครั้งซึ่งในกรณีนี้ฉันต้องการทราบว่า "tmpfile.tmp. *" ตรงกับทุกอย่างใน/tmpนั้นหรือไม่และใช้ไฟล์นั้นแทนการสร้างไฟล์ใหม่หรือไม่ น่าเสียดายtestและสิ่งที่เทียบเท่า[ -f filename ]ไม่สนับสนุนไฟล์ที่ทำให้กลมกลืนไปเท่าที่ฉันสามารถบอกได้

ดังนั้นคำถามของฉันคือสองเท่า:

  1. ฉันจะสร้าง tempfile อย่างปลอดภัยได้อย่างไร คือ"predictablename.$RANDOM"การปฏิบัติที่ได้รับการยอมรับหรือมีที่ดีกว่า (ความปลอดภัยมากขึ้นง่ายขึ้น) วิธี?
  2. ฉันจะเข้าถึงไฟล์และ / หรือสร้างการมีอยู่ของไฟล์ได้ในภายหลังโดยการตรวจสอบได้predictablenameอย่างไร?

คำตอบ:


13

ใช้mktempยูทิลิตีนี้เพื่อสร้างไฟล์ชั่วคราวที่มีชื่อที่ไม่สามารถคาดเดาได้ มันไม่ได้มาตรฐานโดย POSIX แต่มันมีอยู่ใน * BSD เช่นเดียวกับ Linux

> /tmp/predictable.$RANDOMไม่ใช่ตัวเลือกที่ดีเพราะสามารถคาดเดาได้ส่วนใหญ่ opens ซึ่งจะเปิดสคริปต์ของคุณไปยังการโจมตีที่ผู้โจมตีสามารถหลอกให้สคริปต์เขียนทับไฟล์ที่คุณเขียนเพื่อเข้าถึงหรือให้พวกเขาเข้าถึงไฟล์ชั่วคราว นี่เป็นช่องโหว่ของไฟล์ชั่วคราวที่ไม่ปลอดภัย mktempไม่มีช่องโหว่นี้เนื่องจากสร้างไฟล์อย่างปลอดภัย (จะไม่เขียนทับไฟล์ที่มีอยู่แม้ว่าลิงก์สัญลักษณ์จะเกี่ยวข้อง) และใช้ชื่อที่ไม่สามารถคาดเดาได้เพียงพอที่จะหลีกเลี่ยงการปฏิเสธการบริการ

หากสร้างไฟล์ชั่วคราวหนึ่งไฟล์และทำงานกับมันไม่ดีพอให้สร้างไดเรกทอรีชั่วคราวด้วยmktemp -dและทำงานที่นั่น

mktempยังระมัดระวังในการใช้$TMPDIRหากตัวแปรถูกตั้งค่าถอยกลับไปเป็น/tmpหากไม่ได้ตั้งค่าไว้

มีการตั้งค่าการกระจายมากขึ้นTMPDIRเพื่อเป็นไดเร็กทอรีส่วนตัวเช่นUID ของคุณอยู่/run/1234/tmpที่ไหน 1234นี้จะช่วยลดความเสี่ยงของช่องโหว่แฟ้มชั่วคราวที่ค่าใช้จ่ายของไม่มีความสามารถในการแบ่งปันไฟล์ชั่วคราวระหว่างผู้ใช้ (ซึ่งจะเป็นประโยชน์ในบางครั้ง แต่ไม่บ่อยมาก; /tmpยังคงมีอยู่เพียงแค่ไม่ได้TMPDIR)

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

CACHE_DIR="${XDG_CACHE_HOME:-"$HOME/.cache"}"/Wildcard-scripts
[ -d "$CACHE_DIR" ] || mkdir -p -- "$CACHE_DIR"
CACHE_FILE="$CACHE_DIR/tmpfileformyscript"

¹ ไม่เพียง$RANDOMแต่นำค่าที่เป็นไปได้ 32767 เท่านั้น แต่ยังง่ายต่อการคาดการณ์โดยไม่ต้องลองหลายค่า เครื่องสร้างตัวเลขสุ่มของ Bash คือLCG ที่ได้จาก PID และเวลาที่ใช้ครั้งแรก Zsh's เป็นแพลตฟอร์มที่randเริ่มต้นด้วยเวลาเริ่มต้น ATT Ksh's เป็นแพลตฟอร์มที่มาrandจาก PID Mksh's เป็น LCG ที่มีความซับซ้อนมากกว่า แต่ก็ยังไม่ใช่เมล็ดคุณภาพความปลอดภัย กระบวนการทั้งหมดสามารถคาดการณ์ได้โดยกระบวนการอื่นที่มีโอกาสประสบความสำเร็จค่อนข้างสูง


จริง ๆ แล้วการสนทนาของคุณ$TMPDIRและ~/.cacheเป็นสิ่งที่ฉันต้องการ หลังจากนั้นบางคนก็คิดว่าฉันรู้ว่าเหตุผลเดียวที่ฉันต้องการ/tmpคือแบ่งพาร์ติชัน - ดังนั้นแคชจึงไม่สามารถเติม/homeพาร์ติชันได้ แต่สำหรับกรณีการใช้งานนี้เป็นปัญหาที่ไม่สมบูรณ์ดังนั้นไดเรกทอรีย่อยที่ตรง~/.cacheกับความต้องการของฉันอย่างสมบูรณ์แบบและหลีกเลี่ยงปัญหาด้านความปลอดภัย
Wildcard

mktempไม่พร้อมใช้งานบน AIX หรือ Git shell บน Windows ดูเหมือนว่าfile.$RANDOM$RANDOMเป็นโซลูชั่นแบบพกพา $RANDOM$RANDOMควรเพิ่มพื้นที่ถึง 2 ^ 32 สมมติว่าทุบตีผลการสุ่มมีความเป็นอิสระและไม่อ่อนแอ

@jww ผลการสุ่มของ Bash นั้นอ่อนแอ: มันคือ LCG ซึ่งประมาณได้เท่าที่จะทำได้ในขณะที่ดีพอสำหรับแอพพลิเคชั่นมากมายที่ไม่ต้องการการคาดเดา
Gilles 'หยุดชั่วร้าย'

9

mktemp ถูกออกแบบมาเพื่อสิ่งนี้ จากหน้าคน:

TMPFILE=`mktemp /tmp/example.XXXXXXXXXX` || exit 1
echo "program output" >> $TMPFILE

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

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

ทั้งสองสามารถทำได้โดยใช้trapคำสั่ง


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