
هوش مصنوعی چه وقت باید دو پرونده مشتری را یکی بداند؟
نام و نشانی مشابه، هویت مشترک را ثابت نمیکند. راهنمای تطبیق پروندههای مشتری با شواهد قابلبررسی، مرز بازبینی انسانی و امکان بازگرداندن پیوند اشتباه.
ادامه مطلبتیم ژرف

در یادداشت یک درخواست پشتیبانی، عبارت =1+1 آمده است. دستیار آن را عیناً در گزارش میگذارد. فایل CSV درست ساخته میشود، اما وقتی گیرنده آن را با تنظیماتی که فرمول را تشخیص میدهند باز میکند، به جای متن اصلی عدد ۲ میبیند. مدل چیزی را اشتباه نقل نکرده؛ نرمافزار مقصد به متن، معنای دیگری داده است.
این مثال بیخطر و ساختهشده است، نه گزارش حمله به مشتری. مسئله آن برای سازنده گزارش واقعی است: کدام بخش از خروجی باید فقط داده بماند و چه کسی اجازه دارد فرمول ایجاد کند؟ پاسخ را باید در نویسنده فایل و مسیر ورود به صفحهگسترده پیاده کرد. درخواست «فرمول ننویس» از مدل، جای این مرز را نمیگیرد.
«خروجی گرفتن» یک مقصد واحد ندارد. یک فایل به برنامه پردازش داده میرود؛ دیگری با دوبار کلیک در اکسل باز میشود؛ سومی وارد گوگل شیتس میشود و بعد دوباره به CSV تبدیل میشود. اگر محصول همه را یک مسیر بداند، تنظیمی که برای یک گیرنده مناسب است به بقیه هم تحمیل خواهد شد.
برای مهندس محصول و مسئول تحویل گزارش، انتخاب پیشنهادی ژرف چنین است: اگر نوع سلول اهمیت دارد، آن را صریح بنویسید؛ اگر تنها گزینه CSV است، برنامه و تنظیمات ورود مورد پشتیبانی را محدود و آزمایش کنید. برای فایل ماشینی، متن اصلی و تعریف ستونها را حفظ کنید. فایل تغییریافته برای نمایش انسانی را بیتوضیح به عنوان داده خام تحویل ندهید.
از صاحب گزارش بپرسید آیا واقعاً فرمول لازم دارد یا فقط نتیجه محاسبه را میخواهد. گزارشِ صرفاً خواندنی معمولاً به مسیر ایجاد فرمول نیاز ندارد. اگر کاربر بعداً فایل را به قالب دیگری تبدیل کند، آن تبدیل یک مرز تازه است؛ تضمینِ نوع سلول در فایل اول، خودبهخود به فایل دوم منتقل نمیشود.
CSV ابتدا به ردیف و فیلد شکسته میشود. سپس برنامه صفحهگسترده تصمیم میگیرد محتوای هر فیلد متن، عدد، تاریخ یا فرمول است. درستبودن مرحله اول، نتیجه مرحله دوم را تعیین نمیکند. گیومهای که ویرگول داخل یادداشت را از جداکننده ستون متمایز میکند، الزاماً دستور «این سلول متن است» نیست.
سند RFC 4180 قواعد رایج نقلقول و جداکردن فیلدها را شرح میدهد؛ از جمله محصورکردن فیلد دارای ویرگول یا شکست خط و دوتاییکردن گیومه داخلی. این سند اطلاعاتیِ اکتبر ۲۰۰۵، قرارداد نوع سلول در اکسل نیست. برای ساخت CSV از نویسنده معتبر استفاده کنید، نه چسباندن رشتهها با ویرگول.
راهنمای تزریق CSV در OWASP خطر تفسیر داده نامطمئن به عنوان فرمول و محدودیت روشهای پاکسازی را توضیح میدهد. پیشوندهایی مانند مساوی، مثبت، منفی و اتساین و برخی نویسههای کنترلی در بررسی مصرفکننده اهمیت دارند؛ رفتار یکسان در همه برنامهها و زبانها را فرض نکنید. این خطر به معنی اجرای خودکار هر حمله در هر نسخه امروزی اکسل نیست.
تفاوت با تزریق دستور به مدل هم روشن است. در آنجا متن میکوشد رفتار مدل را عوض کند؛ اینجا مفسر صفحهگسترده پس از پایان کار مدل وارد عمل میشود. حتی نقل دقیق یک رشته، یا خروجی سامانهای بدون مدل زبانی، میتواند به همین مرز برسد.
شناسه 00123 عددی برای جمعزدن نیست. شماره تماس با علامت مثبت شروع میشود و مقدار منفی در ستون تعدادِ اصلاحشده ممکن است کاملاً معتبر باشد. حذف هر رشته دارای علامت منفی، امنیت را با خرابکردن داده اشتباه میگیرد. اول معنای ستون را تعیین کنید، سپس مقدار را مطابق همان معنا بپذیرید یا رد کنید.
تعریف خروجی بهتر است برای هر ستون نام ثابت، نوع، امکان خالیبودن، سقف طول، منبع و تبدیلهای مجاز داشته باشد. یادداشت، شناسه و متن استخراجشده در گروه رشته قرار میگیرند. عدد تنها پس از کنترل نوع، بازه و معنای کسبوکار وارد مسیر عددی میشود. مقدار خالی را هم با صفر یا رشته «نامعلوم» یکی نکنید.
قالب ساختاریافته کمک میکند فیلدها قابلبررسی باشند، ولی رشته معتبر هنوز ممکن است با مساوی شروع شود. راهنمای قرارداد خروجی ساختاریافته تفاوت اعتبار ساختار و درستی تصمیم را توضیح میدهد. اینجا یک شرط دیگر اضافه میکنیم: نویسنده فایل نباید رشته معتبر را با حدس خودش به فرمول ارتقا دهد.
واحد، ارز و گردکردن نیز مستقلاند. جلوگیری از فرمول ناخواسته، جمعِ ریال و تومان را درست نمیکند. پیش از نوشتن مقدار عددی، قرارداد مقدار و واحد را روشن کنید. برای مبلغ حساس یا شناسه بلند، حفظ دقت را هم جداگانه بیازمایید؛ نوع عددی صفحهگسترده راهحل عمومی دقت دلخواه نیست.
| مقصد واقعی | انتخاب پیشنهادی | شرطی که هنوز باقی میماند |
|---|---|---|
| گزارش خواندنی برای کاربر صفحهگسترده | XLSX با نوشتن صریح رشته و عدد | نویسنده فایل، اجزای بسته و برنامههای مورد پشتیبانی بررسی شوند |
| ارسال مقدار به گوگل شیتس | ورودی RAW و نوع مقدار مطابق تعریف ستون | مجوز، محدوده نوشتن و صحت داده جدا کنترل شوند |
| سامانه ماشینی دریافتکننده CSV | CSV استاندارد همراه تعریف ستون و حفظ مقدار اصلی | واردکننده نباید به حدس نوع یا تنظیمات نامعلوم متکی باشد |
| کاربر انسانی که فقط CSV میپذیرد | روش ورود مشخص و آزموده برای همان برنامه | بازکردن مستقیم و تبدیل بعدی بیرون از دامنه تضمین نماند |
این جدول پیشنهاد طراحی است، نه رتبهبندی امنیت محصولات. پسوند XLSX بهتنهایی چیزی را ثابت نمیکند؛ چنین فایلی هم میتواند فرمول داشته باشد. مزیت موردنظر، امکان تعیین صریح نوع است. اگر مسیر گیرنده را نمیشناسید، وعده «CSV امن در همهجا» ندهید؛ قالب یا دامنه پشتیبانی را تغییر دهید.
همچنین لازم نیست برای هر گزارش دو نسخه بسازید. اگر فقط یک مقصد کنترلشده دارید، همان را خوب تعریف کنید. دو نسخه زمانی معنا دارد که نیاز ماشین به متن دستنخورده با نیاز نمایش انسانی ناسازگار شود. نام و توضیح نسخهها باید این تفاوت را به گیرنده نشان دهد.
در XlsxWriter، تابع عمومی write() نوع مقدار را بررسی میکند و برای بعضی رشتهها مسیر فرمول یا پیوند را برمیگزیند. راهنمای نوشتن داده توابع اختصاصی مانند write_string() و write_number() را جدا معرفی میکند. برای ستون یادداشت، انتخاب تابع اختصاصی از حدسزدن معنای رشته روشنتر است.
مستندات سازنده Workbook میگوید تبدیل رشته به فرمول و پیوند در تابع عمومی بهطور پیشفرض فعال است؛ تبدیل رشته به عدد پیشفرض غیرفعال دارد. میتوان هر سه را صریح غیرفعال کرد. این تنظیمها جلوی فراخوانی مستقیم تابع نوشتن فرمول توسط کد دیگری را نمیگیرند.
نمونه کوچک زیر فقط مرز نوشتن متن را نشان میدهد. فایل در حافظه ساخته میشود؛ هیچ فرمولی اجرا نمیشود. سقف دههزار نویسه، انتخاب آموزشی ماست، نه محدودیت ادعاشده نرمافزار:
from io import BytesIO
import xlsxwriter
def text_export(values):
output = BytesIO()
options = {
"in_memory": True,
"strings_to_formulas": False,
"strings_to_urls": False,
"strings_to_numbers": False,
}
with xlsxwriter.Workbook(output, options) as book:
sheet = book.add_worksheet("Report")
for row, value in enumerate(values):
if not isinstance(value, str) or not 1 <= len(value) <= 10_000:
raise ValueError("Expected bounded, non-empty text")
if sheet.write_string(row, 0, value) != 0:
raise ValueError("Cell write failed")
return output.getvalue()
خروجی را فقط پس از بستهشدن موفق کتاب کار تحویل دهید. این تابع عمداً مقدار تهی و رشته خالی را رد میکند؛ محصول واقعی باید سیاست آنها را صریح تعریف کند. شمار ردیف، سقف اندازه فایل، خطای ساخت بسته و رفتار همه ستونها هم مسئولیت فراخواننده است. این کد صادرکننده کامل سازمانی نیست.
عنوان ستون و نام برگه را در اختیار قالب ثابت برنامه بگذارید. داده کاربر نباید نام فایل، مسیر ذخیره یا ساختار کتاب کار را بیواسطه تعیین کند. همچنین تغییر یک گزینه در کتابخانه کافی نیست اگر لایه دیگری بعداً همان مقدار را با تابع عمومی یا در CSV دوباره بنویسد.
در مرجع ValueInputOption گوگل، حالت RAW مقدار را بدون تجزیه ذخیره میکند؛ USER_ENTERED آن را مانند ورود از رابط کاربر تفسیر میکند. برای متن نامطمئن، حالت اول با هدف ما سازگار است. بااینحال، مقدار را ابتدا مطابق ستون بررسی کنید؛ خامنوشتن، عدد نادرست را درست یا مقصد غیرمجاز را مجاز نمیکند.
در Calc نیز راهنمای ورود متن LibreOffice گزینه ارزیابی فرمول، نوع متنی ستون و واردکردن فیلد نقلقولشده به صورت متن را توضیح میدهد. زبان انتخابشده بر تشخیص عدد اثر دارد. برای مسیر CSV، دستورالعمل ورود باید این انتخابها را مشخص کند؛ اتکا به تنظیمات باقیمانده از واردکردن فایل قبلی کافی نیست.
این رفتارهای مستند، جای آزمون نسخه نصبشده را نمیگیرند. اگر تیم هم اکسل و هم Calc را پشتیبانی میکند، برای هرکدام مسیر ورود جدا ثبت کند. نام مشترک CSV، تضمین مشترک رفتار نمیسازد. تغییر زبان دستگاه یا تبدیل فایل به قالب دیگر را هم تغییر در محیط مصرف بدانید.
افزودن آپاستروف یا نویسه کنترلی شاید در مسیر مشخصی مانع تفسیر فرمول شود، ولی مقدار اصلی را تغییر میدهد. گیرنده ماشینی ممکن است همان پیشوند را بخشی از شناسه بداند. حذف خودکار آن در مرحله بعد هم میتواند حفاظ را از بین ببرد. OWASP درباره محدودیت روشهای پیشوندی و ذخیره و بازکردن دوباره هشدار میدهد؛ نسخه واحدی برای همه مصرفکنندگان ارائه نمیکند.
پیشنهاد ما این است که تغییر متن فقط با قاعده مصوب، ثبت نوع تغییر و آزمون مسیر کامل انجام شود. مقدار اصلی را در محل مجاز و محدود نگه دارید، نه الزاماً در همان فایل خروجی. کاربر نباید برای بازیابی شناسه درست مجبور شود حدس بزند کدام فاصله یا پیشوند را حذف کند.
«تعداد سلول پاکسازیشده» بهتنهایی سنجه خوبی نیست. آیا آنها هنوز همان مشتری، شماره سفارش و یادداشت را نشان میدهند؟ اگر راهکار صددرصد رشتهها را بیخطر کند اما شناسهها را تغییر دهد، گزارش از نظر عملیاتی قابلاعتماد نشده است.
اگر گزارش واقعاً محاسبه داخل فایل میخواهد، فرمول را قالب بازبینیشده برنامه تولید کند؛ مقدار مدل ورودی آن باشد، نه متن خود فرمول. حتی در این حالت، نوع و بازه ورودی را بررسی کنید. الحاق رشته نامطمئن به عبارت فرمول، جداسازی را دوباره از بین میبرد.
در پیشنهاد ژرف، فهرست سلولهای فرمولدار و قالب هر فرمول از پیش معلوم است. سایر سلولها نباید فرمول داشته باشند. برای گزارش صرفاً دادهای، انتظار صفر فرمول سادهتر است. اگر مدل فرمول پیشنهاد میدهد، پیشنهاد را به صورت متن برای بازبینی نگه دارید و تبدیل آن به فرمول فعال را اقدام مستقلی بدانید.
اگر نتیجه ثابت نیاز کاربر را برآورده میکند، محاسبه مصوب را پیش از ساخت فایل انجام دهید و منشأ نتیجه را همراهش نگه دارید. البته فایل وعدهدادهشده با قابلیت محاسبه مجدد را بیخبر به چند عدد ثابت تبدیل نکنید. این انتخاب بخشی از رفتار اعلامشده گزارش است، نه جزئیات پنهان پیادهسازی.
کنترل مقصد و محرمانگی همچنان لازم است. رشته کاملاً بیاثر هم ممکن است داده مشتری دیگری باشد. راهنمای مجوز انتشار خروجی این مرز را از مجوز خواندن جدا میکند. نوع امن سلول، اجازه ارسال گزارش به هر گیرندهای نیست.
مجموعه آزمون را با عبارت بیخطر =1+1، رشته دارای مثبت و اتساین، متن منفی و عدد منفی واقعی، شناسه با صفر ابتدایی، ویرگول، گیومه، شکست خط، تب، بازگشت سطر و متن فارسی بسازید. گونههای تمامعرض علامتها و فاصلههای ابتدایی نیز برای مسیرهای چندزبانه مفیدند. هدف اجرای حمله نیست؛ هدف مشاهده نوع و حفظ مقدار است.
برای هر مورد، پاسخ مورد انتظار را پیش از تولید فایل بنویسید: رشته همان رشته بماند، عدد تأییدشده عدد بماند و ورودی خارج از تعریف رد شود. پس از ساخت XLSX، اجزای XML را بررسی کنید تا سلولهای نامطمئن گره فرمول نداشته باشند. رشته بازیابیشده، تعداد ردیفها و نبود پیوند خودکار ناخواسته را نیز کنترل کنید.
این بررسی ساختاری رفتار همه برنامههای صفحهگسترده را ثابت نمیکند. در آزمون محصول، فایل را با نسخه و تنظیمات اعلامشده وارد، ذخیره و دوباره باز کنید؛ اگر تبدیل به CSV جزو کاربرد است، همان مسیر را هم بیازمایید. از نمونه ساختگی استفاده کنید تا آزمون، داده واقعی را افشا نکند. تصویر پیشنمایش برای اثبات نوع سلول کافی نیست.
برای پذیرش انتشار، شمار فرمول غیرمنتظره، اختلاف رشته پس از رفتوبرگشت، ردیف ازدسترفته و بریدگی متن را ثبت کنید. افزایش رد ورودی را جدا بررسی کنید؛ شاید تعریف ستون تغییر کرده باشد، نه اینکه حمله بیشتر شده است. پس از ارتقای کتابخانه، تغییر تنظیمات ورود، زبان یا قالب خروجی، همین نمونهها را دوباره اجرا کنید.
در کتاب کار دارای فرمول مصوب، محل و عبارت فرمولها را با فهرست مجاز تطبیق دهید؛ وجود چند فرمول مورد انتظار، بقیه را مجاز نمیکند. ورودی خالی و بیشازحد بلند هم باید پاسخ آزمون مشخص داشته باشد. داده حساس را وارد گزارش روزمره خطا نکنید؛ نام قاعده و شاهد لازم برای بررسی را با دسترسی محدود نگه دارید. یک مسئول نیز باید فهرست برنامهها و مسیرهای مورد پشتیبانی را بهروز کند.
رفتار ابزارها از مستندات زیر آمده است. جدول انتخاب، تعریف ستون، نمونه کد و معیارهای پذیرش، پیشنهاد مهندسی ژرفاند؛ مقاله آزمون جامع امنیت اکسل یا گزارش حادثه نیست. بررسی ساخت فایل با آزمون اجرای آن در برنامه مقصد تفاوت دارد.

نام و نشانی مشابه، هویت مشترک را ثابت نمیکند. راهنمای تطبیق پروندههای مشتری با شواهد قابلبررسی، مرز بازبینی انسانی و امکان بازگرداندن پیوند اشتباه.
ادامه مطلب
متن روان جلسه شاید جملهای داشته باشد که هیچکس نگفته است. راهنمای حفظ صدای اصلی، بررسی سکوت و جداکردن پیشنویس از حرفی که به سند و تعهد تبدیل میشود.
ادامه مطلب
وقتی دستیار ترتیب کار در یک صف مشترک را عوض میکند، گروه کنترل هم اثر میگیرد. راهنمای انتخاب مرز تخصیص، مهار اثر باقیمانده و سنجش نتیجهای که قرار است اجرا شود.
ادامه مطلباگر این مطلب به یک سامانه واقعی در سازمان شما مربوط است، از خدمات و مطالعه موردی شروع کنید.