printf ไม่ปลอดภัยที่จะใช้ใน C
ฉันยังใหม่กับ C ดังนั้นฉันจึงเริ่มเล่นกับโค้ด ฉันมีข้อบกพร่องในรหัสของฉันเนื่องจากฉันเชื่อว่าการใช้printf(pass)ไม่ปลอดภัยที่จะใช้เนื่องจากสามารถเขียนทับค่าได้และด้วยเหตุนี้จึงไม่ปลอดภัยสำหรับผู้ใช้ ฉันสงสัยว่าฉันพูดถูกprintf(pass)หรือเปล่าที่ไม่ปลอดภัยในรหัสของฉัน นอกจากนี้ฉันจะให้ผู้ใช้พิมพ์ข้อความfinally logged inโดยไม่เปลี่ยนรหัสได้อย่างไร มีวิธีใดบ้างที่จะทำเช่นนั้น?
รหัสของฉัน:
#include <stdio.h>
char pass[100];
char getPass() {
int value = 'G';
int * j = & value;
fgets(pass, sizeof(pass), stdin);
printf("your entered pass is ");
printf(pass);
return (char)( * j);
}
void main() {
printf("enter the pass here ");
if (getPass() == 'K') {
printf("finally logged in\n");
exit(0);
} else {
printf("Wrong password\n");
exit(1);
}
}
คำตอบ
ใช่มันไม่ปลอดภัย แต่ไม่ใช่ด้วยเหตุผลที่คุณแนะนำ หากคุณตรวจสอบmanหน้าสำหรับprintf()ฟังก์ชันคุณจะเห็นว่ามีต้นแบบดังต่อไปนี้:
int printf(const char * restrict format, ...);
constปรับปรุงนำไปใช้ระบุอาร์กิวเมนต์แรกว่าค่าของพารามิเตอร์นี้จะไม่เปลี่ยนแปลงเมื่อคุณเรียกใช้ฟังก์ชันนี้
formatแต่คุณจะสังเกตเห็นว่าพารามิเตอร์นี้จะถูกเรียกว่า นั่นเป็นเพราะมันควรจะระบุสตริงรูปแบบ ในโปรแกรมของคุณไม่มีอะไรที่จะหยุดผู้ใช้ที่ป้อนตัวระบุรูปแบบเช่น%pในกรณีนี้การโทรของคุณprintf()จะเริ่มพิมพ์เนื้อหาของสแต็ก มีบทความ Wikipediaที่อธิบายช่องโหว่นี้โดยละเอียด
ฟังก์ชั่นfgetsหากการโทรสำเร็จจะให้สตริงที่คุณสามารถส่งออกได้
ปัญหาอาจเกิดขึ้นได้หากสตริงที่ได้รับออกมาในลักษณะนี้
printf(pass);
และมีการระบุการแปลง
ดังนั้นแทนที่จะเรียกว่า
printf(pass);
ปลอดภัยกว่าในการใช้งาน
printf( "%s", pass );
หรือ
puts(pass);
fgetsเบื้องต้นคุณสามารถเอาตัวอักษรบรรทัดใหม่เก็บไว้ในสตริงโดยการเรียกร้องของ