زمان بررسی تا زمان استفاده

زمان بررسی تا زمان استفاده (به اختصار TOCTTOU یا TOCTOU، به صورت TOCK too تلفظ می‌شود) نام یک دسته از باگ‌های نرم‌افزاری است. در خیلی از برنامه‌ها ابتدا یک شرط بررسی می‌شود و سپس از نتیجه آن شرط در جای دیگری استفاده می‌شود. این عمل اتمی و تجزیه‌ناپذیر نیست و بین زمان بررسی کردن یک شرط و زمان استفاده از نتایج آن، یک حفره زمانی وجود دارد. این حفره زمانی این امکان را ایجاد می‌کند که پس از بررسی کردن اولیه شرط، نتایج آن توسط یک رویداد خارجی تغییر کند، در نتیجه، وقتی که برنامه قصد استفاده از نتایج را دارد، آن نتایج دیگر معتبر نخواهند بود، چرا که تغییر یافته‌اند. این باگ، نوعی شرایط رقابتی است.
به عنوان یک مثال ساده، می‌توان یک برنامه وب را تصور کرد که به کاربران اجازه می‌دهد تا صفحات را ویرایش کنند، همچنین به مدیران هم اجازه می‌دهد تا آن صفحه را قفل کرده و مانع از ویرایش آن توسط دیگر کاربران شوند. کاربری درخواست ویرایش آن صفحه را می‌دهد، و فرمی برای او باز می‌شود که از طریق آن می‌تواند صفحه مورد نظر را ویرایش کند، قبل از اینکه کاربر صفحه را ارسال کند و تغییرات در آن صفحه اعمال شوند، یک مدیر آن صفحه را قفل می‌کند، که مانع از ویرایش آن توسط کاربر می‌شود. با این حال، از آنجا که عمل ویرایش از قبل شروع شده است، وقتی که کاربر تغییراتش را در صفحه ذخیره می‌کند، تغییرات او مورد قبول واقع می‌شود.وقتی که کاربر شروع به ویرایش می‌کند، اختیارات او بررسی می‌شود و به کاربر اجازه ویرایش صفحه داده می‌شود. با این حال، اختیارات او بعدا مورد استفاده قرار می‌گیرند، وقتی که کاربر دیگر نباید اجازه ویرایش داشته باشد.
این نوع از باگ‌ها، عمدتا در سیستم‌عامل یونیکس در حین کار کردن با فایل‌سیستم رایج هستند، اما در جای‌های دیگر هم می‌توانند اتفاق بیوفتند، مثلا در حین کار با متغیرهای سراسری. در اوایل دهه ۱۹۹۰، برنامه mail در بی‌اس‌دی نسخه ۴٫۳ یک جور شرایط رقابتی در حین کار با فایل‌های موقت داشت که امکان سوء استفاده از آن هم وجود داشت. این برنامه از mktemp() استفاده می‌کرد (که هم‌اکنون منسوخ شده و mkstemp() جایگزین آن شده). نسخه‌های اولیه اوپن‌اس‌اس‌اچ هم در حین کار با سوکت‌های دامنه یونیکس یک شرایط رقابتی داشتند.
مثال
در یونیکس، اگر کد زیر در برنامه‌ای که setuid است استفاده شود، یک باگ TOCTTOU خواهد داشت:
if (access("file", W_OK) != 0) {
exit(1);
fd = open("file", O_WRONLY);
write(fd, buffer, sizeof(buffer));
در اینجا، از فراخوان access استفاده شده تا بررسی شود که آیا کاربر واقعی که برنامه را اجرا کرده قادر به نوشتن در فایل است یا نه. access شناسه واقعی را چک می‌کند، نه شناسه موثر را.
از این شرایط رقابتی می‌توان به شکل زیر سوءاستفاده کرد:
Victim
Attacker
if (access("file", W_OK) != 0) {
exit(1);
fd = open("file", O_WRONLY);
// Actually writing over /etc/passwd
write(fd, buffer, sizeof(buffer));
// After the access check
symlink("/etc/passwd", "file");
// Before the open, "file" points to the password database
در مثال بالا، یک مهاجم می‌تواند از حفره زمانی بین بررسی کردن مجوز فایل (access) تا باز کردن آن (open)، سوءاستفاده کند و برنامه را فریب بدهد تا به جای فایل مورد نظرش، طالاعاتش را در پایگاه داده کلمه عبور کاربران سیستم بنویسد. از باگ‌های TOCTTOU می‌توان به همراه ترفیع امتیازی استفاده کرد تا دسترسی مدیریتی به سیتسم بدست آورد.
هرچند که روی دادن چنین توالی از اتفاقات نیازمند زمان‌بندی کردن دقیق است، یک مهاجم می‌تواند بودن سختی زیاد چنین کاری را انجام دهد.
برنامه‌ها نمی‌توانند این تصور را داشته باشند که بین زمان بررسی و زمان استفاده، هیچ تغییری رخ نخواهد داد.