نسخهٔ فعلی |
متن شما |
سطر ۱: |
سطر ۱: |
− | هنگامی که از توابع ورودی و خروجی بر اساس فرمتی استفاده می کنید، ممکن است مهاجم بتواند با رشته فرمت شده بتواند پروسه آسیب پذیری را crash کند و بتواند محتوای stack، محتوای memory بخواند و یا در محتوا حافظه مقداری را بنویسند و یا امکان اجرای کد با استفاده از دسترسی پروسه آسیب پذیر امکان پذیر است.
| |
− |
| |
− | توابع خروجی بر اساس فرمت می توانند مقدار integer را در آدرسی خاص با استفاده از %n بنویسند.
| |
− |
| |
− | برای مثال در کدر زیر تابع incorrect_password() هنگام احراز هویت و نادرست بودن کلمه عبور پیام خطایی را چاپ می کند.
| |
− |
| |
− | کد، نام کاربر را با user بدون هیچ گونه فیلتر از کاربر دریافت می کند.
| |
− |
| |
− | پیام خطا در stderr و با استفاده از تابع fprintf چاپ می شود و هیچگونه کنترلی بر روی مقدار integer وارد شده و overflow آن نیست.
| |
− |
| |
− | همپنین معمولا تابع ()snprintf برای نمایش پیام از چند نقطه استفاده می شود و در این کد msg بدون هیچ گونه کنترلی و به صورت مستقیم، ورودی کاربر را در snprintf استفاده می نماید.
| |
− |
| |
− | <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)]] |