<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های مرتضی مظاهریان</title>
        <link>https://virgool.io/feed/@moorteza</link>
        <description>یه آدم معمولی</description>
        <language>fa</language>
        <pubDate>2026-06-07 06:32:32</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/60497/avatar/avatar.png?height=120&amp;width=120</url>
            <title>مرتضی مظاهریان</title>
            <link>https://virgool.io/@moorteza</link>
        </image>

                    <item>
                <title>چت بات کرونا در WhatsApp. آموزش ساخت بات واتس اپ با پایتون</title>
                <link>https://virgool.io/coderlife/%DA%86%D8%AA-%D8%A8%D8%A7%D8%AA-%DA%A9%D8%B1%D9%88%D9%86%D8%A7-%D8%AF%D8%B1-whatsapp-%D8%A2%D9%85%D9%88%D8%B2%D8%B4-%D8%B3%D8%A7%D8%AE%D8%AA-%D8%A8%D8%A7%D8%AA-%D9%88%D8%A7%D8%AA%D8%B3-%D8%A7%D9%BE-%D8%A8%D8%A7-%D9%BE%D8%A7%DB%8C%D8%AA%D9%88%D9%86-bmsyhdukigdh</link>
                <description>مشغول کار روی پایان نامم بود که متاسفانه ویروس کرونا تو ایران همه گیر شد. تو این اوضاع و شرایط احساس کردم که به عنوان یک وظیفه شهروندی باید یک سیستمی رو ایجاد کنم که مردم بهتر با خطرات این اپیدمی آشنا بشن.سایت ها و اپلیکشن های زیادی در این مورد ساخته شده و در حال استفاده است که انصافا برنامه های خیلی خوبی هم هستند. ولی چون اکثر کسایی که گوشی های هوشمند دارن از پیام رسانهایی مثل واتس آپ و تلگرام استفاده میکنند به نظر من یک بات روی این پیام رسانها برای اطلاع رسانی و اگاهی و اموزش کاربرد بیشتری میتونه داشته باشه. نمونه کامل و پیاده سازی و اجرا شده این بات از اینجا یا ارسال سلام به شماره 09160459678 قابل دسترسی است.ساخت بات برای تلگرام راحت و کتابخونه های زیادی در انواع زبانها براش وجود داره. ولی مشکلی که داره اینه که تو ایران فیلتر و شاید خیلی ها نتونن بهش دسترسی داشته باشن ولی خب واتس اپ تقریبا روی اکثر گوشی ها نصب و در حال استفاده است. پس تصمیم گرفت که برای واتس اپ درست کنم.متاسفانه برای واتس اپ api که در دسترس عموم باشه وجود نداره. توی گیتهاب یکسری پروژه  هست که از آخرین اپدیتشون خیلی وقت میگذره و از کار افتادن و قابل استفاده نیستن.پس تصمیم گرفتم خودم یکی درست کنم. و چون اموزشی در سطح نت ندیدم و سوال میپرسیدن که چطور بات رو درست کردی، به نظرم رسید که این اموزش رو اینجا قرار بدم. امیدوارم که مفید واقع بشه.نحوه کار این بات به این صورت که منتظر میمونه تا پیام جدیدی برسه و بعد از دریافت پیام پاسخ متناسب با اون پیام رو ارسال میکنه. همونطور که میبینید یک روال خیلی ساده است.برای پیاده سازیش ما از نسخه تحت وب واتس اپ  و برای کنترلش از کتابخونه selenium استفاده میکنیم. پس قبل از شروع کار سلنیوم رو نصب میکنیم.سلنیوم یک کتابخونه برای اتوماتیک کردن کارها در مرورگرهاست. پس در ابتدای کار کتابخونه سلنیوم رو با دستور زیر نصب میکنم:pip install -U seleniumدر مرحله بعد باید تصمیم بگیریم که میخواییم از چه مرورگری استفاده کنیم. اگر از کروم استفاده میکنید باید اخرین نسخه chrome driver رو از اینجا و اگر از فایرفاکس استفاده میکند باید اخرین نسخه Geckodriver رو از اینجا دانلود کنید. برای مرورگرهای ادج و سافاری هم هست که میتونید لینکشون از اینجا پیدا کنید. من تو این پروژه از فایرفاکس استفاده کردم ولی روال کار با مرورگرهای دیگه تفاوت آنچنانی نداره.from selenium import webdriver
driver=webdriver.Firefox(executable_path=dir_path+&#039;/geckodriver&#039;)
driver.get(&amp;quothttps://web.whatsapp.com&amp;quot)کد بالا باعث اجرای مرروگر فایرفاکس و بارگزاری آدرس  https://web.whatsapp.com میشود.خط دوم باعث اجرای فایرفاکس میشه. ورودی این تابع، آدرس geckodriver که در بالا دانلود کردیم رو وارد میکنیم. در خط سوم هم سایت https://web.whatsapp.com در مرورگر باز میشه. بعد از اجرای این ۳ خط چیزی که مشاهده میشه تصویر زیر:در ادامه با اسکن کد بالا با گوشی وارد محیط چت میشیم. توی محیط چت باید منتظر بمونیم تا یک پیامی ارسال بشه و بعد از اینکه پیامی اومد باید پاسخ متناسب با اون پیام ارسال بشه. حالا چطور تشخیص بدیم که پیامی اومده. به تصویر زیر دقت کنید.همانطور که مشاهده میکنید زمانی که پیام جدیدی میرسه یک دایره سبز رنگ کنار نام مخاطب ایجاد میشه. به بیان دقیق تر یک المان جدید به صفحه اظافه میشه و بعد از خواندن پیام این دایره پاک میشه. پس ما باید این المان رو شناسایی کنیم. حالا چطور این کار کنیم. برای این کار ابتدا در مرورگر فایرفاکس رو دایره سبز رنگ کلیک راست و در ادامه روی Inspect element کلیک میکنیم و وارد محیطی شبیه به محیط زیر میشویم.در اینجا برای اینکه بتونیم دایره سبز رنگ رو پیدا کنیم نیاز به نام کلاس داریم که در اینجا &quot;_15G96&quot; است. حالا باید کدش رو پیاده سازی کنیم.from selenium.webdriver.support.ui import WebDriverWait
wait = WebDriverWait(driver,3600)
wait.until(ec.presence_of_element_located((By.CLASS_NAME,&amp;quot_15G96&amp;quot)))
newMessages=driver.find_elements_by_class_name(&amp;quot_15G96&amp;quot)در کد بالا خط سوم به این معنی که تا زمانی که المانی با کلاس _15G96 در ساختار DOM سایت ظاهر نشده به خط بعدی نرو. مدت زمانی هم که میتونه منتظر بمونه ۳۶۰۰ ثانیه است که در خط قبلش مشخص شده و اگه از این مقدار بگذره خطا میده که باید به نحوی مدیریت بشه. بعد از اینکه این کلاس در ساختار سایت ظاهر شد وارد خط چهارم میشه و همه اونها رو در متغیر  newMessages ذخیره میکنه.خب تا اینجای کار ما تونستیم کدی بنویسیم که میتونه تشخیص بده پیام جدیدی رسیده یا نه . حالا وقتش که این پیام رو تحلیل کنیم و پاسخ مناسب رو ارسال کنیم.for newMessage in newMessages:
....parent=newMessage.find_element_by_xpath(&amp;quot../../..&amp;quot)
....messageText=parent.find_element_by_class_name(&#039;_1wjpf&#039;).textبالاتر گفتیم که متغیر newMessages حاوی پیامهای جدیدی که رسیده. حالا با استفاده از یک حلقه، یکی یکی پیامهای جدید رو میخونیم. ایده ای که برای خوندن پیامها هست اینه که اصلا نیازی نیست وارد محیط چت بشیم و فقط کافیه که متنی که زیر شماره مخاطب نوشته شده رو بخونیم. مانند پیام سلام در شکل زیر:به محل قرارگیری دایره سبز رنگ در ساختار DOM سایت توجه کنید چیزی شبیه به ساختار زیر رو مشاهده میکنیدحالا ما بخواهیم از طریق المانی با نام کلاس _15G96به متن دست پیدا کنیم ابتدا نیاز که جَدِ این المان که کلاس _1AwDx هست رو پیدا کنیم. خط دوم از کد بالا این کار رو انجام میده در واقع برای پیدا کردن پدر یک المان از .. استفاده میکنیم. در خط سوم هم محتوا متنی کلاس _1wjpf رو که همون پیام جدید هست رو بدست میاریم. تا اینجای کار ما تونستیم پیام جدید که رسیده رو شناسایی و بخونیم . حالا باید تصمیم بگیریم که با این پیام جدید که رسیده چکار کنیم.ساده ترین کار تعریف یک دیکشنری است که کلیدهاش پیام رسیده و مقدارش جواب پیام ها باشه. چیزی شبیه به مثال زیر:responses={
....&#039;hello&#039;:&#039;hi&#039;,
....&#039;name&#039;:&#039;morteza&#039;,
....&#039;goodbye&#039;: &#039;by&#039;
}در کد بالا یک دیکشنری تعریف کردیم که مشخص کنیم متناسب با هر پیام چه جوابی رو ارسال کنیم. حالا میخواییم جواب ارسال کنیم. از کدی شبیه به کد زیر استفاده میکنیم.if messageText in responses.keys():
....response=responses[messageText]
....parent.click()
....wait.until(ec.element_to_be_clickable((By.XPATH,&#039;//div[@spellcheck=&amp;quottrue&amp;quot]&#039;)))
....txtBox=driver.find_element_by_xpath(&#039;//div[@spellcheck=&amp;quottrue&amp;quot]&#039;)
....txtBox.click()تو کد بالا ما هنوز جواب رو ارسال نکردیم و فقط تا تا مرحله شبیه سازی کلیک کردن رو نام مخاطبی که پیام رو ارسال کرده پیش رفتیم. در ادامه در خط۴ بعد از کلیک کردن منتظر میمونیم تا باکس وارد کردن متن پیام بالا بیاد تا همه چی برای وارد کردن متن پاسخ و ارسال اون اماده بشه. کد بالا ک اجرا بشه چیزی شبیه به تصویر زیر داریم که باکس پیام هم منتظر وارد کردن متن است.حالا باید پیام رو وارد باکس پیام کنیم. میتونیم از کد زیر استفاده کنیمtxtBox.send_keys(response)اما این کد دو تا ایراد داره. اولی اینکه این کد دقیقه تایپ کردن رو شبیه سازی میکنه و اگه متن طولانی باشه زمان میبره. دومین ایرادش اینه اگه در متن ارسالی \n داشته باشیم معادل با اینتر در نظر میگیره و یک پیام چند خطی رو در چند پیام یک خطی ارسال میکنه. حالا باید چکار کنیم که اینطوری نشه. ایده من کپی کردن متن در کلیپ بورد و پیست کردنش توی باکس متن بود. به این صورت که ابتدا pyperclip رو با دستور زیر نصب میکنیم. و کد ما به شکل زیر میشودpip install pyperclipimport pyperclip
pyperclip.copy(response)
txtBox.send_keys(Keys.CONTROL+&#039;V&#039;)
txtBox.send_keys(Keys.ENTER)در خط اول متن رو در کلیپبرد ذخیره در ادامه پیست و در انتها دکمه اینتر رو میفرستیم تا پیام ارسال بشه. کدی در انتها به بدست میاد چیزی شبیه به کد زیر است:from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
import pyperclip
driver=webdriver.Firefox(executable_path=dir_path+&#039;/geckodriver&#039;)
driver.get(&amp;quothttps://web.whatsapp.com&amp;quot)
wait = WebDriverWait(driver,3600)
wait.until(ec.presence_of_element_located((By.CLASS_NAME,&amp;quot_15G96&amp;quot)))
newMessages=driver.find_elements_by_class_name(&amp;quot_15G96&amp;quot)
responses={
....&#039;hello&#039;:&#039;hi&#039;,
....&#039;name&#039;:&#039;morteza&#039;,
....&#039;goodbye&#039;: &#039;by&#039;
}
for newMessage in newMessages:
....parent=newMessage.find_element_by_xpath(&amp;quot../../..&amp;quot)
....messageText=parent.find_element_by_class_name(&#039;_1wjpf&#039;).text
....if messageText in responses.keys():
........response=responses[messageText]
........parent.click()
........wait.until(ec.element_to_be_clickable((By.XPATH,&#039;//div[@spellcheck=&amp;quottrue&amp;quot]&#039;)))
........txtBox=driver.find_element_by_xpath(&#039;//div[@spellcheck=&amp;quottrue&amp;quot]&#039;)
........txtBox.click()
........pyperclip.copy(response)
........txtBox.send_keys(Keys.CONTROL+&#039;V&#039;)
........txtBox.send_keys(Keys.ENTER)امکان دیگه ای که بات داره ارسال عکس که دقیقا شبیه به کد بالاست با این تفاوت که به جای کپی متن در کلیپبرد، عکس رو کپی میکنه. برای این کار در لینوکس از برنامه xcopy استفاده میکنیم. کدی که برای ارسال عکس بکار بردیم چیزی شبیه به کد زیر استimport subprocess
subprocess.Popen([&#039;xclip&#039;, &#039;-selection&#039;, &#039;clipboard&#039;, &#039;-t&#039;, &#039;image/png&#039;, &#039;-i&#039;, imagePath)
txtBox.send_keys(Keys.CONTROL+&#039;V&#039;)
wait.until(ec.element_to_be_clickable((By.CLASS_NAME,&#039;_2gZno&#039;)))
driver.find_element_by_class_name(&#039;_3hV1n&#039;).click()مورد دیگه چگونگی ساخت تصاویر زیر استبه این گونه تصاویر در اصطلاح word cloud میگن که یک کتابخونه در پایتون به همین نام وجود داره. ابتدا باید این کتابخونه رو نصب کنیمpip install wordcloudکد ما برای ساخت این تصاویر چیزی شبیه به زیر بود:from wordcloud import WordCloud
import matplotlib.pyplot as plt
import json

with open(fileName,&#039;r&#039;,encoding=&#039;utf-8&#039;) as f:
data=json.load(f)
myDict={}
for t in data:
....myDict[t[&#039;name&#039;]]=float(t[&#039;count&#039;])
wordcloud = WordCloud().generate_from_frequencies(myDict)
plt.imshow(wordcloud, interpolation=&#039;bilinear&#039;)
plt.axis(&amp;quotoff&amp;quot)
plt.savefig(imgFile,bbox_inches=&#039;tight&#039;)مورد بعدی به بدست اوردن آمار جهانی که اطلاعاتش رو با کدی شبیه به کد زیر از سایت worldometers بدست میاریم.ابتدا باید کتابخونه pandas  رو نصب کنیم.import pandas as pd
pd.options.mode.chained_assignment = None
data = pd.read_html(&#039;https://www.worldometers.info/coronavirus/&#039;)
data_cases=data[-1]
print(data_cases.to_string())امکان دیگه ای که توی بات هست لیست کردن مقالات مرتبط با کرونا است که این مقالات رو با کد زیر از سایت corona.ir بدست میاریم. ابتدا باید کتابخونه BeautifulSoup  رو نصب کنیمimport requests
from bs4 import BeautifulSoup
req=requests.get(&#039;https://corona.ir/&#039;)
if req.status_code==200:
....soup = BeautifulSoup(req.content, &#039;html.parser&#039;)
....soup=soup.select_one(&#039;section.home:nth-child(6)&#039;)
....articles=soup.findAll(&#039;h4&#039;)
....for a in articles:
........print(a.get_text()+&#039;\nhttps://corona.ir&#039;+a.find(&#039;a&#039;)[&#039;href&#039;])یه مقدار خلاصه توضیح دادم ولی امیدواردم که براتون مفید باشه. کد کامل رو بعدا توی گیتهاب میزارم و همین پست رو اپدیت میکنم.نکته ای که هست اینکه اسامی کلاس ها در برنامه های فیسبوک مثل اینستاگرام و واتس اپ به صورت رندوم تولید میشه و احتمالا هر روز یا دو روزی یکبار عوض بشه که باید تغییرات رو اعمال کنید.نکته بعدی اینکه برای اجرای اپلیکیشن واتس اپ روی سرور از امولاتور genymotion روی ابونتو سرور استفاده کردیم. مشکلی که داشتم اسکن کردن qrcode نسخه تحت وب با استفاده از اپلیکیشن روی شبیه ساز بود. راه حل من برای این مشکل نصب یک fake camera روی امولاتور و گرفتن عکس از صفحه نمایش و ارسال اون به شبیه ساز بود.امیدوارم که مفید باشه.</description>
                <category>مرتضی مظاهریان</category>
                <author>مرتضی مظاهریان</author>
                <pubDate>Sat, 28 Mar 2020 13:50:39 +0430</pubDate>
            </item>
                    <item>
                <title>چگونه یک کد تمیز بنویسیم. خلاصه‌ای از کتاب Clean Code</title>
                <link>https://virgool.io/@moorteza/%DA%86%DA%AF%D9%88%D9%86%D9%87-%DB%8C%DA%A9-%DA%A9%D8%AF-%D8%AA%D9%85%DB%8C%D8%B2-%D8%A8%D9%86%D9%88%DB%8C%D8%B3%DB%8C%D9%85-%D8%AE%D9%84%D8%A7%D8%B5%D9%87%D8%A7%DB%8C-%D8%A7%D8%B2-%DA%A9%D8%AA%D8%A7%D8%A8-clean-code-y4eqdayjiasf</link>
                <description>به کدی تمیز میگن که به راحتی توسط هرکسی که کد رو میخونه، قابل فهم باشه. یکی از مشکلاتی که در هنگام نگاه به کد و بررسی آسیب پذیری دارم اینه که اصلا نمیفهمم چی نوشتن و چکار کردن. کتاب clean code نوشته رابرت مارتین، یکی از بهترین کتاب‌ها در زمینه نوشتن کد خوانا و تمیز است. در این پست قصد دارم خلاصه ای از این کتاب رو به صورت تیتر وار بگم. اگه نیاز به جزئیات بیشتر داشتید می‌تونید به کتاب اصلی مراجعه کنید.کد تمیز چیست؟کد خوب یا بد، کدی هست که بشه خیلی زود فهمیدش و در موردش صحبت کرد.یک کد خوب باید کوتاه، مفید، قابل خوندن، ساده و بدون تکرار باشه.یک کد خوب می‌تونه ارزش کسب و کار یک بیزینس رو بالا ببره.قواعد کلیاز یک قرارداد استاندارد پیروی کنید.سادگی همیشه بهترِ. تا جای ممکن پیچیدگی را کاهش بدید.از قانون پیشاهنگی پیروی کنید. یعنی کد رو تمیز‌تر از آنچه که تحویل گرفتید، تحویل بدید.همیشه دنبال دلیل اصلی یک مشکل باشید.قوانین نامگذارینام‌ها توصیفی و قابل فهم باشه. نام‌ها قابل تمایز از هم باشن.از نام‌های قابل تلفظ استفاده کنید.از نام‌های قابل جستجو استفاده کنید.اعدادی که در کد زیاد استفاده می‌شوند (اعداد جادویی)، مثل ۳.۱۴ را با ثابت‌ها جایگزین کنید.از نام‌هایی با کدینگ‌های جورواجور، اظافه کردن پیشوند یا اطلاعاتی در مورد نوع متغیر، اجتناب کنید.سعی کنید نام، مشخص کننده دامنه سیستم، زمینه و مشکلاتی که برای حل آن ایجاد شده، باشد.قوانین توابعکوچک باشند. حداکثر ۲۰ خطفقط یک کار انجام دهند.از نام گذاری توصیفی استفاده کنید.هرچه تعداد پارامترها کمتر باشه، بهترِ. حداکثر ۲ تا. اگر احساس می‌کنید بیشتر نیازه باید توجیح داشته باشید.از پارامترهای پرچم(بولین) که شرایط خاصی را در تابع نشان می‌دهند اجتناب کنید. با این کار نشون میدید تابع شما بیش از یک کار انجام میده. به جای آن تابع را به چند تابع مستقل تقسیم کنید به گونه ای که بدون پرچم هم قابل فراخوانی باشند.توابع باید کاری رو انجام دهند و چیزی رو برگردونن.قوانین توضیحاتسعی کنید توضیحات کوتاهی در مورد خودتون تو کد قرار بدید.یکی از عمده ترین دلایل قرار دادن توضیحات به دلیل بد بودن کد است.اگر همش به این فکر می‌کنی که چه توضیحاتی باید بنویسی، کدت نیاز بازسازی داره.توضیحات، یک کد بد رو نجات نمیده.توضیحات بیش از حد نباشه.از اضافه کردن مواردی که آشکار هستن و نیاز به توضیحات بیشتری ندارند اجتناب کنید.از قرار دادن توضیحات در جلوی براکت بسته اجتناب کنید.کدی را که قصد استفاده ندارید، تبدیل به کامنت نکنید. فقط حذفش کنید.از توضیحات برای شرح هدفتون استفاده کنید.به منظور شفاف کردن کد، از توضیحات استفاده کنید.توضیحات زمانی مفیدن که در جای درست قرار بگیرند.به عنوان یک هشدار برای نشان دادن عواقب استفاده از کد، از توضیحات استفاده کنید.قوانین طراحیداده‌های قابل پیکربندی را در بالاترین سطح قرار بدید.سعی کنید تا جای ممکن از چندریختی (polymorphism) به جای if/else و switch/case استفاده کنید.کدهایی که مولتی ترد اجرا می‌شوند رو جدا کنید.از پیکربندی‌های غیرضروری و اضافی که فهم کد را سخت میکنه، اجتناب کنید.از تکنیک تزریق وابستگی استفاده کنید. یعنی به جای استفاده مستقیم از وابستگی‌های خارجی در درون کلاس، آنها را به کلاس تزریق کنید.از قانون دمیتر پیروی کنید. این قانون میگه یک کلاس فقط باید وابستگی‌های مستقیم خودش رو بشناسه.ساختار کدمفاهیم را به صورت عمودی از هم جدا کنید.کدهایی که مرتبط با هم هستند، زیر هم قرار گیرند.متغیرها را نزدیک به جایی که قصد استفاده از آنها را دارید، تعریف کنید.توابعی که به هم وابسته هستند باید در کنار هم تعریف شوند.توابعی که شبیه هم هستند باید در کنار هم تعریف شوند.توابع را بر حسب اهمیت و استفاده، از بالا به پایین قرار بدید.تعدا کاراکترها در خط‌وط را محدود کنید. ۱۲۰ تا کاراکتر در هر خط.عملگرها، پارامترها و کاما را با فاصله از هم جدا کنید. قوانین تورفتگی رو تقض نکنید.ساختمان داده و اشیاءساختار داخلی را پنهان کنید.از ساختمان‌های داده‌های ترکیبی (نیمی اشیاء، نیمی داده) خودداری کنید.کپسوله سازی (Encapsulate) و کلاس‌هاای انتزاعی (abstract class) را به درستی پیاده سازی کنید.ساختارها باید کوتاه باشند.ساختارها باید یک کاری را انجام بدن.کلاس پایه نباید هیچ اطلاعی از کلاس‌های مشتق شده داشته باشد.بهتر است چندین تابع مختلف تعریف کنیم تا اینکه یک تابع داشته باشیم که در شرایط مختلف رفتار متفاوتی داشته باشد.بهتر است به جای استفاده از توابع استاتیک از توابع غیر استاتیک استفاده کنید.تست‌هابه ازای هر تست یک assert تعریف کنید.تست باید سریع باشد.مستقل باشد.قابل تکرار باشد.کد بد بو (Code smells)در انتها، کد شما نباید بد بو باشه. موارد زیر ویژگی‌های یک کد بد بو را نشون میده: ایجاد تغییرات در نرم افزار سخت و یک تغییر کوچک باعث ایجاد تغییرات بعدی به صورت آبشاری میشه. با یک تغییر کوچک، نرم افزار در خیلی از جاها شکننده میشه.شما نمی‌تونید بخشی از کد را به خاطر ریسک‌ها و خطرات آن در پروژه‌ دیگری استفاده مجدد کنید.پیچیدگی زیاد داره.تکرار زیاد داره.درک کردن کد دشوار است.منبع با اندکی تغییر</description>
                <category>مرتضی مظاهریان</category>
                <author>مرتضی مظاهریان</author>
                <pubDate>Wed, 29 Jan 2020 17:50:12 +0330</pubDate>
            </item>
                    <item>
                <title>ایران چطور تونست دامنه فارس نیوز که توسط آمریکا مسدود شده بود را برگردونه. بررسی حمله DNS Spoofing</title>
                <link>https://virgool.io/@moorteza/%D8%A7%DB%8C%D8%B1%D8%A7%D9%86-%DA%86%D8%B7%D9%88%D8%B1-%D8%AA%D9%88%D9%86%D8%B3%D8%AA-%D8%AF%D8%A7%D9%85%D9%86%D9%87-%D9%81%D8%A7%D8%B1%D8%B3-%D9%86%DB%8C%D9%88%D8%B2-%DA%A9%D9%87-%D8%AA%D9%88%D8%B3%D8%B7-%D8%A2%D9%85%D8%B1%DB%8C%DA%A9%D8%A7-%D9%85%D8%B3%D8%AF%D9%88%D8%AF-%D8%B4%D8%AF%D9%87-%D8%A8%D9%88%D8%AF-%D8%B1%D8%A7-%D8%A8%D8%B1%DA%AF%D8%B1%D8%AF%D9%88%D9%86%D9%87-%D8%A8%D8%B1%D8%B1%D8%B3%DB%8C-%D8%AD%D9%85%D9%84%D9%87-dns-spoofing-am30vwnhpbzf</link>
                <description>حتما در خبرها شنیدید که چند روز پیش دامنه دات کام سایت‌هایی مثل فارس نیوز توسط امریکا تحریم و مسدود شد.روز بعد سجاد بنابی، نائب رئیس هیئت مدیره شرکت زیرساخت در پیامی اعلام کرد دامنه دات کام در تمام کشور قابل دسترس است.در این پست بررسی می‌کنیم که این کار چگونه انجام گرفته است.DNS Cache Spoofing(poisoning)یک دانشگاه را تصور کنید که موقع شروع سال تحصیلی، دانشجوهای ترم بالایی برای اینکه دانشجوهای جدیدالورود را اذیت کنند میان شماره کلاس‌ها را عوض می‌کنند.حالا دانشجوهای جدیدالورود را تصور کنید که هنوز با چیدمان کلاس‌ها آشنا نیستند و تو کلاس‌های اشتباهی حاضر می‌شوند. حالا تصور کنید که این شماره کلاس‌های اشتباه تو سیستم راهنمای دانشگاه هم ثبت بشه و دانشجوها تا زمانی که یکی بیاد و این اشکال را برطرف کنه وارد کلاسهای اشتباهی میشن.جعل DNS یعنی وارد کردن اطلاعات اشتباه در کش DNS، به نحوی که در کاربران را به یک سایت اشتباهی هدایت کند. آی پی آدرس‌ها همان شماره کلاس‌ها در اینترنت هستند، اجازه می‌دهند که ترافیک اینترنت به مسیر درست هدایت بشه. DNS Resolverها هم سیستم راهنمای دانشگاه هستند، و زمانی که اشتباه ثبت بشن ترافیک اینترنت را تا زمانی که اطلاح بشن به مسیر اشتباهی هدایت می‌کنند.از آنجا که هیچ راهی برای تایید دیتای درون کش، توسط DNS Resolver وجود نداره، دیتای اشتباه تا زمانی که دستی پاک نشن یا TTL منقضی نشه،در کش باقی میمونه.کار DNS Resolver چیست؟وظیفه ربط دادن ای پی به دامین مربوطه، وظیفه DNS Resolverهاست. به بیان ساده‌تر یک نام خوانا برای انسان مثل virgool.io را به یک آدرس خوانا برای ماشین مانند 72.64.109.38 تبدیل می‌کنه. زمانی که شما درخواست یک سایتی را می‌کنید، سیستم عامل این درخواست را برای یک DNS Resolver ارسال می‌کند. DNS Resolver در جواب یک ای پی برمیگردونه، مرورگر این ایپی را گرفته و سایت را بارگذاری می‌کند.دی ان اس کش چطور کار می‌کنه؟دی ان اس ریزالور (بخاطر باگ ویرگول مجبورم فارسی بنویسم) پاسخ‌هایی را که ارسال می‌کنه، جهت افزایش سرعت، برای مدتی ذخیره می‌کنه. پاسخ ‌ها تا زمانی که TTL مشخص کرده در حافظه کش باقی میمونن.DNS Uncached ResponseDNS Cached Responseمهاجم چطور آدرس اشتباه را در کش DNS قرار میده: مهاجم برای مسموم کردن کش دی ان اس،یک درخواست برای DNS Resolver ارسال تا ای پی سایت را دریافت کند. اگر این آدرس در کش نباشه DNS Resolver شروع میکنه به درخواست فرستادن برای nameserver تا ای پی دامنه مورد نظر را پیدا کنه. در این بین مهاجم هم همزمان شروع میکنه به فرستادن آی پی جعلی تا به جای ای پی اصلی توسط DNS Resolver پذیرفته بشه. از انجایی که سرورهای DNS از پروتکل UDP به جای TCP استفاده و  در حال حاضر برای این پروتکل هیچ راهی برای تصدیق طلاعات DNS وجود نداره. پس این حمله امکان پذیر است.فرایند مسموم کردن کش DNSمسموم کردن کش DNSدر TCP هر دو طرف برای شروع برقرای ارتباط نیاز به handshake و تایید هویت هم دارند. ولی برای درخواست و پاسخ های DNS از پروتکل UDP استفاده میشه. در UDP هیچ تضمینی وجود نداره که آیا درخواست هنوز برقرار یا فرستنده همان کسی است که ادعا می‌کند. به همین دلیل در مقابل جعل آسیب پذیر است.  مهاجم میتونه از طریق UDP پیامی رو ارسال و ادعا کنه از یک منبع معتبر ارسال شده.با وجود این آسیب پذیری، ولی در عمل انجام این حمله بسیار مشکل است. چون DNS Resolver یک درخواست برای Nameserver ارسال میکنه و مهاجم زمان بسیار کمی در حد چند میلی ثانیه فرصت داره تا درخواست رو قبل از اینکه پاسخ از nameserver دریافت بشه، جعل کنه.حالا خیلی از دولت‌ها برای سانسور کردن و جلوگیری از دسترسی به بعضی سایت‌ها میان از DNS Spoofing استفاده می‌کنند. کاری که ایران کرده، اومده از عمد DNS ها رو جعل و farsnews.com رو در کش DNS قرار داده. در عکس زیر میتونید مشاهده کنید دامنه farsnews.com کاملا مسدوده ولی وقتی در مرورگر واردش می‌کنید به ادرس farsnews.ir منتقل میشید.</description>
                <category>مرتضی مظاهریان</category>
                <author>مرتضی مظاهریان</author>
                <pubDate>Mon, 27 Jan 2020 22:11:35 +0330</pubDate>
            </item>
                    <item>
                <title>انواع آسیب پذیری در PHP - چک لیست بررسی باگ در کد</title>
                <link>https://virgool.io/@moorteza/%D8%A7%D9%86%D9%88%D8%A7%D8%B9-%D8%A2%D8%B3%DB%8C%D8%A8-%D9%BE%D8%B0%DB%8C%D8%B1%DB%8C-%D8%AF%D8%B1-php-%DA%86%DA%A9-%D9%84%DB%8C%D8%B3%D8%AA-%D8%A8%D8%B1%D8%B1%D8%B3%DB%8C-%D8%A8%D8%A7%DA%AF-%D8%AF%D8%B1-%DA%A9%D8%AF-yniijcl2gblw</link>
                <description>در نوشته های قبلی در مورد مبانی امنیت برنامه‌های تحت وب و امنیت در PHP  توضیحاتی رو ارائه دادم. در این پست قصد دارم نکات و آسیب پذیری‌هایی را که هنگام نوشتن کدهای PHP، امکان رخ دادنشان هست و نیاز به توجه و حساسیت بیشتری از جانب برنامه نویسان و توسعه دهندگان دارد را توضیح دهم.زبان PHP محبوب‌ترین زبان برنامه نویسی سمت سرور است. بر اساس داده‌های سایت W3Techs در سال ۲۰۱۹، ۷۹ درصد از وب سایت‌ها، قدرت گرفته از PHP هستند. از آنجایی که PHP زبان محبوبی است، امنیت در PHP امری ضروری است. متاسفانه تعداد برنامه‌های آسیب پذیر نوشته شده با PHP بسیار زیاد است.منابعی که این آسیب پذیری‌ها را شرح دادن اکثرا از mitre.org و OWASP هستند. اگر فرصتی باشه در مورد هر کدام از این آسیب پذیری‌ها در پست‌های جداگانه‌ای توضیحات بیشتری ارائه میدم. این نکته رو هم بگم که بعضی از آسیب پذیری‌ها انواع مختلفی دارند. ولی از آنجایی که هدف این پست تنها معرفی گونه‌های مختلف آسیب پذیری است، در اینجا ذکر نشدن. این پست فقط برای برنامه نویسان PHP نیست و می‌تواند برای همه برنامه نویسان وب مفید باشد. ممکن است خیلی از آسیب پذیری‌ها را فراموش کرده باشم که در این پست بیارم، اگر شما هم آسیب پذیری غیر از این موارد می‌شناسید و یا ایرادی می‌بینید خوشحال میشم تو نظرها اعلام کنید تا اعمال کنم. نکته بعدی اینکه، قطعه کدهایی که در زیر آسیب پذیری‌ها آورده شده، نمونه کدآسیب پذیر است و نباید به این فرم در برنامه استفاده شود. برای یادگیری نحوه صحیح نوشتن و جلوگیری از حمله، می‌توانید از مراجع کمک بگیرید. آسیب پذیری در برنامه‌های تحت وب به ۴ دسته تقسیم می‌شود: Medium, High, Critical و Low:۱. آسیب پذیری‌های با درجه اهمیت Critical آسیب پذیری‌هایی با درجه اهمیت حیاتی که معمولا برای اکسپلویت کردنشان نیاز به استفاده از تکنیک‌های مهندسی اجتماعی نیست و می‌تواند منجر به آسیب دیدن زیرساخت و یا از دست رفتن اطلاعات حساس شود. در ادامه آسیب پذیری‌های این دسته رو به صورت مختصر توضیح میدم.Command Injectionاین حمله زمانی اتفاق می‌افتد که داده ورودی به عنوان یک دستور سیستمی تفسیر و اجرا شود:$file=$_GET[&#039;filename&#039;];
system&#40;&amp;quotrm $file&amp;quot&#41;;SQL Injectionزمانی رخ می‌دهد که داده ورودی به عنوان یک دستور SQL، تفسیر و اجرا شود:$articleid = $_GET[&#039;article&#039;];
$query = &amp;quotSELECT * FROM articles WHERE articleid = &#039;$articleid&#039;&amp;quotCode Injectionزمانی زخ می‌دهد که داده ورودی به عنوان یک کد PHP، تفسیر و اجرا شود:$myvar = &amp;quotvarname&amp;quot
$x = $_GET[&#039;arg&#039;];
eval&#40;&amp;quot\$myvar = \$x;&amp;quot&#41;;Arbitrary File Writeزمانی که مهاجم بتواند هر فایل با هر پسوند دلخواهی را در سرور بارگذاری یا ایجاد کند این حمله صورت می‌گیرد:$target_dir = &amp;quotuploads/&amp;quot
$target_file = $target_dir . basename($_FILES[&amp;quotfileToUpload&amp;quot][&amp;quotname&amp;quot]);
if(isset($_POST[&amp;quotsubmit&amp;quot])) {
move_uploaded_file&#40;$_FILES[&amp;quotfileToUpload&amp;quot][&amp;quottmp_name&amp;quot], $target_file&#41;}Remote File Inclusionبا استفاده از include برنامه نویس قادر است تا یک فایل php را گرفته و از کدهای آن در فایل جاری استفاده کند. حالا چه اتفاقی می‌افتد اگر این فایل، یک فایل مخرب باشد:$file = $_GET[&#039;file&#039;];
include($file);Object Injectionاین آسیب پذیری هم زمانی رخ می‌دهد که ورودی کاربر قبل از آنکه sanitize شود در اختیار تابع unserialize قرار گیرد:$user_data = unserialize($_GET[&#039;data&#039;]);۲. آسیب پذیری‌های با درجه اهمیت High آسیب پذیری‌های این دسته معمولا اکسپلویت کردنشان سخت‌تر از دسته Critical است. مهاجم بعد از کسپلویت، می‌تواند سطح دسترسی خودش رو در سیستم افزایش، بخشی از داده‌ها را سرقت و یا باعث از کار افتادن سیستم شود.Local File Inclusionشبیه آسیب پذیری File Inclusion است. با این تفاوت که مهاجم فقط قادر به اجرای فایل‌های محلی در سرور است: $file = $_GET[&#039;file&#039;];
include(&#039;directory/&#039; . $file);LDAP Injectionاِلدَپ یک پروتکل در لایه کاربرد، برای ارتباط با دایرکتوری سرویس است. در صورتی که ورودی کاربر sanitize نشود مهاجم قادر است که اطلاعات موجود در LDAP را مشاهده، تغییر و یا دستور مد نظرش را اجرا کند:class LDAPAuthenticator {
  public $conn;
  public $host;

  function __construct($host = &amp;quotlocalhost&amp;quot) {
    $this-&gt;host = $host;
  }

  function authenticate($user, $pass) {
    $result = [];
    $this-&gt;conn = ldap_connect($this-&gt;host);
    ldap_set_option(
      $this-&gt;conn,
      LDAP_OPT_PROTOCOL_VERSION,
      3
    );
    if (!@ldap_bind($this-&gt;conn))
      return -1;
    $result = ldap_search(
      $this-&gt;conn,
      &amp;quot&amp;quot,
      &amp;quot(&amp;(uid=$user)(userPassword=$pass))&amp;quot
    );
    $result = ldap_get_entries($this-&gt;conn, $result);
    return ($result[&amp;quotcount&amp;quot] &gt; 0 ? 1 : 0);
  }
}

if(isset($_GET[&amp;quotu&amp;quot]) &amp;&amp; isset($_GET[&amp;quotp&amp;quot])) {
  $ldap = new LDAPAuthenticator();
  if ($ldap-&gt;authenticate($_GET[&amp;quotu&amp;quot], $_GET[&amp;quotp&amp;quot])) {
    echo &amp;quotYou are now logged in!&amp;quot
  } else {
    echo &amp;quotUsername or password unknown!&amp;quot
  }
}Path Traversalاشاره به یک نوع حمله، که بخاطر sanitize نکردن ورودی، مهاجم را قادر می‌سازد که به فایل‌های غیر از آنچه برنامه نویس انتظار دارد دسترسی داشته باشد:$file = $_GET[&#039;file&#039;];
file_get_contents&#40;&#039;directory/&#039; . $file&#41;;Integer Overflowزمانی رخ می‌دهد که در محاسبات اعداد، خروجی با چیزی که برنامه نویس انتظار دارد تفاوت داشته باشد. مثلا  در جمع عدد ۱ با 9223372036854775807 ، انتظار می‌رود که حاصل یکی بیشتر شود، ولی در عمل اینگونه نیست. البته این مشکل در زبان‌هایی مثل C و C++  نمود بیشتری دارد.var_dump(PHP_INT_MAX+1);   //float(9.2233720368548E+18)Type Confusionزمانی که دو مقدار را با هم مقایسه می‌کنید، PHP نوع آنها را حدس و بر اساس آن مقایسه رو انجام می‌دهد. PHP یک زبان داینامیک است و معمولا به صورت خودکار بر روی داده‌ها تغییر نوع انجام می‌دهد. در کد زیر انتظار می‌رود که خروجی به ما False دهد، ولی اینگونه نیست:var_dump(&amp;quot0&amp;quot == &amp;quot-0&amp;quot);Phar Deserializationاین آسیب پذیری اولین بار در سال ۲۰۱۸ و در کنفرانس Black Hat معرفی شد. مشابه Object Injection است، با این تفاوت که نیازی به تابع unserialize برای اجرا ندارد. ولی نیاز به یک سری شرایط مثل تعریف magic methodها دارد که اگر فرصت کنم توی پست‌های بعدی مفصل‌تر توضیح میدم. مثال زیر دارای آسیب پذیری از این نوع است:class AnyClass {
	function __destruct() {
		echo $this-&gt;data;
	}
}
include(&#039;phar://test.phar&#039;);۳. آسیب پذیری‌های با درجه اهمیت Medium آسیب پذیری‌های این دسته معمولا برای بهره برداری نیاز به استفاده از تکنیک‌های مهندسی اجتماعی دارند. معمولا بعد از اکسپولیت تاثیر کمی برو روی کسب و کار سازمان می‌گذارند. اکسپلویت کردن آنها معمولا مشکل است. یا اینکه نیاز به سطح دسترسی خاصی دارند.Arbitrary File Deletionزمانی رخ می‌دهد که به کاربر اجازه دهیم فایل دلخواهی را حذف کند:unlink&#40;$_GET($file&#41;);Data Manipulationگاهی اوقات مهاجم نیازی به سرقت داده‌ها ندارد. با دستکاری داده‌ها، به آنچه نیاز دارد، می‌رسد.نباید به مهاجم اجازه دهیم تا محتویات فایل یا داه ای را تغییر دهد.Cross-Site Scripting (XSS)یک نمونه از حملات تزریق کد است که مهاجم کدهای مخرب خود را در یک وب سایت مطمئن تزریق می‌کند. هدف این گونه حملات، بازدیدکنندگان سایت است.print &amp;quotNot found: &amp;quot . urldecode($_SERVER[&amp;quotREQUEST_URI&amp;quot]);XQuery Injectionزبان XQuery (XML Query)، یک پرس و جو بر روی داده های ساخت یافته و غیر ساخت یافته مانند XML و فایل‌های متنی است. در این نوع حمله، مهاجم قادر به تغییر مفهوم پرس و جو است:$memstor = InMemoryStore::getInstance();
$z = Zorba::getInstance($memstor);
try {
  // get data manager
  $dataman = $z-&gt;getXmlDataManager();
  // load external XML document
  $dataman-&gt;loadDocument(&#039;users.xml&#039;, file_get_contents&#40;&#039;users.xml&#039;&#41;);
  // create and compile query
  $express =
&amp;quotfor \$user in doc(users.xml)//user[username=&#039;&amp;quot . $_GET[&amp;quotusername&amp;quot] . &amp;quot&#039;and pass=&#039;&amp;quot . $_GET[&amp;quotpassword&amp;quot] . &amp;quot&#039;] return \$user&amp;quot
  $query = $zorba-&gt;compileQuery($express);
  // execute query
  $result = $query-&gt;execute(); XPath Injectionزبان XPath یک پرس و جو برای انتخاب نود‌ها در یک سند XML است . این آسیب پذیری زمانی رخ می‌دهد که داده‌های ورودی از کاربر بدون sanitize کردن در در یک پرس و جو قرار داده شود:&amp;quot//Employee[UserName/text()=&#039;&amp;quot &amp; $_GET[&#039;UserName&#039;] &amp; &amp;quot&#039; And Password/text()=&#039;&amp;quot &amp; $_GET[&#039;Password&#039;] &amp; &amp;quot&#039;]&amp;quotReflection Injectionاین آسیب پذیری هم زمانی رخ می‌دهد که به اشتباه از Reflection در برنامه استفاده کنید. مهاجم معمولا در صورت وجود این نوع آسیب پذیری قادر به کنترل جریان برنامه و تزریق کد است.XSLT Injectionزبان XSLT مبتنی بر XML است و شیوه تبدیل از یک فایل XML به فایلی دیگر را توصیف می‌کند. در این نوع حمله مهاجم قادر است، ساختار و محتوای یک فایل XML رو تغییر دهد. که منجر به خواندن از  یک فایل یا اجرای یک دستور دلخواه می‌شود:$xml = new DOMDocument;
$xml-&gt;load(&#039;local.xml&#039;);
$xsl = new DOMDocument;
$xsl-&gt;load($_GET[&#039;key&#039;]);
$processor = new XSLTProcessor;
$processor-&gt;registerPHPFunctions();
$processor-&gt;importStyleSheet($xsl);
echo $processor-&gt;transformToXML($xml);XML/XXE Injectionیک نمونه از حملات که هدف آن برنامه ای است که ورودی XML را پردازش می‌کند. زمانی که ورودی XML حاوی یک رفرنس به یک موجودیت خارجی باشد و پیکربندی پردازشگر XML ضعفی داشته باشد، این حمله احتمال رخ دادنش وجود دارد.NoSQL Injectionحمله‌ای مشابه SQL Injection، با این تفاوت که بر روی پایگاه داده‌های NoSQL است.Session Fixationدر این حمله مهاجم یک session id معتبری دارد که کاربر را به سمت استفاده از این session id هدایت می‌کند. در واقع این حمله زمانی رخ می‌دهد که برنامه به جای تولید یک session id جدید در هر بار ارتباط، از یک session id ذخیره شده استفاده کند.Open Redirectاین حمله زمانی اتفاق می‌افتد که برنامه، ورودی را از مهاجم دریافت و به آن تغییر مسیر دهد. این کار می‌تواند کاربر را به یک سایت مخرب هدایت کند:&lt;?php
header(&amp;quotLocation: http://www.mysite.com&amp;quot);
exit;
?&gt;HTTP Response Splittingاین حمله زمانی رخ می‌دهد که داده‌ از طریق یک منبع نامطمئن مانند HTTP Request به برنامه ارسال شود. و یا اینکه داده ارسال شده به کاربر نهایی، بدون هیچگونه اعتبار سنجی در کاراکترهایش، در HTTP response header قرار گیرد.Variable Tamperingاین حمله زمانی اتفاق که مهاجم با قرار گرفتن در بین کاربر نهایی و سرور، داده‌های ارسالی به سمت سرور را تغییر دهد. حمله Man In The Middle.Mass Assignmentفرآیندی است که آرایه‌ای از داده‌ها را به یک کلاس ارسال می‌کند. یعنی نیاز نیست داده‌ها را یکی یکی ارسال کنیم. مشکلی ک این روش دارد این است که ممکن است مهاجم مقداری را بدون هیچگونه بررسی به این کلاس ارسال و منجر به نقص امنیتی شود. مثال زیر نمونه ای از این آسیب پذیری است:class User {
private $userid;
    private $password;
    private $email;
    private $isAdmin;

//Getters &amp; Setters
}۴. آسیب پذیری‌های با درجه اهمیت Lowاین دسته از آسیب پذیری‌ها اکسپلویت کردنشان مشکل و معمولا نیاز به دسترسی فیزیکی به سرور دارند. همچنین  تاثیر کمی بر روی کسب وکار یک سازمان دارند. Server-Side Request Forgeryاین حمله هنگامی رخ‌ میدهد که مهاجم بتواند درخواستی را به سمت سرور ارسال و منابع داخلی سیستم که در حالت عادی امکان دسترسی به آنها از بیرون وجود ندارد، مانند فایل‌هایی پشت فایروال یا تنظیمات پیکربندی را بخواند. در قطعه کد زیر، مشاهده می‌کنید که مهاجم کنترل کاملی روی پارامتر url دارد:&lt;?php
if (isset($_GET[&#039;url&#039;])){
$url = $_GET[&#039;url&#039;];
$image = fopen&#40;$url, &#039;rb&#039;&#41;;
header(&amp;quotContent-Type: image/png&amp;quot);
fpassthru&#40;$image&#41;;}Memcached Injectionاز Memcached برای انجام عملیات کش بر روی سرور به صورت داینامیک استفاده می‌شود. ولی در صورت استفاده نادرست می‌تواند منجر به نقص امنیتی شود. قطعه کد زیر این آسیب پذیری رو نشان می‌دهد:&lt;?php
$m = new Memcached();
$m-&gt;addServer(&#039;localhost&#039;, 11211);
$m-&gt;set(str_repeat(“a”,251),&amp;quotset injected 0 3600 10\r\n1234567890&amp;quot,30);?&gt;Resource Injectionمشابه حمله Path Traversal، با این تفاوت که تمرکز اصلی آن دسترسی به منابع سیستم است. در مثال زیر نام فایل موقت از کاربر گرفته شده و سپس حذف می‌شود. ولی یک مهاجم با وارد کردن آدرس یا نام منبعی غیر از آنچه برنامه نویس انتظار دارد، موجب حذف شدن آن منبع می‌شود:&lt;?php
$rName = $_GET[&#039;fileId&#039;];
$myfile = fopen&#40;&#039;/log/&#039;.$rName, &amp;quotr&amp;quot&#41;;
unlink&#40;$myfile&#41;?&gt;Environment Manipulationاین آسیب پذیری از آنجا ناشی می‌شود که یک مهاجم بتواند به پیکربندی سیستم دسترسی و آنرا تغییر دهد.HTTP Parameter Pollutionاین آسیب پذیری زمانی رخ می‌دهد که برنامه چندین پارامتر با نام یکسان را پذیرش کند. زمانی که این داده‌ها به سرور ارسال می‌شوند، با توجه به تنظیمات و پیکربندی سرور، این داده‌ها به طرق مختلف پردازش می‌شوند. مثلا در سرور آپاچی تنها آخرین پارامتر پردازش می‌شود. مهاجم با بهره برداری از این آسیب پذیری قادر به تغییر رفتار برنامه و حتی دور زدن WAF است.Weak Cryptographyاین آسیب پذیری از آنجا ناشی می‌شود که برای انجام عملیاتی مثل رمزنگاری فایل‌ها و داده‌ها، تولید هش، ایجاد اعداد تصادفی و غیر قابل حدس و ... از الگوریتم‌های ضعیف یا منسوخ شده استفاده کنیم. برای مثال قطعه کد زیر تابعی برای تولید اعداد تصادفی جهت رمزنگاری است. ولی ایراد آن این است که مقادیر تکراری تولید می‌کند و مناسب رمزنگاری نیست: function gen_uuid() {
    return sprintf( &#039; x x- x- x- x- x x x&#039;,
        mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ),
        mt_rand( 0, 0xffff ),
        mt_rand( 0, 0x0fff ) | 0x4000,
        mt_rand( 0, 0x3fff ) | 0x8000,
        mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ));}در انتها جا داره دوباره بگم که این لیست کمبود‌های زیادی داره و جمع آوری این لیست حاصل تجربه شخصی خودم در بررسی کدهاست. اگر شما هم پیشنهادی دارید توی نظرها بگید تا اعمال کنم. اگر بتوانم و وقت کنم بعدا همچین پستی برای زبان‌های دیگه مثل پایتون، جاوا و سی هم می نویسم.</description>
                <category>مرتضی مظاهریان</category>
                <author>مرتضی مظاهریان</author>
                <pubDate>Sun, 26 Jan 2020 16:12:26 +0330</pubDate>
            </item>
                    <item>
                <title>امنیت در PHP بخش ۱: SQL Injection</title>
                <link>https://virgool.io/@moorteza/sql-injection-%D8%AF%D8%B1-php-yp5ikhirdebi</link>
                <description>زبان PHP محبوب‌ترین زبان برنامه نویسی سمت سرور است. بر اساس داده‌های سایت W3Techs در سال ۲۰۱۹، ۷۹ درصد از وب سایت‌ها، قدرت گرفته از PHP هستند. وب سایت‌هایی مانند فیسبوک،یاهو و ویکی پدیا.از آنجایی که PHP زبان محبوبی است، امنیت در PHP امری ضروری است. متاسفانه تعداد برنامه‌های آسیب پذیر نوشته شده با PHP بسیار زیاد است. اغلب برنامه‌های نوشته شده با PHP بخشی از کد خود را با سایر برنامه‌ها به اشتراک می‌گذراند که اگه این کد‌های به اشتراک گذاشته شده دارای آسیب پذیری باشد، تمام برنامه‌هایی که از این کد استفاده کرده‌اند نیز آسیب پذیر می‌شوند.دلایل آسیب پذیریاغلب آسیب پذیری‌ها نتیجه عادت‌های غلط برنامه نویسی یا عدم آگاهی از امنیت برنامه‌های PHP است. علت این عدم آگاهی و عادت‌های بد، می‌تواند اعتماد برنامه نویس به ورودی کاربران به عنوان یک ورودی مطمئن باشد.زمانی که شما شروع به نوشتن کد می‌کنید، باید همیشه دو نکته را در ذهن داشته باشید: اعتبارسنجی و sanitization کردن داده‌های ورودی از کاربر. اگر این دو نکته را در هنگام نوشتن کد رعایت کنید، می‌توانید مطمئن شوید که آنچه را که پردازش و اجرا می‌کنید، معتبر است. همچنین باید مطمئن شوید که  خروجی شما از هرگونه کدهای مخرب که ممکن است توسط مهاجمان در داده‌های شما تزریق  و به کاربران آسیب برساند، مصون باشد. اگر این نکات ساده را برای هر درخواستی و پردازشی رعایت کنید، احتمال قرار گرفتن در معرض یک تهدید امنیتی را به حداقل می‌رسانید.برنامه نویسی شی گرا (OOP) نقش مهمی در اعمال امنیت در PHP دارد. کدی که قابلیت استفاده مجدد داشته باشد و به خوبی نوشته شده باشد، می‌تواند امنیت کلی یک سیستم را افزایش دهد. نوشتن یک کد مناسب و قابل فهم می‌تواند این تضمین را به ما بدهد که برنامه همیشه یک روند ثابت را برای پردازش دنبال می‌کند.تزریق کد SQL یا SQL Injection در PHPتزریق کد SQL یکی از خطرناک‌ترین  آسیب پذیری‌ها در برنامه‌های تحت وب است. این آسیب پذیری هر ساله در لیست سایت OWASP در کنار مواردی دیگری مانند XSS و CSRF، جایگاه شماره یک را در بین آسیب پذیری‌های برنامه‌های تحت وب را به خود اختصاص داده است. اگر شما ورودی کاربر را بدون اعتبار سنجی و sanitize کردن در یک کوئری قرار دهید، مهاجم این توانایی را دارد که کوئری و خروجی را مطابق با خواسته خود تغییر دهد.یک حمله موفق SQL Injection می‌تواند منجر به سرقت اطلاعاتی مثل: نام کاربری، رمز عبور، اطلاعات کارت اعتباری و یا هرگونه اطلاعات مهم و حساسی شود. در برخی موارد این حملات می‌تواند منجر به آسیب دیدن کل سرور شود. نمونه‌ای از کد نا امندر مثال زیر پارامتر &#x27;article&#x27; که از کاربر گرفته شده، به شکل نا امنی در کوئری استفاده شده است:$articleid = $_GET[&#039;article&#039;];
$query = &amp;quotSELECT * FROM articles WHERE articleid = &#039;$articleid&#039;&amp;quotیک مهاجم می‌تواند با قرار دادن مقداری خاص در ورودی ساختار پرس و جو را عوض کند. مثلا:1&#039;+union+select+1,version(),3&#039;که در نتیجه کوئری زیر حاصل می‌شود:$query = &amp;quotSELECT * FROM articles WHERE articleid = &#039;1&#039;+union+select+1,version(),3&#039;&#039;&amp;quotمهاجم می‌تواند از دستورات مشابهی استفاده کند تا کلیه جداول و ستون‌های پایگاه داده را استخراج و به اطلاعات حساس دسترسی پیدا کند. راه حل این مشکل استفاده از prepared statements هاست. در صورت استفاده از این گونه کوئری‌ها (parameterized queries) مشخص می‌کنید که کدام بخش از کوئری شما داده ورودی از سمت کاربر است. این قابلیتی است که به ما کمک می‌کند تا از تداخل  ورودی کاربر با دستورات SQL و تغییر در روال کوئری جلوگیری کنیم.توصیه می‌شود که برای اجرای prepared statements در کد PHP از PHP Data Objects (PDO) استفاده کنید. PDO از نسخه ۵.۱ تا نسخه نهایی (۷.۴.۲) PHP، در دسترس است.سعی کنید از افزونه‌های mysql در کدهای PHP استفاده نکنید. این افزونه‌ها معمولا بعد از مدتی منسوخ شده و دیگر قابل استفاده نیستند. شما به راحتی می‌توانید کده‌های نوشته شده با این افزونه‌ها را با PDO جایگزین کنید.نمونه‌ای از کد امندر این مثال، مقدار user_id  مستقیما به کوئری ارسال نمی‌شود. به جای آن از یک placeholder استفاده می‌کنیم و زمانی که تابع execute  اجرا می‌شود، پایگاه داده مقدار آنرا به صورت امن با ورودی کاربر جایگزین می‌کند.// User ID must not be empty, must be numeric and must be less than 5 characters long
if((!empty($_GET[&#039;user_id&#039;])) &amp;&amp; (is_numeric($_GET[&#039;user_id&#039;])) &amp;&amp; (mb_strlen($_GET[&#039;user_id&#039;])&lt;5)) {

  $servername = &amp;quotlocalhost&amp;quot
  $username = &amp;quotusername&amp;quot
  $password = &amp;quotpassword&amp;quot
  $database = &amp;quotdbname&amp;quot 

  // Establish a new connection to the SQL server using PDO
  try { 
    $conn = new PDO(&amp;quotmysql:host=$servername;dbname=$database&amp;quot, $username, $password); 

    // Assign user input to the $user_id variable 
    $user_id = $_GET[&#039;user_id&#039;]; 

    // Prepare the query and set a placeholder for user_id 
    $sth = $conn-&gt;prepare(&#039;SELECT user_name, user_surname FROM users WHERE user_id=?&#039;);

    // Execute the query by providing the user_id parameter in an array
    $sth-&gt;execute(array($user_id));

    // Fetch all matching rows
    $user = $sth-&gt;fetch();

    // If there is a matching user, display their info
    if(!empty($user)) {
      echo &amp;quotWelcome &amp;quot.$user[&#039;user_name&#039;].&amp;quot &amp;quot.$user[&#039;user_surname&#039;]; 
    } else {
      echo &amp;quotNo user found&amp;quot 
    }

    // Close the connection
    $dbh = null; 
  } catch(PDOException $e) {
    echo &amp;quotConnection failed.&amp;quot 
  }
} else {
  echo &amp;quotUser ID not specified or invalid.&amp;quot 
}منبع : acunetix</description>
                <category>مرتضی مظاهریان</category>
                <author>مرتضی مظاهریان</author>
                <pubDate>Sat, 25 Jan 2020 00:27:10 +0330</pubDate>
            </item>
                    <item>
                <title>برنامه نویسی امن در PHP</title>
                <link>https://virgool.io/@moorteza/%DA%A9%D8%AF%D9%86%D9%88%DB%8C%D8%B3%DB%8C-%D8%A7%D9%85%D9%86-%D8%AF%D8%B1-php-hjsyxplw1y4p</link>
                <description>زبان PHP محبوب ترین زبان سمت سرور برای ساخت وب سایت‌ها و برنامه‌های تحت وب است.مطابق آماری که سایت w3techs منتشر کرده، این زبان در ۷۹ درصد از وب سایت‌هایی که زبان سمت سرور آنها شناخته شده، مورد استفاده قرار گرفته است.دلایل زیادی برای احتیاط بیشتر هنگام برنامه نویسی با زبان PHP وجود دارد. PHP زبان سخاوتمندی است که در مقابل اشتباهات ساده برنامه نویسی، سخت گیری چندانی ندارد. همچنین کتابخانه‌ها و افزونه‌های زیادی برای این زبان نوشته شده‌ که کنترل و مدیریت خطاها و اشتباهات را عملا سخت و دشوار می‌کند.چگونه PHP را امن نگه داریم؟برای نوشتن برنامه امن در PHP، یک راهنمای جامع و پنج بخشی آماده کردیم که به مرور در سایت منتشر می‌کنیم.در بخش ۱، در مورد SQL Injection و جلوگیری از این حملات در PHP  صحبت می‌کنیم.در بخش ۲، در مورد آسیب پذیری‌های Code Injection و Directory Traversal صحبت می‌کنیم.در بخش ۳، یاد می‌گیریم که چگونه از حملات Cross-site Scripting(XSS) جلوگیری و رمزهای عبور خود را به طور ایمن ذخیره کنیم.در بخش ۴، تنظیمات مهمی که برای امنیت PHP مهم هستند را بیان می‌کنیم.در انتها در بخش ۵، یکسری از نکات و ترفندها را برای امنیت بیشتر معرفی می‌کنیم.منبع: Acunetix</description>
                <category>مرتضی مظاهریان</category>
                <author>مرتضی مظاهریان</author>
                <pubDate>Thu, 23 Jan 2020 23:24:16 +0330</pubDate>
            </item>
                    <item>
                <title>مبانی امنیت برنامه های تحت وب: آیا برنامه شما امن است؟</title>
                <link>https://virgool.io/fboard/%D9%85%D8%A8%D8%A7%D9%86%DB%8C-%D8%A7%D9%85%D9%86%DB%8C%D8%AA-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%87%D8%A7%DB%8C-%D8%AA%D8%AD%D8%AA-%D9%88%D8%A8-%D8%A2%DB%8C%D8%A7-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D8%B4%D9%85%D8%A7-%D8%A7%D9%85%D9%86-%D8%A7%D8%B3%D8%AA-pxwqwzbgvikr</link>
                <description>وب سایت acunetix در تبلیغات خود اینطور عنوان کرده  که ۷۰ درصد از برنامه‌های تحت وب آسیب پذیر و امکان هک کردن آنها وجود دارد. حقیقت تلخ اینکه، همه وب سایت‌ها و برنامه‌های تحت وب، امکان هک شدنشان وجود دارد. انجام این کار تنها نیاز به زمان و منابع کافی دارد.دسته‌بندی هکرها و اهداف آنهابرای درک بهتر خطرات و تهدیدهای امنیتی، ما ابتدا باید با انواع هکرها و اینکه چگونه اهداف خود را برای حمله انتخاب می‌کنند، آشنا شویم. هکرها در یک نمونه از دسته بندی‌ها براساس دانش، انگیزه و روش انجام کار، به گروه‌های زیر تقسیم می‌شوند:بچه اسکریپتی‌ها: این اصطلاح به هکرهای تازه کاری اشاره دارد که معمولا انگیزه اصلی‌شان کسب شهرت است. دانش فنی این هکرها محدود و از ابزارهای آماده استفاده می‌کنند. انگیزه‌ای برای دسترسی به داده‌های حساس ندارند، مگر اینکه این داده‌ها حاوی اطلاعات مالی، مانند اطلاعات کارت‌های اعتباری باشد.هکر‌های کلاه سیاه: این اصطلاح به هکرهای حرفه‌ای اشاره دارد که معمولا انگیزه اصلی آنها مالی است و روش‌هایی که به کار می‌برند غیر قانونی و غیر مجاز است. دانش فنی این دسته از هکرها معمولا بسیار گسترده و ممکن است برای اهداف خود روش‌ها و ابزارهای پیچیده‌ای را پیاده سازی کنند. متاسفانه روز به روز هکرهای بیشتری از این دست، درگیر جرائم سازمان یافته می‌شوند، که آنها را خطرناک‌تر از گذشته می‌کنند.هکرهای کلاه سفید: این اصطلاح هم به هکرهای حرفه‌ای اشاره دارد که انگیزه اصلی آنها نیز مالی است، ولی از روش‌های مجاز و قانونی برای اهداف خود استفاده می‌کنند. این دست از هکرها کمک می‌کنند تا آسیب پذیری‌ها را شناسایی و نسبت به آنها آگاهی پیدا کنیم. هکرهای کلاه سفید هیچگونه آسیبی به سیستم‌ها وارد نمی‌کنند. باید به آنها اطمینان و از آنها درخواست کنید تا در بررسی امنیت برنامه‌هایتان به شما کمک کنند.در ادامه ما بررسی می‌کنیم که هکرها چگونه اهداف خود را برای حمله انتخاب می‌کنند:حملات فرصت طلبانه: این حمله زمانی استفاده می‌شود که یک ضعف امنیتی در یک ابزار یا کد، با طیف وسیعی از کاربران و سیستم‌ها کشف شود و هدف به صورت تصادفی از بین این سیستم‌ها انتخاب می‌شود. هکرها سیستم‌هایی که از این ضعف امنیتی رنج می‌برند را شناسایی و از بین آنها، هدف خود را برای نفوذ انتخاب می‌کنند. برای مثال، یک هکر با بررسی آسیب پذیری‌های که برای وردپرس کشف و گزارش شده است، متوجه یک آسیب پذیری از نوع PHP Object Injection در نسخه‌های 4.9.9 و ماقبل آن می‌شود و سعی می‌کند اهداف خود را از بین سایت‌هایی که از این نسخه استفاده کرده‌اند، انتخاب کند.CVE-2018-20148. اغلب این حملات توسط بچه اسکریپتی‌ها انجام می‌شود.حملات هدفمند: این اصطلاح زمانی به کار می‌رود، که اهداف به منظور خاصی، توسط هکر یا حمله کننده انتخاب شوند. هکرها سعی می‌کنند برای هدفی که انتخاب کرده‌اند، یک آسیب پذیری پیدا و از طریق این آسیب پذیری، به هدف خود حمله کنند. مثلا فرض کنید که یک هکر، قصد جاسوسی از یک شرکت یا کارخانه جهت دسترسی به اطلاعات مشتریان را داشته باشد. برای عملی کردن نفوذ، نیاز است که ابتدا یک آسیب پذیری در سیستم هدف کشف و از طریق آن حمله و نفوذ را انجام دهد. این نوع حملات معمولا در دامنه هکرهای کلاه سیاه و توسط هکرهای کارکشته‌ و حرفه‌ای انجام می‌شود.تصور اینکه کسب و کار شما ارزش کمی برای هکرهای حرفه‌ای دارد،یک تصور اشتباه است. کسب و کار شما هر لحظه امکان آسیب دیدن توسط یک حمله فرصت طلبانه را دارد. اگر داده‌های حساسی دارید و فکر می‌کنید که امن‌ترین روش‌ها را برای محافطت از آنها به کار برده‌اید، باز هم اشتباه می‌کنید. در واقع هر چه بیشتر مکانیزم‌های امنیتی برای دفاع در مقابل حملات را بیشتر کنید، احتمال موفقیت نفوذگر کمتر می شود. ولی باز هم احتمال آسیب نرسیدن به شما صفر نمی‌شود. بزرگترین اشتباهی که می‌توانید مرتکب شوید این است که احساس کنید این موارد در مورد شما صدق نمی‌کند و حمله ای به سیستم‌های شما صورت نمی‌گیرد.اهمیت امنیت در برنامه‌های تحت وبحمله و نفوذ به برنامه‌های تحت وب و وب سایت‌ها، فقط از طریق آسیب پذیری در بخشی از کد برنامه یا مشکل در پیاده سازی برنامه صورت نمی‌گیرد، بلکه نفوذگر می‌تواند از روش‌ها و تکنیک‌های دیگری مثل مهندسی اجتماعی (از جمله فیشینگ) برای نفوذ استفاده کند. با وجود اینکه امنیت برنامه‌های تحت وب بسیار مهم است، ولی هنوز خیلی از سازمان‌ها و مشاغل در مقابل این نوع حملات (مهندسی اجتماعی) آسیب پذیرند. در ادامه لیستی از راهکارها و توصیه ها، برای دست یافتن به بهترین سطح امنیتی را معرفی می‌کنیم:استفاده از روش‌های ابتکاری: اگر برای شناسایی حملات تنها از روش‌های مبتنی بر امضا (شناسایی و کشف حملات شناخته شده) استفاده کنید، سیستم شما تنها در برابر حملاتی از جانب بچه اسکریپتی‌ها و هکرهای تازه کار مقاوم است. هکرهای کارکشته و حرفه ای معمولا برای پیدا کردن آسیب پذیری، یا به صورت دستی و یا با استفاده از ابزارهایی که به صورت اکتشافی با استفاده از ابزارهایی مانند Acunetix، یک سیستم را بررسی، آسیب پذیری‌ها را کشف و به سیستم شما نفوذ می‌کنند.اولویت بالاتر امنیت وب نسبت به امنیت شبکه: اگر اولویت و تمرکز خود را بیشتر به سمت امنیت شبکه معطوف کرده‌اید، باید به این نکته توجه داشته باشید که بیشتر مشکلات و مباحثی که در حوزه امنیت اطلاعات در سال‌های گذشته رخ و کشف شده است، ناشی از مشکلات و آسیب پذیری‌های مربوط به امنیت وب بوده است. با یک نگاه به لیست ۱۰ آسیب پذیری اول در حوزه امنیت وب، مشاهده می‌کنیم که عمده این آسیب پذیری‌ها از نوع SQL Injection، Cross Site Scripting (XSS)، CSRF و یا مشکلات پیکربندی هستند.از بین بردن منبع مشکلات: اگر احساس می کنید که یک فایروال برای محافظت از داده‌های شما مناسب است، باید این واقعیت را قبول کنید که خط مشی‌ها و قوانینی که در WAF ها برای جلوگیری از نفوذ اعمال می‌شود، اغلب قابل دور زدن هستند. در واقع WAF منبع مشکل را از بین نمی‌برد، بلکه تنها یک کمک و پشتیبان برای بهبود موقت امنیت سیستم است.امنیت برنامه‌های وب، تنها به کشف آسیب پذیری‌های امنیتی و از بین بردن آنها نمی‌پردازد، بلکه شامل پیشگیری از آسیب رسانی هم می‌شود، که می‌تواند شامل تغییر روش و رویکرد در فرآیند توسعه برنامه‌ها باشد. در ادامه این روش‌ها را بررسی می‌کنیم:آموزش: کارآمدترین روش برای کاهش سطح حمله ، آموزش کل تیم است. توسعه دهندگان ، سرپرستان ، آزمایش کنندگان و حتی افراد غیر فنی باید از موضوعات بالقوه امنیت وب آگاه باشند و باید بدانند که چگونه از این آسیب پذیری‌ها و مباحث و مشکلات مربوط به آنها در امان باشند.انتقال به چپ: مباحث مربوط به امنیت، در فرايند تولید و تست نرم افزار، باید به گونه ای باشد که مشکلات امنیتی در اسرع وقت شناسایی و رفع شوند. اگر بعد از تست این مشکلات شناسایی و کشف شوند، نشان از عدم بهینه سازی و ناکار آمدی تست نرم افزار است.همه ابعاد را در نظر بگیرید: این نکته را هیچوقت فراموش نکنید که امنیت برنامه‌های شما نه تنها باید در سمت سرور و کلاینت، بلکه باید در API ها، سرویس‌های تلفن همراه، دستگاه‌های IOT و هرجایی که برنامه‌های شما مورد استفاده قرار می‌گیرد، اعمال شود.منبع : acunetix</description>
                <category>مرتضی مظاهریان</category>
                <author>مرتضی مظاهریان</author>
                <pubDate>Wed, 22 Jan 2020 16:05:38 +0330</pubDate>
            </item>
            </channel>
</rss>