به گزارش زوم تک، ابزارهای کدنویسی مبتنی بر هوش مصنوعی می توانند در مدت کوتاهی کدهای کاربردی تولید کنند، اما همین ابزارها ممکن است الگوهای ناامن موجود در داده های آموزشی خود را نیز با سرعت زیادی تکرار کنند. بر اساس تحقیقات Sonar، مدل Claude Opus 4.6 Thinking در آزمایش های این شرکت به ازای هر یک میلیون خط کد، ۶۴ آسیب پذیری با شدت Blocker ایجاد کرده است.
در نظرسنجی Sonar از بیش از ۱۱۰۰ توسعه دهنده نیز مشخص شده است که ۹۶ درصد از توسعه دهندگان اعتماد کامل به کد تولیدشده توسط هوش مصنوعی ندارند، اما تنها ۴۸ درصد اعلام کرده اند که همیشه کد تولیدشده توسط AI را پیش از Commit کردن بررسی می کنند.
مشکلات امنیتی ایجادشده توسط ابزارهای هوش مصنوعی معمولا آسیب پذیری های عجیب و ناشناخته ای نیستند. بخش زیادی از آن ها همان مشکلاتی مانند Injection، افشای اطلاعات احراز هویت و خطاهای رمزنگاری هستند که سال ها در فهرست آسیب پذیری های مهم امنیتی قرار داشته اند. تفاوت اصلی در مقیاس تولید کد است؛ ابزارهای هوش مصنوعی می توانند این الگوهای ناامن را بسیار سریع تر از توانایی بررسی دستی توسعه دهندگان تولید کنند.
چرا ابزارهای هوش مصنوعی کد ناامن تولید می کنند؟
مدل های زبانی بزرگ برای یادگیری برنامه نویسی از منابعی مانند مخازن متن باز، پاسخ های Stack Overflow، آموزش های اینترنتی و کدهای قدیمی استفاده می کنند. بسیاری از این منابع حاوی باگ و آسیب پذیری امنیتی هستند.
تحقیقات SonarSweep نیز این موضوع را بررسی کرده است. بر اساس این تحقیق، مدل هایی که با داده های آموزشی پاکسازی شده آموزش دیده بودند، در مقایسه با مدل هایی که از داده های پاکسازی نشده استفاده کرده بودند، تا ۶۷ درصد آسیب پذیری امنیتی کمتر و تا ۴۲ درصد باگ کمتری ایجاد کردند.
از طرف دیگر، مدل های زبانی سیستم هایی احتمالاتی هستند. حتی اگر یک مدل الگوی برنامه نویسی امن را یاد گرفته باشد، تضمینی وجود ندارد که در تمام دفعات همان روش امن را انتخاب کند. یک درخواست مشابه ممکن است یک بار به تولید Query پارامتری منجر شود و بار دیگر کدی مبتنی بر اتصال مستقیم رشته ها تولید کند.
۱. آسیب پذیری SQL Injection
قانون تشخیص: pythonsecurity:S3649
شدت: Blocker
CWE: CWE-89
زمانی که از یک ابزار هوش مصنوعی خواسته می شود یک Endpoint برای دریافت اطلاعات از پایگاه داده ایجاد کند، ممکن است مدل به سراغ اتصال مستقیم رشته ها برود.
@app.route("/api/tasks")
def get_tasks():
status = request.args.get("status", "")
assignee = request.args.get("assignee", "")
conn = sqlite3.connect(DB_PATH)
cursor = conn.cursor()
query = "SELECT * FROM tasks WHERE status = '" + status + "'"
if assignee:
query += " AND assignee = '" + assignee + "'"
cursor.execute(query)
rows = cursor.fetchall()
conn.close()
tasks = [{"id": r[0], "title": r[1], "status": r[2], "assignee": r[3]} for r in rows]
return {"tasks": tasks}این کد در نگاه اول مرتب و منطقی به نظر می رسد و برای ورودی های معمول نیز به درستی کار می کند. اما مهاجم می تواند ورودی مخربی را به پارامتر status ارسال کند و ساختار Query را تغییر دهد تا اطلاعات بیشتری از جدول دریافت کند.
راهکار مناسب استفاده از Queryهای پارامتری است:
@app.route("/api/tasks", methods=["GET"])
def get_tasks():
status = request.args.get("status", "")
assignee = request.args.get("assignee", "")
conn = sqlite3.connect(DB_PATH)
cursor = conn.cursor()
if assignee:
cursor.execute(
"SELECT * FROM tasks WHERE status = ? AND assignee = ?",
(status, assignee),
)
else:
cursor.execute("SELECT * FROM tasks WHERE status = ?", (status,))
rows = cursor.fetchall()
conn.close()
tasks = [{"id": r[0], "title": r[1], "status": r[2], "assignee": r[3]} for r in rows]
return jsonify({"tasks": tasks})یکی از دلایلی که مدل های هوش مصنوعی به سمت اتصال مستقیم رشته ها می روند، فراوانی این الگو در آموزش ها و کدهای قدیمی است. در نتیجه ممکن است کدی تولید شود که از نظر ظاهری کاملا منطقی باشد اما آسیب پذیری آن در نگاه اول مشخص نباشد.
۲. آسیب پذیری Reflected XSS
قانون تشخیص: pythonsecurity:S5131
شدت: Blocker
CWE: CWE-79
اگر از ابزار هوش مصنوعی بخواهید یک صفحه جستجو ایجاد کند، ممکن است مدل برای ساخت HTML از F-string استفاده کند.
@app.route("/search")
def search():
query = request.args.get("q", "")
results = perform_search(query)
html = f"""
<html>
<head><title>Search Results</title></head>
<body>
<h1>Results for: {query}</h1>
<ul>
"""
for result in results:
html += f"<li>{result['title']}</li>"
html += """
</ul>
</body>
</html>
"""
return make_response(html)F-string روش رایجی برای ساخت رشته در Python است، اما مدل ممکن است تفاوت میان ساخت یک پیام متنی و تولید یک پاسخ HTML را در نظر نگیرد. در این شرایط ورودی کاربر می تواند به بخشی از صفحه HTML تبدیل شده و امکان اجرای اسکریپت مخرب را فراهم کند.
استفاده از قابلیت Auto-Escaping در Jinja2 راهکار مناسب تری است:
SEARCH_TEMPLATE = """
<html>
<head><title>Search Results</title></head>
<body>
<h1>Results for: {{ query }}</h1>
<ul>
{% for result in results %}
<li>{{ result.title }}</li>
{% endfor %}
</ul>
</body>
</html>
"""
@app.route("/search", methods=["GET"])
def search():
query = request.args.get("q", "")
results = perform_search(query)
return render_template_string(SEARCH_TEMPLATE, query=query, results=results)مدل هوش مصنوعی ممکن است F-string را انتخاب کند چون ساخت HTML به این روش به Import و کدهای جانبی کمتری نیاز دارد. اما همین سادگی می تواند مسیر مستقیمی برای سرقت نشست کاربر ایجاد کند.
۳. آسیب پذیری Path Traversal
قانون تشخیص: pythonsecurity:S2083
شدت: Blocker
CWE: CWE-22
ابزارهای هوش مصنوعی معمولا برای ساخت مسیر فایل از os.path.join استفاده می کنند، اما این تابع به تنهایی بررسی نمی کند که مسیر نهایی همچنان داخل پوشه مورد نظر باقی مانده است یا خیر.
@app.route("/files/<path:filename>")
def download_file(filename):
file_path = os.path.join(UPLOAD_DIR, filename)
return send_file(file_path, as_attachment=True)
@app.route("/reports")
def get_report():
report_name = request.args.get("name")
report_path = os.path.join("reports", report_name)
with open(report_path, "r") as f:
content = f.read()
return make_response(content, 200, {"Content-Type": "text/plain"})در چنین شرایطی، ورودی هایی که شامل مسیرهای بازگشت به پوشه های بالاتر هستند می توانند باعث شوند برنامه از محدوده پوشه تعیین شده خارج شود و به فایل های دیگری دسترسی پیدا کند.
در Flask می توان از send_from_directory استفاده کرد که برای جلوگیری از حملات Path Traversal طراحی شده است:
@app.route("/files/<path:filename>", methods=["GET"])
def download_file(filename):
return send_from_directory(UPLOAD_DIR, filename, as_attachment=True)
@app.route("/reports", methods=["GET"])
def get_report():
report_name = request.args.get("name")
return send_from_directory("reports", report_name)بر اساس تحلیل Sonar، send_from_directory در داده های آموزشی مدل ها کمتر از ترکیب os.path.join و send_file دیده می شود. در نتیجه، حتی زمانی که API امن تر ساده تر باشد، مدل ممکن است الگویی را انتخاب کند که بیشتر در داده های آموزشی خود دیده است.
۴. اطلاعات احراز هویت Hardcoded
قوانین تشخیص: python:S6418 و javascript:S6418
شدت: Blocker
CWE: CWE-798
مدل های هوش مصنوعی گاهی مقادیر شبیه کلیدهای واقعی API را مستقیما داخل کد قرار می دهند:
api_key = "ak-9f8e7d6c5b4a3210fedcba9876543210abcdef01"const DB_API_KEY = "sk-proj-Ax7mK9pL2qR4sT6uV8wX0yZ1aB3cD5eF";این مقادیر ممکن است کاملا واقعی به نظر برسند، به ویژه زمانی که از پیشوندها و ساختارهایی شبیه کلیدهای واقعی استفاده شده باشد. توسعه دهنده نیز ممکن است بدون بررسی دقیق، چنین مقداری را مستقیما در پروژه قرار دهد.
راهکار بهتر استفاده از متغیرهای محیطی است:
api_key = os.environ.get("ANALYTICS_API_KEY", "")const DB_API_KEY = process.env.DB_API_KEY || "";قانون S6418 در SonarQube می تواند این اطلاعات احراز هویت Hardcoded را شناسایی کند تا پیش از ورود کد به مخزن اصلی، مشکل برطرف شود.
۵. آسیب پذیری Server-Side Request Forgery یا SSRF
قانون تشخیص: pythonsecurity:S7044
شدت: Major
CWE: CWE-918
ساخت Endpointهای Proxy یکی از درخواست های رایج در توسعه با کمک هوش مصنوعی است. مدل ممکن است ورودی کاربر را مستقیما با URL سرویس مقصد ترکیب کند:
@app.route("/api/analytics/<path:endpoint>")
def proxy_analytics(endpoint):
upstream_url = ANALYTICS_BASE_URL + "/" + endpoint
headers = {"Authorization": f"Bearer {api_key}"}
response = requests.get(upstream_url, headers=headers)
return make_response(response.content, response.status_code)در چنین شرایطی مهاجم می تواند از ساختارهای مربوط به مسیر برای دسترسی به Endpointهایی در سرور مقصد استفاده کند که قرار نبوده از طریق Proxy در دسترس باشند. این مسئله زمانی خطرناک تر می شود که هدر احراز هویت سرویس نیز همراه درخواست ارسال شود.
راهکار مناسب استفاده از Allowlist و URL Encoding است:
ALLOWED_ANALYTICS_ENDPOINTS = {"dashboard", "summary", "trends", "users"}
@app.route("/api/analytics/<path:endpoint>", methods=["GET"])
def proxy_analytics(endpoint):
if endpoint not in ALLOWED_ANALYTICS_ENDPOINTS:
return jsonify({"error": "Invalid endpoint"}), 400
upstream_url = ANALYTICS_BASE_URL + "/?endpoint=" + quote(endpoint)
headers = {"Authorization": f"Bearer {api_key}"}
response = requests.get(upstream_url, headers=headers)
return make_response(response.content, response.status_code)این آسیب پذیری ممکن است نسبت به SQL Injection و XSS کمتر مورد توجه توسعه دهندگان قرار گیرد، اما سرویس های داخلی و Endpointهای غیرقابل دسترسی از بیرون می توانند هدف مهمی برای حملات SSRF باشند.
۶. رمزنگاری ناامن
قوانین تشخیص: javascript:S4790 و python:S4790
CWE: CWE-1240
نوع هشدار: Security Hotspot
الگوریتم هایی مانند MD5 و SHA-1 برای مدت طولانی در پروژه های نرم افزاری استفاده شده اند و به همین دلیل نمونه های زیادی از آن ها در داده های آموزشی مدل های هوش مصنوعی وجود دارد.
const passwordHash = crypto
.createHash("sha1")
.update(password)
.digest("hex");
const token = crypto.createHash("md5").update(Date.now().toString()).digest("hex");file_hash = hashlib.md5(content).hexdigest()مشکل اینجاست که استفاده از MD5 برای محاسبه Hash یک فایل با استفاده از آن برای ذخیره رمز عبور یکسان نیست. MD5 ممکن است در برخی کاربردهای مربوط به تشخیص تکراری بودن فایل ها قابل استفاده باشد، اما برای ذخیره امن رمز عبور مناسب نیست.
برای رمز عبور باید از الگوریتم های مناسب مانند bcrypt استفاده شود و برای بررسی یکپارچگی فایل نیز می توان از SHA-256 استفاده کرد:
const bcrypt = require("bcrypt");
const passwordHash = await bcrypt.hash(password, 12);
const token = crypto.randomBytes(32).toString("hex");file_hash = hashlib.sha256(content).hexdigest()SonarQube این موارد را به عنوان Security Hotspot شناسایی می کند تا توسعه دهنده بررسی کند الگوریتم ضعیف دقیقا در چه زمینه ای استفاده شده است.
SonarQube چگونه این ۶ آسیب پذیری را شناسایی می کند؟
این شش دسته آسیب پذیری را می توان در دو گروه اصلی از روش های تشخیص قرار داد.
تحلیل Taint
در تحلیل Taint، جریان اطلاعات ورودی کاربر از منبع اولیه مانند پارامترهای HTTP، اطلاعات فرم یا فایل های آپلودشده تا مقصد خطرناک دنبال می شود. مقصد می تواند اجرای Query SQL، تولید HTML، دسترسی به فایل یا ارسال درخواست HTTP باشد.
SQL Injection، Reflected XSS، Path Traversal و SSRF از جمله آسیب پذیری هایی هستند که می توانند با این روش شناسایی شوند. SonarQube مسیر کامل حرکت داده از منبع تا مقصد را بررسی کرده و مسیر مشکل دار را مشخص می کند.
تحلیل معنایی
تحلیل Semantic برای شناسایی ساختارهای شناخته شده ناامن استفاده می شود و لزوما به دنبال کردن جریان داده نیاز ندارد.
Hardcoded Secretها و رمزنگاری ناامن در این دسته قرار می گیرند. موتور تحلیل SonarQube می تواند ساختار کد را بررسی کرده و رشته هایی با ویژگی های شبیه اطلاعات محرمانه یا فراخوانی هایی مانند md5 و sha1 را در زمینه های حساس شناسایی کند.
Quality Gate و جلوگیری از ورود کد ناامن
هر دو روش تشخیص می توانند در Quality Gate قرار بگیرند. Quality Gate مانند یک نقطه کنترل برای قبولی یا رد شدن کد عمل می کند. اگر کد جدید مشکلاتی ایجاد کند که شرایط تعیین شده برای Quality Gate را نقض کنند، فرآیند بررسی شکست می خورد.
در صورتی که این کنترل به CI و محافظت از مخزن کد متصل شود، Pull Request دارای مشکلات امنیتی می تواند پیش از Merge شدن متوقف شود.
برای پروژه هایی که بخش قابل توجهی از کد آن ها توسط هوش مصنوعی تولید شده است، قابلیت AI Code Assurance نیز می تواند یک لایه کنترل اضافی ایجاد کند. در این حالت می توان از Quality Gate و Quality Profileهای سختگیرانه تر استفاده کرد تا کد تولیدشده توسط AI پیش از ورود به پروژه از نظر امنیت و قابلیت نگهداری بررسی شود.
چرا بررسی کد تولیدشده توسط هوش مصنوعی ضروری است؟
کد تولیدشده توسط هوش مصنوعی ممکن است کاملا کاربردی و از نظر ظاهری مرتب باشد، اما این موضوع به معنای امن بودن آن نیست. مدل می تواند الگویی را انتخاب کند که در داده های آموزشی خود بارها دیده است، حتی اگر همان الگو از نظر امنیتی مشکل داشته باشد.
SQL Injection، XSS، Path Traversal، اطلاعات احراز هویت Hardcoded، SSRF و رمزنگاری ناامن از جمله مهم ترین نمونه هایی هستند که در این بررسی مطرح شده اند. بنابراین استفاده از ابزارهای هوش مصنوعی برای افزایش سرعت توسعه، بدون بررسی امنیتی خودکار و انسانی، می تواند حجم قابل توجهی از کد ناامن را وارد پروژه کند.





نظرات در مورد : ۶ آسیب پذیری امنیتی مهم که ابزارهای کدنویسی هوش مصنوعی ایجاد می کنند