การสะท้อนกลับเสียเปรียบเนื่องจากไม่สามารถ จำกัด ตัวแปรส่วนตัวได้หรือไม่?


14

โมดิprivateฟายเออร์ใช้เพื่อ จำกัด การเข้าถึงภายนอกคลาส แต่การใช้การสะท้อนคลาสอื่น ๆ สามารถเข้าถึงเมธอดและฟิลด์ส่วนบุคคลได้ ดังนั้นฉันจึงสงสัยว่าเราจะ จำกัด การเข้าถึงได้อย่างไรถ้ามันเป็นส่วนหนึ่งของข้อกำหนด


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

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

6
google มันมีความอุดมสมบูรณ์ของรายการที่ซ้ำกัน: stackoverflow.com/questions/7566626/... , stackoverflow.com/questions/29246028/... , stackoverflow.com/questions/18619754/java-preventing-reflection ...
dagnelies

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

6
นี่ไม่ใช่คำถามเฉพาะทางภาษาใช่หรือไม่ Reflection ทำงานแตกต่างกันในภาษาที่ต่างกัน ฉันสงสัยว่าคำถามนี้ควรมีแท็กสำหรับ Java หรืออย่างอื่น
เวย์นคอนราด

คำตอบ:


54

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


33
สิ่งนี้ไม่เป็นความจริงในระดับสากล การอ้างถึงEric Lippert , "ตัวดัดแปลงการเข้าถึงใน CLR เป็นคุณลักษณะด้านความปลอดภัยกฎสำหรับการเข้าถึงนั้นได้รับการเปิดเผยอย่างละเอียดกับระบบความปลอดภัยและระบบความปลอดภัยของประเภท" ใน C # การสะท้อนจะใช้ได้เฉพาะกับรหัสที่ทำงาน สิ่งนี้ไม่ได้ (และไม่สามารถใช้) กับผู้ใช้ที่เป็นอันตรายของระบบที่ใช้รหัส อย่างไรก็ตามมันใช้กับปลั๊กอินที่เป็นอันตราย
Brian

5
@Brian ประเด็นที่ Brian กล่าวถึงมีความเกี่ยวข้องคือเมื่อระบบอนุญาตให้โค้ดของ บริษัท อื่นทำงานต่อโดยไม่ไว้วางใจอย่างเต็มที่ ตัวอย่างเช่นเบราว์เซอร์กล่องทราย (เช่นแอปเพล็เกลียดมาก) google เครื่องยนต์แอปและAzure มันจะโง่จริงๆสำหรับ Azure ที่จะอนุญาตให้โค้ดที่ไม่น่าเชื่อถือสำรวจรายละเอียดของไลบรารีหลักของแพลตฟอร์ม
JimmyJames

3
@Brian นั้นไม่ถูกต้อง 100% - มีการดำเนินการสะท้อนบางอย่างที่คุณสามารถทำได้ในรหัสที่เชื่อถือได้เพียงบางส่วน; มันไม่อนุญาตให้คุณทำสิ่งต่าง ๆ เช่นการเข้าถึงฟิลด์ส่วนตัว
Luaan

1
@Brian จนกระทั่งมีคนพบช่องโหว่หรือวิศวกรรมทางสังคมที่ช่วยให้พวกเขาสามารถข้ามข้อ จำกัด ได้ ไม่มีจุดใดในการพยายามใช้สิ่งเหล่านั้น นั่นไม่ใช่จุดประสงค์หลักของพวกเขา
jpmc26

31

ในการอ้างอิงHerb Sutter เกี่ยวกับสิทธิ์การเข้าถึงระดับ :

"ปัญหาในที่นี้คือการปกป้อง Murphy vs. การป้องกัน Machiavelli ... นั่นคือการป้องกันการใช้ในทางที่ผิดโดยไม่ตั้งใจ (ซึ่งภาษาทำได้ดีมาก) เทียบกับการป้องกันการละเมิดโดยเจตนา (ซึ่งเป็นไปไม่ได้อย่างมีประสิทธิภาพ) ในท้ายที่สุดถ้า โปรแกรมเมอร์ต้องการแย่มากพอที่จะล้มล้างระบบเขาจะหาทาง "


2
มีอยู่ครั้งที่คุณจำเป็นต้อง Sandbox รหัสที่ไม่น่าเชื่อถือ แต่ที่เป็นงานที่น่ากลัว การป้องกันข้อผิดพลาด (Murphy) เป็นกรณีที่พบได้บ่อยกว่ามาก
Paul Draper

#define private public(ไม่สนใจว่ามันเป็นพฤติกรรมที่ไม่ได้กำหนดจริง ๆ ) และ voila ฉันมีสิทธิ์เข้าถึงเต็มรูปแบบจากภายนอกสู่ส่วนที่จำกัดของชั้นเรียนของคุณ
bolov

การป้องกันการทารุณกรรมโดยเจตนาอาจเป็นไปไม่ได้ในทางทฤษฎีแต่เป็นไปได้อย่างมีประสิทธิภาพโดยการทำทารุณกรรมที่ยากพอเพียงซึ่งมันเกิดขึ้นน้อยมาก สิ่งสำคัญคือต้องมีความชัดเจนเกี่ยวกับเรื่องนี้ ไม่สามารถใช้ซอฟต์แวร์ได้ในทุกสถานการณ์เช่นอุปกรณ์การแพทย์ที่มีความสำคัญต่อชีวิต
MarkJ

@MarkJ คำพูดของ Herb Sutter นั้นเกี่ยวกับการละเมิดโดยเจตนาโดยผู้พัฒนาที่เขียนชั้นเรียนตั้งแต่แรกและอาจเป็นเพื่อนร่วมทีมของเขา ฉันไม่คิดว่าจะมีวิธีการป้องกันการใช้ภาษาในทางที่ผิด
Nemanja Trifunovic

@bolov การแสดงความสามารถนั้นขึ้นอยู่กับภาษาฉันคิดว่า ในขณะที่ตัวประมวลผลล่วงหน้า C / C ++ อาจช่วยให้คุณสามารถหลีกเลี่ยงสิ่งนั้นได้ แต่หากไม่มีสิ่งใดที่พวกเขาอาจจะทำให้เกิดข้อผิดพลาด "ไม่สามารถใช้คำที่สงวนไว้ใน #define" ได้
แดนเล่นซอโดย Firelight

10

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


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

4

คุณ จำกัด การเข้าถึงได้มากขึ้นโดยการเพิ่มขึ้นอีกระดับ: สภาพแวดล้อมการดำเนินการ

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

ข้อมูลเพิ่มเติมเกี่ยวกับการทำเช่นนี้ใน Java: Reflection Security


3

คุณกำลังพูดถึงเรื่องอะไร

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

หากคุณกังวลเกี่ยวกับการห่อหุ้มวิธีแก้ปัญหาง่ายๆคือการไม่ใช้ระบบการสะท้อนที่ไม่ได้เก็บรักษาไว้


3

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

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

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


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