فرمت داده ها: تفاوت بین نسخه‌ها

از Secure Coding

 
(یک نسخهٔ میانیِ همین کاربر نمایش داده نشده است)
سطر ۱: سطر ۱:
هنگامی که از توابع ورودی بر اساس فرمتی استفاده می کنید، ممکن است مهاجم بتواند با رشته فرمت شده بتواند پروسه آسیب پذیری را crash کند و بتواند محتوای stack، محتوای memory بخواند و یا در محتوا حافظه مقداری را بنویسند و یا امکان اجرای کد با استفاده از دسترسی پروسه آسیب پذیر امکان پذیر است.
+
هنگامی که از توابع ورودی و خروجی بر اساس فرمتی استفاده می کنید، ممکن است مهاجم بتواند با رشته فرمت شده بتواند پروسه آسیب پذیری را crash کند و بتواند محتوای stack، محتوای memory بخواند و یا در محتوا حافظه مقداری را بنویسند و یا امکان اجرای کد با استفاده از دسترسی پروسه آسیب پذیر امکان پذیر است.
 
 
همچنین استفاده از توابع خروجی ممکن است دارای ریسک باشد.
 
  
 
توابع خروجی بر اساس فرمت می توانند مقدار integer را در آدرسی خاص با استفاده از %n بنویسند.
 
توابع خروجی بر اساس فرمت می توانند مقدار integer را در آدرسی خاص با استفاده از %n بنویسند.
سطر ۹: سطر ۷:
 
کد، نام کاربر را با user بدون هیچ گونه فیلتر از کاربر دریافت می کند.
 
کد، نام کاربر را با user بدون هیچ گونه فیلتر از کاربر دریافت می کند.
  
پیام خطا در stderr و با استفاده از تابع fprintf چاپ می شود و هیچگونه کنترلی بر روی مقدار integer وارد شده و overflow آن ندارد.
+
پیام خطا در stderr و با استفاده از تابع fprintf چاپ می شود و هیچگونه کنترلی بر روی مقدار integer وارد شده و overflow آن نیست.
 +
 
 +
همپنین معمولا تابع ()snprintf برای نمایش پیام از چند نقطه استفاده می شود و در این کد msg بدون هیچ گونه کنترلی و به صورت مستقیم، ورودی کاربر را در snprintf استفاده می نماید.
  
 
<div lang="en" dir="ltr" class="mw-content-ltr">
 
<div lang="en" dir="ltr" class="mw-content-ltr">
سطر ۳۷: سطر ۳۷:
 
</pre>
 
</pre>
 
</div>
 
</div>
 
کد
 
  
 
در کد بهبود یافته زیر از تابع ()fputs برای خروجی msg در stderr استفاده شده است.
 
در کد بهبود یافته زیر از تابع ()fputs برای خروجی msg در stderr استفاده شده است.

نسخهٔ کنونی تا ‏۶ مارس ۲۰۲۰، ساعت ۱۴:۱۲

هنگامی که از توابع ورودی و خروجی بر اساس فرمتی استفاده می کنید، ممکن است مهاجم بتواند با رشته فرمت شده بتواند پروسه آسیب پذیری را crash کند و بتواند محتوای stack، محتوای memory بخواند و یا در محتوا حافظه مقداری را بنویسند و یا امکان اجرای کد با استفاده از دسترسی پروسه آسیب پذیر امکان پذیر است.

توابع خروجی بر اساس فرمت می توانند مقدار integer را در آدرسی خاص با استفاده از %n بنویسند.

برای مثال در کدر زیر تابع incorrect_password() هنگام احراز هویت و نادرست بودن کلمه عبور پیام خطایی را چاپ می کند.

کد، نام کاربر را با user بدون هیچ گونه فیلتر از کاربر دریافت می کند.

پیام خطا در stderr و با استفاده از تابع fprintf چاپ می شود و هیچگونه کنترلی بر روی مقدار integer وارد شده و overflow آن نیست.

همپنین معمولا تابع ()snprintf برای نمایش پیام از چند نقطه استفاده می شود و در این کد msg بدون هیچ گونه کنترلی و به صورت مستقیم، ورودی کاربر را در snprintf استفاده می نماید.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
  
void incorrect_password(const char *user) {
  int ret;
  /* User names are restricted to 256 or fewer characters */
  static const char msg_format[] = "%s cannot be authenticated.\n";
  size_t len = strlen(user) + sizeof(msg_format);
  char *msg = (char *)malloc(len);
  if (msg == NULL) {
    /* Handle error */
  }
  ret = snprintf(msg, len, msg_format, user);
  if (ret < 0) { 
    /* Handle error */ 
  } else if (ret >= len) { 
    /* Handle truncated output */ 
  }
  fprintf(stderr, msg);
  free(msg);
}

در کد بهبود یافته زیر از تابع ()fputs برای خروجی msg در stderr استفاده شده است.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
  
void incorrect_password(const char *user) {
  int ret;
  /* User names are restricted to 256 or fewer characters */
  static const char msg_format[] = "%s cannot be authenticated.\n";
  size_t len = strlen(user) + sizeof(msg_format);
  char *msg = (char *)malloc(len);
  if (msg == NULL) {
    /* Handle error */
  }
  ret = snprintf(msg, len, msg_format, user);
  if (ret < 0) { 
    /* Handle error */ 
  } else if (ret >= len) { 
    /* Handle truncated output */ 
  }
  fputs(msg, stderr);
  free(msg);
}