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

از Secure Coding

سطر ۱: سطر ۱:
تست
+
هنگامی که از توابع ورودی بر اساس فرمتی استفاده می کنید، ممکن است مهاجم بتواند با رشته فرمت شده بتواند پروسه آسیب پذیری را crash کند و بتواند محتوای stack، محتوای memory بخواند و یا در محتوا حافظه مقداری را بنویسند و یا امکان اجرای کد با استفاده از دسترسی پروسه آسیب پذیر امکان پذیر است.
 +
 
 +
همچنین استفاده از توابع خروجی ممکن است دارای ریسک باشد.
 +
 
 +
برای مثال توابع خروجی بر اساس فرمت می توانند مقدار integer را در آدرسی خاص با استفاده از %n بنویسند.
 +
 
 +
در مثال زیر تابع incorrect_password() هنگام احراز هویت و نادرست بودن کلمه عبور پیام خطایی را چاپ می کند.
 +
 
 +
کد، نام کاربر را با user بدون هیچ گونه فیلتر از کاربر دریافت می کند.
 +
 
 +
پیام خطا در stderr و با استفاده از تابع fprintf چاپ می شود.
 +
 
 +
<div lang="en" dir="ltr" class="mw-content-ltr">
 +
<pre>
 +
#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);
 +
}
 +
</pre>
 +
</div>
 +
 
 +
در کد بهبود یافته زیر از تابع fputs() برای خروجی msg در stderr استفاده شده است.
 +
 
 +
<div lang="en" dir="ltr" class="mw-content-ltr">
 +
<pre>
 +
#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);
 +
}
 +
</pre>
 +
</div>
 +
 
 +
 
 +
 
 +
 
 +
 
 +
 
 +
 
  
 
[[category:ورودی و خروجی(FIO)]]
 
[[category:ورودی و خروجی(FIO)]]

نسخهٔ ‏۶ مارس ۲۰۲۰، ساعت ۱۳:۵۳

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

همچنین استفاده از توابع خروجی ممکن است دارای ریسک باشد.

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

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

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

پیام خطا در stderr و با استفاده از تابع fprintf چاپ می شود.

#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);
}