PDA

View Full Version : بررسی امنیت ورودی تابع



رامین مرادی
چهارشنبه 08 آذر 1396, 08:46 صبح
دوستان بنظرتون این دوتا تابع میتونن امنیت ورودی رو بررسی کنن؟ نیازه بیشتر از این روش کار بشه؟:متفکر:



public string GetGovahinameh(string unit, string certificateId, string date)
{
try
{
if (string.IsNullOrEmpty(unit))
unit = "";
if (string.IsNullOrEmpty(certificateId))
certificateId = "";
if (string.IsNullOrEmpty(date))
date = "";
if (certificateId.ToString() != "")
{
if (!CheckParametr(unit.ToString()) || !CheckParametr(certificateId.ToString()) || !CheckParametr(date.ToString()))
{
return "ERROR: شما از یک مقدار غیر مجاز استفاده کردید";
}
else
{
Unit = unit;
CertificateId = certificateId;
Date = date;
return Exqute();
}
}
else if (certificateId == "" || certificateId == null || string.IsNullOrEmpty(certificateId))
{
return "ERROR: فیلد شماره گواهینامه نباید خالی باشد";
}
return "";
}
catch (Exception ex)
{
return "ERROR: خطای نامشخصی رخ داده است لطفا دوباره سعی نمایید." + ex.Message;
}
}
private bool CheckParametr(string Value)
{
if (Value.ToLower().Contains("select"))
return false;
else if (Value.ToLower().Contains("delete"))
return false;
else if (Value.ToLower().Contains("update"))
return false;
else if (Value.ToLower().Contains("union"))
return false;
else if (Value.ToLower().Contains("join"))
return false;
else if (Value.ToLower().Contains("drop"))
return false;
else if (Value.ToLower().Contains("create"))
return false;
else if (Value.ToLower().Contains("table"))
return false;
else if (Value.ToLower().Contains("where"))
return false;
else if (Value.ToLower().Contains("order by"))
return false;
else if (Value.ToLower().Contains("group by"))
return false;
else if (Value.ToLower().Contains("having "))
return false;
else if (Value.ToLower().Contains("and"))
return false;
else if (Value.ToLower().Contains("or"))
return false;
else if (Value.ToLower().Contains("in"))
return false;
else if (Value.ToLower().Contains("max"))
return false;
else if (Value.ToLower().Contains("min"))
return false;
else if (Value.ToLower().Contains("count"))
return false;
else if (Value.ToLower().Contains("'"))
return false;
else if (Value.ToLower().Contains("="))
return false;
else if (Value.ToLower().Contains("null"))
return false;
else
{
return true;
}
}

ژیار رحیمی
چهارشنبه 08 آذر 1396, 12:05 عصر
اگر هدف شما اعتبار سنجی Sql syntax هست میتونی از اعتبار سنجی سمت سرور استفاده کنیhttps://stackoverflow.com/a/6287892/7325558
و اگر هدف شما جلوگیری از Sql Injection هست اولا لازم به چک کردن تمام کلمات کلیدی script نیست و در ثانی بجای مقایسه های زیاد ، رشته ورودی کاربر در صورتی که دارای کلمات کلیدی(create,drop,delete,update,insert,select ) باشد را با مقدار نال Replace کن.

رامین مرادی
چهارشنبه 08 آذر 1396, 13:24 عصر
اگر هدف شما اعتبار سنجی Sql syntax هست میتونی از اعتبار سنجی سمت سرور استفاده کنیhttps://stackoverflow.com/a/6287892/7325558
و اگر هدف شما جلوگیری از Sql Injection هست اولا لازم به چک کردن تمام کلمات کلیدی script نیست و در ثانی بجای مقایسه های زیاد ، رشته ورودی کاربر در صورتی که دارای کلمات کلیدی(create,drop,delete,update,insert,select ) باشد را با مقدار نال Replace کن.
این موردو برای استفاده در وب سرویسم در نظر گرفتم. برای جلوگیری از sql injection اینکارو دارم میکنم.اولین باره دارم وب سرویس مینویسم نمیخوام الکی کار دست خودم بدم. کلا برای چک کردن ورودی های کاربر این مورد کافیه؟(مورد آخرتون رو بیشتر توضیح میدید)

ژیار رحیمی
چهارشنبه 08 آذر 1396, 14:37 عصر
نگاهی به وب سرویس ها انداخته باشی ،پیاده سازی آن بصورت متد هایی هست که دادهای کاربر رو از طریق کلاس های تعریف شده در آن دریافت میکنند.اصولا دریافت کویری sql از وب سرویس اشتباه میباشد.شما وب سرویس رو به دو لایه برنامه نویسی Model و Service تقسیم کنید متدها و کلاس های لازم رو در سطح سرویس پیاده سازی کن که کاربر به آن دسترسی دارد.و لایه Model که دسترسی آن فقط از طریق لایه Service امکان پذیر است و کاربر امکان دسترسی مستقیم به متدهای آن را ندارد و و ظیفه دریافت اطلاعات از لایه سرویس و اعمال ان در دیتابیس هست.در لایه Model از Linq to Sql ویا Entityframework استفاده کنی ریسک Sql injection به پایین میاد.
در مورد توضیح:

public string RemoveSqlScript(string userInput)
{
if(userInput==null)return string.Empty;
return userInput.Replce("create","").Replce("delete","").Replce("drop","");
}

رامین مرادی
چهارشنبه 08 آذر 1396, 14:44 عصر
نگاهی به وب سرویس ها انداخته باشی ،پیاده سازی آن بصورت متد هایی هست که دادهای کاربر رو از طریق کلاس های تعریف شده در آن دریافت میکنند.اصولا دریافت کویری sql از وب سرویس اشتباه میباشد.شما وب سرویس رو به دو لایه برنامه نویسی Model و Service تقسیم کنید متدها و کلاس های لازم رو در سطح سرویس پیاده سازی کن که کاربر به آن دسترسی دارد.و لایه Model که دسترسی آن فقط از طریق لایه Service امکان پذیر است و کاربر امکان دسترسی مستقیم به متدهای آن را ندارد و و ظیفه دریافت اطلاعات از لایه سرویس و اعمال ان در دیتابیس هست.در لایه Model از Linq to Sql ویا Entityframework استفاده کنی ریسک Sql injection به پایین میاد.
در مورد توضیح:

public string RemoveSqlScript(string userInput)
{
if(userInput==null)return string.Empty;
return userInput.Replce("create","").Replce("delete","").Replce("drop","");
}

تقریبا همین روالی که فرومدید دارم پیش میرم. یه لایه دسترسی به داده ها دارم. یه لایه سرویس و یه لایه مابین این دوتا که این دو رو به هم مرتبط میکنه. من این متد ها رو داخل لایه میانی نوشتم که ورودی رو کنترل کنه و بفرسته به لایه دیتا اکسس و نتیجه رو بگیره و برگردونه به سرویس. هیچ دسترسی مستقیمی از لایه سرویس به لایه دیتااکسس وجود نداره.بازم اگه راهی که پیش میرم اشتباهه ممنون میشم راهنمایی کنید.

ژیار رحیمی
چهارشنبه 08 آذر 1396, 16:49 عصر
لازم به لایه میانی نیست شما اعتبارسنجی داده های ورودی را درلایه Service می نویسی در صورت معتبر نبودن لازم نیست به لایه Model پاس شود . در همان لایه Service در صورت معتبر نبودن پیام خطا به کاربر برگرداند

رامین مرادی
پنج شنبه 09 آذر 1396, 08:27 صبح
لازم به لایه میانی نیست شما اعتبارسنجی داده های ورودی را درلایه Service می نویسی در صورت معتبر نبودن لازم نیست به لایه Model پاس شود . در همان لایه Service در صورت معتبر نبودن پیام خطا به کاربر برگرداند

مهندس جان در ضمن من تصاویر رو با فرمت base64 برمیگردونم که گاها زمان اجراش وقتی حجم عکس یا فایل زیاد باشه طول میکشه تا برگردونه.به نظرتون برا کاهش این زمان میشه کاری کرد؟

sg.programmer
پنج شنبه 09 آذر 1396, 12:30 عصر
نگاهی به وب سرویس ها انداخته باشی ،پیاده سازی آن بصورت متد هایی هست که دادهای کاربر رو از طریق کلاس های تعریف شده در آن دریافت میکنند.اصولا دریافت کویری sql از وب سرویس اشتباه میباشد.شما وب سرویس رو به دو لایه برنامه نویسی Model و Service تقسیم کنید متدها و کلاس های لازم رو در سطح سرویس پیاده سازی کن که کاربر به آن دسترسی دارد.و لایه Model که دسترسی آن فقط از طریق لایه Service امکان پذیر است و کاربر امکان دسترسی مستقیم به متدهای آن را ندارد و و ظیفه دریافت اطلاعات از لایه سرویس و اعمال ان در دیتابیس هست.در لایه Model از Linq to Sql ویا Entityframework استفاده کنی ریسک Sql injection به پایین میاد.
در مورد توضیح:

public string RemoveSqlScript(string userInput)
{
if(userInput==null)return string.Empty;
return userInput.Replce("create","").Replce("delete","").Replce("drop","");
}


آیا نمونه پروژه ای با وب سرویس دارید تا از اون الگو برداری بشه
تشکر

Mahmoud.Afrad
جمعه 10 آذر 1396, 13:23 عصر
اگر مقادیر رو با پارامتر به دیتابیس ارسال کنید دیگه نیازی به این کارها نیست.

ASKaffash
سه شنبه 14 آذر 1396, 07:28 صبح
سلام
خیلی پیچیده فکر می کنید حذف کلمات کار اشتباهی است چون یک رشته انگلیسی درونش شاید از لغت مثلا" Delete استفاده کرده باشد شما برای رشته های ورودی فقط کارکتر ' را حذف کن SQL Injection کارش تمام است و یا از SP استفاده کنید و درون SP از Dynamic SQL استفاده نکنید

رامین مرادی
سه شنبه 14 آذر 1396, 08:31 صبح
سلام
خیلی پیچیده فکر می کنید حذف کلمات کار اشتباهی است چون یک رشته انگلیسی درونش شاید از لغت مثلا" Delete استفاده کرده باشد شما برای رشته های ورودی فقط کارکتر ' را حذف کن SQL Injection کارش تمام است و یا از SP استفاده کنید و درون SP از Dynamic SQL استفاده نکنید
سلام. بله میدونم ممکنه کلمات کلیدی دیگه ای هم استفاده بشه . اما ورودی من مشخصه که باید چی باشه یه سری حرف و عدد شبیه TRA96/442-110104 این هست که قسمت عددیش فرق میکنه.
بازم ممنون بابت اعلام نظر مفیدتون

محمد آشتیانی
سه شنبه 14 آذر 1396, 09:55 صبح
سلام
همونطور که آقای افراد فرمودند ، اگر در لایه دیتا از ADO.Net استفاده می کنید ، کافیه از پارامترها استفاده کنید ، به این ترتیب نگرانی از بابت Sql Injection وجود نداره.
بنابراین نیازی به چک کردن ورودی ها به این شکل وجود نداره ، درسته شما ورودی ها رو باید برای صحتشون در لایه Business چک کنید اما نه این مفهومی که در سوالتون اشاره کردید

رامین مرادی
سه شنبه 14 آذر 1396, 10:36 صبح
سلام
همونطور که آقای افراد فرمودند ، اگر در لایه دیتا از ADO.Net استفاده می کنید ، کافیه از پارامترها استفاده کنید ، به این ترتیب نگرانی از بابت Sql Injection وجود نداره.
بنابراین نیازی به چک کردن ورودی ها به این شکل وجود نداره ، درسته شما ورودی ها رو باید برای صحتشون در لایه Business چک کنید اما نه این مفهومی که در سوالتون اشاره کردید
استاد در مورد برگردوندن عکس به صورت base64 در وب سرویس نظری ندارید؟ گاها این مورد زمان زیادی طول میکشه تا عکس رو برگردونه .

محمد آشتیانی
سه شنبه 14 آذر 1396, 15:10 عصر
سلام
طول مکیشه چون حجم عکس به هر حال زیاده ، علاوه بر این زمانی هم صرف تبدیل عکس به Base64 میشه ، کار خاصی به نظر بنده نمیرسه که بشه انجام داد

رامین مرادی
سه شنبه 14 آذر 1396, 15:31 عصر
سلام
طول مکیشه چون حجم عکس به هر حال زیاده ، علاوه بر این زمانی هم صرف تبدیل عکس به Base64 میشه ، کار خاصی به نظر بنده نمیرسه که بشه انجام داد
ممنون بابت اظهار نظر مفیدتون