اشتراک‌ها
بررسی فنی بدافزار Regin

نسخه‌های مختلف Regin براساس برخی روایت‌ها بیش از یک دهه است به جاسوسی از کشورهای مختلف می‌پردازد. در حالی که در بیشتر موارد، مهاجمان تمرکز شان بر روی استخراج اطلاعات حساس مانند ایمیل‌ها و مستندات است، مواردی نیز مشاهده شده است که مهاجمان اپراتورهای مخابراتی را نیز مورد هدف قرار داده تا راه را برای حملات اضافی باز کنند.  

بررسی فنی بدافزار Regin
نظرات مطالب
Blazor 5x - قسمت 31 - احراز هویت و اعتبارسنجی کاربران Blazor WASM - بخش 1 - انجام تنظیمات اولیه
تا زمانیکه بتوانید در برابر حملات XSS مقاومت کنید، خیر. برای این مورد هم فعالسازی content security policy توصیه می‌شود:
نظرات مطالب
امنیت در LINQ to SQL
یک نکته‌ی تکمیلی
اگر از Entity framework استفاده کرده و کوئری‌های SQL را به نحو مستقیمی بر روی بانک اطلاعاتی اجرا می‌کنید، می‌توانید لیست مواردی را که ممکن است مستعد به حملات تزریق اس کیوال باشند، در برنامه‌ی DNTProfiler مشاهده کنید:

مطالب
طراحی ValidationAttribute دلخواه و هماهنگ سازی آن با ASP.NET MVC
در سری پست‌های آقای مهندس یوسف نژاد با عنوان Globalization در ASP.NET MVC روشی برای پیاده سازی کار با Resource‌ها در ASP.NET با استفاده از دیتابیس شرح داده شده است. یکی از کمبودهایی که در این روش وجود داشت عدم استفاده از این نوع Resourceها از طریق Attributeها در ASP.NET MVC بود. برای استفاده از این روش در یک پروژه به این مشکل برخورد کردم و پس از تحقیق و بررسی چند پست سرانجام در این پست  پاسخ خود را پیدا کرده و با ترکیب این روش با روش آقای یوسف نژاد موفق به پیاده سازی Attribute دلخواه شدم.
در این پست و با استفاده از سری پست‌های آقای مهندس یوسف نژاد  در این زمینه، یک Attribute جهت هماهنگ سازی با سیستم اعتبار سنجی ASP.NET MVC در سمت سرور و سمت کلاینت (با استفاده از jQuery Validation) بررسی خواهد شد.

قبل از شروع مطالعه سری پست‌های MVC و Entity Framework الزامی است.

برای انجام این کار ابتدا مدل زیر را در برنامه خود ایجاد می‌کنیم.

using System;

public class SampleModel
{
public DateTime StartDate { get; set; }
public string Data { get; set; }
public int Id { get; set; }
با استفاده از این مدل در برنامه در زمان ثبت داده‌ها هیچ گونه خطایی صادر نمی‌شود. برای اینکه بتوان از سیستم خطای پیش فرض ASP.NET MVC کمک گرفت می‌توان مدل را به صورت زیر تغییر داد.
using System;
using System.ComponentModel.DataAnnotations;

public class SampleModel
{
    [Required(ErrorMessage = "Start date is required")]
    public DateTime StartDate { get; set; }

    [Required(ErrorMessage = "Data is required")]
    public string Data { get; set; }

    public int Id { get; set; }
}
حال ویو این مدل را طراحی می‌کنیم.
@model SampleModel
@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<section>
    <header>
        <h3>SampleModel</h3>
    </header>
    @Html.ValidationSummary(true, null, new { @class = "alert alert-error alert-block" })

    @using (Html.BeginForm("SaveData", "Sample", FormMethod.Post))
    {
        <p>
            @Html.LabelFor(x => x.StartDate)
            @Html.TextBoxFor(x => x.StartDate)
            @Html.ValidationMessageFor(x => x.StartDate)
        </p>
        <p>
            @Html.LabelFor(x => x.Data)
            @Html.TextBoxFor(x => x.Data)
            @Html.ValidationMessageFor(x => x.Data)
        </p>
        <input type="submit" value="Save"/>
    }
</section>
و بخش کنترلر آن را به صورت زیر پیاده سازی می‌کنیم.
 public class SampleController : Controller
    {
        //
        // GET: /Sample/

        public ActionResult Index()
        {
            return View();
        }

        public ActionResult SaveData(SampleModel item)
        {
            if (ModelState.IsValid)
            {
                //save data
            }
            else
            {
                ModelState.AddModelError("","لطفا خطاهای زیر را برطرف نمایید");
                RedirectToAction("Index", item);
            }
            return View("Index");
        }
    }
حال با اجرای این کد و زدن دکمه Save صفحه مانند شکل پایین خطاها را نمایش خواهد داد.

تا اینجای کار روال عادی همیشگی است. اما برای طراحی Attribute دلخواه جهت اعتبار سنجی (مثلا برای مجبور کردن کاربر به وارد کردن یک فیلد با پیام دلخواه و زبان دلخواه) باید یک کلاس جدید تعریف کرده و از کلاس RequiredAttribute ارث ببرد. در پارامتر ورودی این کلاس جهت کار با Resource‌های ثابت در نظر گرفته شده است اما برای اینکه فیلد دلخواه را از دیتابیس بخواند این روش جوابگو نیست. برای انجام آن باید کلاس RequiredAttribute بازنویسی شود.

کلاس طراحی شده باید به صورت زیر باشد:

public class VegaRequiredAttribute : RequiredAttribute, IClientValidatable
    {
#region Fields (2) 

        private readonly string _resourceId;
        private String _resourceString = String.Empty;

#endregion Fields 

#region Constructors (1) 

        public VegaRequiredAttribute(string resourceId)
        {
            _resourceId = resourceId;
            ErrorMessage = _resourceId;
            AllowEmptyStrings = true;
        }

#endregion Constructors 

#region Properties (1) 

        public new String ErrorMessage
        {
            get { return _resourceString; }
            set { _resourceString = GetMessageFromResource(value); }
        }

#endregion Properties 

#region Methods (2) 

// Public Methods (1) 

        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {

            yield return new ModelClientValidationRule
            {
                ErrorMessage = GetMessageFromResource(_resourceId),
                ValidationType = "required"
            };
        }
// Private Methods (1) 

        private string GetMessageFromResource(string resourceId)
        {
            var errorMessage = HttpContext.GetGlobalResourceObject(_resourceId, "Yes") as string;
            return errorMessage ?? ErrorMessage;
        }

#endregion Methods 
    }
در این کلاس دو نکته وجود دارد.
1- ابتدا دستور
HttpContext.GetGlobalResourceObject(_resourceId, "Yes") as string;  

که عنوان کلید Resource را از سازنده کلاس گرفته (کد اقای یوسف نژاد) رشته معادل آن را از دیتابیس بازیابی میکند.

2- ارث بری از اینترفیس IClientValidatable، در صورتی که از این اینترفیس ارث بری نداشته باشیم. Validator طراحی شده در طرف کلاینت کار نمی‌کند. بلکه کاربر با کلیک بروی دکمه مورد نظر داده‌ها را به سمت سرور ارسال می‌کند. در صورت وجود خطا در پست بک خطا نمایش داده خواهد شد. اما با ارث بری از این اینترفیس و پیاده سازی متد GetClientValidationRules می‌توان تعریف کرد که در طرف کلاینت با استفاده از Unobtrusive jQuery  پیام خطای مورد نظر به کنترل ورودی مورد نظر (مانند تکست باکس) اعمال می‌شود. مثلا در این مثال خصوصیت data-val-required به input هایی که قبلا در مدل ما Reqired تعریف شده اند اعمال می‌شود.

حال در مدل تعریف شده می‌توان به جای Required می‌توان از VegaRequiredAttribute مانند زیر استفاده کرد. (همراه با نام کلید مورد نظر در دیتابیس)

public class SampleModel
{
    [VegaRequired("RequiredMessage")]
    public DateTime StartDate { get; set; }

    [VegaRequired("RequiredMessage")]
    public string Data { get; set; }

    public int Id { get; set; }
}
ورودی Validator مورد نظر نام کلیدی است به زبان دلخواه که عنوان آن RequiredMessage تعریف شده است و مقدار آن در دیتابیس مقداری مانند "تکمیل این فیلد الزامی است" است. با این کار در زمان اجرا با استفاده از این ولیدتور ابتدا کلید مورد نظر با توجه به زبان فعلی از دیتابیس بازیابی شده و در متادیتابی مدل ما قرار می‌گیرد. به جای استفاده از Resource‌ها می‌توان پیام‌های خطای دلخواه را در دیتابیس ذخیره کرد و در مواقع ضروری جهت جلوگیری از تکرار از آنها استفاده نمود.
با اجرای برنامه اینبار خروجی به شکل زیر خواهد بود.

جهت فعال ساری اعتبار سنجی سمت کلاینت ابتدا باید اسکریپت‌های زیر به صفحه اضافه شود.
<script src="@Url.Content("~/Scripts/jquery-1.9.1.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
سپس در فایل web.config تنظیمات زیر باید اضافه شود
<appSettings>
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true"/>
</appSettings>
سپس برای اعمال Validator طراحی شده باید توسط کدهای جاوا اسکریپت زیر داده‌های مورد نیاز سمت کلاینت رجیستر شوند.
<script type="text/javascript">
        jQuery.validator.addMethod('required', function (value, element, params) {
            if (value == null | value == "") {
                return false;
            } else {
                return true;
            }

        }, '');

        jQuery.validator.unobtrusive.adapters.add('required', {}, function (options) {
            options.rules['required'] = true;
            options.messages['required'] = options.message;
        });
    </script>
البته برای مثال ما قسمت بالا به صورت پیش فرض رجیستر شده است اما در صورتی که بخواهید یک ولیدتور دلخواه و غیر استاندارد بنویسید روال کار به همین شکل است.
موفق و موید باشید.
منابع ^ و ^ و ^ و ^
مطالب
معرفی JSON Web Token


دو روش کلی و پرکاربرد اعتبارسنجی سمت سرور، برای برنامه‌های سمت کاربر وب وجود دارند:
الف) Cookie-Based Authentication که پرکاربردترین روش بوده و در این حالت به ازای هر درخواست، یک کوکی جهت اعتبارسنجی کاربر به سمت سرور ارسال می‌شود (و برعکس).


ب) Token-Based Authentication که بر مبنای ارسال یک توکن امضاء شده به سرور، به ازای هر درخواست است.


مزیت‌های استفاده‌ی از روش مبتنی بر توکن چیست؟

 • Cross-domain / CORS: کوکی‌ها و CORS آنچنان با هم سازگاری ندارند؛ چون صدور یک کوکی وابسته‌است به دومین مرتبط به آن و استفاده‌ی از آن در سایر دومین‌ها عموما پذیرفته شده نیست. اما روش مبتنی بر توکن، وابستگی به دومین صدور آن‌را ندارد و اصالت آن بر اساس روش‌های رمزنگاری تصدیق می‌شود.
 • بدون حالت بودن و مقیاس پذیری سمت سرور: در حین کار با توکن‌ها، نیازی به ذخیره‌ی اطلاعات، داخل سشن سمت سرور نیست و توکن موجودیتی است خود شمول (self-contained). به این معنا که حاوی تمام اطلاعات مرتبط با کاربر بوده و محل ذخیره‌ی آن در local storage و یا کوکی سمت کاربر می‌باشد.
 • توزیع برنامه با CDN: حین استفاده از روش مبتنی بر توکن، امکان توزیع تمام فایل‌های برنامه (جاوا اسکریپت، تصاویر و غیره) توسط CDN وجود دارد و در این حالت کدهای سمت سرور، تنها یک API ساده خواهد بود.
 • عدم در هم تنیدگی کدهای سمت سرور و کلاینت: در حالت استفاده‌ی از توکن، این توکن می‌تواند از هرجایی و هر برنامه‌ای صادر شود و در این حالت نیازی نیست تا وابستگی ویژه‌ای بین کدهای سمت کلاینت و سرور وجود داشته باشد.
 • سازگاری بهتر با سیستم‌های موبایل: در حین توسعه‌ی برنامه‌های بومی پلتفرم‌های مختلف موبایل، کوکی‌ها روش مطلوبی جهت کار با APIهای سمت سرور نیستند. تطابق یافتن با روش‌های مبتنی بر توکن در این حالت ساده‌تر است.
 • CSRF: از آنجائیکه دیگر از کوکی استفاده نمی‌شود، نیازی به نگرانی در مورد حملات CSRF نیست. چون دیگر برای مثال امکان سوء استفاده‌ی از کوکی فعلی اعتبارسنجی شده، جهت صدور درخواست‌هایی با سطح دسترسی شخص لاگین شده وجود ندارد؛ چون این روش کوکی را به سمت سرور ارسال نمی‌کند.
 • کارآیی بهتر: حین استفاده‌ی از توکن‌ها، به علت ماهیت خود شمول آن‌ها، رفت و برگشت کمتری به بانک اطلاعاتی صورت گرفته و سرعت بالاتری را شاهد خواهیم بود.
 • امکان نوشتن آزمون‌های یکپارچگی ساده‌تر: در حالت استفاده‌ی از توکن‌ها، آزمودن یکپارچگی برنامه، نیازی به رد شدن از صفحه‌ی لاگین را ندارد و پیاده سازی این نوع آزمون‌ها ساده‌تر از قبل است.
 • استاندارد بودن: امروزه همینقدر که استاندارد JSON Web Token را پیاده سازی کرده باشید، امکان کار با انواع و اقسام پلتفرم‌ها و کتابخانه‌ها را خواهید یافت.


اما JWT یا JSON Web Token چیست؟

JSON Web Token یا JWT یک استاندارد وب است (RFC 7519) که روشی فشرده و خود شمول (self-contained) را جهت انتقال امن اطلاعات، بین مقاصد مختلف را توسط یک شیء JSON، تعریف می‌کند. این اطلاعات، قابل تصدیق و اطمینان هستند؛ از این‌رو که به صورت دیجیتال امضاء می‌شوند. JWTها توسط یک کلید مخفی (با استفاده از الگوریتم HMAC) و یا یک جفت کلید خصوصی و عمومی (توسط الگوریتم RSA) قابل امضاء شدن هستند.
در این تعریف، واژه‌هایی مانند «فشرده» و «خود شمول» بکار رفته‌اند:
 - «فشرده بودن»: اندازه‌ی شیء JSON یک توکن در این حالت کوچک بوده و به سادگی از طریق یک URL و یا پارامترهای POST و یا داخل یک HTTP Header قابل ارسال است و به دلیل کوچک بودن این اندازه، انتقال آن نیز سریع است.
 - «خود شمول»: بار مفید (payload) این توکن، شامل تمام اطلاعات مورد نیاز جهت اعتبارسنجی یک کاربر است؛ تا دیگر نیازی به کوئری گرفتن هر باره‌ی از بانک اطلاعاتی نباشد (در این روش مرسوم است که فقط یکبار از بانک اطلاعاتی کوئری گرفته شده و اطلاعات مرتبط با کاربر را امضای دیجیتال کرده و به سمت کاربر ارسال می‌کنند).


چه زمانی بهتر است از JWT استفاده کرد؟

اعتبارسنجی: اعتبارسنجی یک سناریوی متداول استفاده‌ی از JWT است. زمانیکه کاربر به سیستم لاگین کرد، هر درخواست بعدی او شامل JWT خواهد بود که سبب می‌شود کاربر بتواند امکان دسترسی به مسیرها، صفحات و منابع مختلف سیستم را بر اساس توکن دریافتی، پیدا کند. برای مثال روش‌های «Single Sign On» خود را با JWT انطباق داده‌اند؛ از این جهت که سربار کمی را داشته و همچنین به سادگی توسط دومین‌های مختلفی قابل استفاده هستند.
انتقال اطلاعات: توکن‌های با فرمت JWT، روش مناسبی جهت انتقال اطلاعات امن بین مقاصد مختلف هستند؛ زیرا قابل امضاء بوده و می‌توان اطمینان حاصل کرد که فرستنده دقیقا همانی است که ادعا می‌کند و محتوای ارسالی دست نخورده‌است.


ساختار یک JWT به چه صورتی است؟

JWTها دارای سه قسمت جدا شده‌ی با نقطه هستند؛ مانند xxxxx.yyyyy.zzzzz و شامل header، payload و signature می‌باشند.
الف) Header
Header عموما دارای دو قسمت است که نوع توکن و الگوریتم مورد استفاده‌ی توسط آن را مشخص می‌کند:
 {
   "alg": "HS256",
   "typ": "JWT"
}
نوع توکن در اینجا JWT است و الگوریتم‌های مورد استفاده، عموما  HMAC SHA256 و یا RSA هستند.

ب) payload
payload یا «بار مفید» توکن، شامل claims است. منظور از claims، اطلاعاتی است در مورد موجودیت مدنظر (عموما کاربر) و یک سری متادیتای اضافی. سه نوع claim وجود دارند:
Reserved claims: یک سری اطلاعات مفید و از پیش تعیین شده‌ی غیراجباری هستند؛ مانند:
iss یا صادر کنند (issuer)، exp یا تاریخ انقضاء، sub یا عنوان (subject) و aud یا مخاطب (audience)
 Public claims: می‌تواند شامل اطلاعاتی باشد که توسط IANA JSON Web Token Registry پیشتر ثبت شده‌است و فضاهای نام آن‌ها تداخلی نداشته باشند.
Private claims: ادعای سفارشی هستند که جهت انتقال داده‌ها بین مقاصد مختلف مورد استفاده قرار می‌گیرند.
یک نمونه‌ی payload را در اینجا ملاحظه می‌کنید:
 {
   "sub": "1234567890",
   "name": "John Doe",
   "admin": true
}
این اطلاعات (هم header و هم payload)، به صورت base64 انکد شده و به JWT اضافه می‌شوند.

ج) signature
یک نمونه فرمول محاسبه‌ی امضای دیجیتال پیام JWT به صورت ذیل است:
 HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)
در اینجا بر اساس الگوریتم HMAC SHA256، هدر و بار مفید پیام به صورت base64 دریافت و به کمک یک کلید مخفی، محاسبه و به JWT اضافه می‌شود تا توسط آن بتوان اصالت پیام و فرستنده‌ی آن‌را تائید کرد. امضاء نیز در نهایت با فرمت base64 در اینجا انکد می‌شود:


یک نمونه مثال تولید این نوع توکن‌ها را در آدرس https://jwt.io می‌توانید بررسی کنید.
در این سایت اگر به قسمت دیباگر آن مراجعه کنید، برای نمونه قسمت payload آن قابل ویرایش است و تغییرات را بلافاصله در سمت چپ، به صورت انکد شده نمایش می‌دهد.


یک نکته‌ی مهم: توکن‌ها امضاء شده‌اند؛ نه رمزنگاری شده

همانطور که عنوان شد، توکن‌ها از سه قسمت هدر، بار مفید و امضاء تشکیل می‌شوند (header.payload.signature). اگر از الگوریتم HMACSHA256 و کلید مخفی shhhh برای امضای بار مفید ذیل استفاده کنیم:
 {
   "sub": "1234567890",
   "name": "Ado Kukic",
   "admin": true
}
یک چنین خروجی باید حاصل شود:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFkbyBLdWtpYyIsImFkbWluIjp0cnVlLCJpYXQiOjE0NjQyOTc4ODV9.Y47kJvnHzU9qeJIN48_bVna6O0EDFiMiQ9LpNVDFymM
در اینجا باید دقت داشت که هدر و بار مفید آن، صرفا با الگوریتم base64 انکد شده‌اند و این به معنای رمزنگاری نیست. به عبارتی می‌توان اطلاعات کامل هدر و بار مفید آن‌را به دست آورد. بنابراین هیچگاه اطلاعات حساسی را مانند کلمات عبور، در اینجا ذخیره نکنید.
البته امکان رمزنگاری توسط JSON Web Encryption نیز پیش بینی شده‌است (JWE).


از JWT در برنامه‌ها چگونه استفاده می‌شود؟

زمانیکه کاربر، لاگین موفقی را به سیستم انجام می‌دهد، یک توکن امن توسط سرور صادر شده و با فرمت JWT به سمت کلاینت ارسال می‌شود. این توکن باید به صورت محلی در سمت کاربر ذخیره شود. عموما از local storage برای ذخیره‌ی این توکن استفاده می‌شود؛ اما استفاده‌ی از کوکی‌ها نیز منعی ندارد. بنابراین دیگر در اینجا سشنی در سمت سرور به ازای هر کاربر ایجاد نمی‌شود و کوکی سمت سروری به سمت کلاینت ارسال نمی‌گردد.
سپس هر زمانیکه کاربری قصد داشت به یک صفحه یا محتوای محافظت شده دسترسی پیدا کند، باید توکن خود را به سمت سرور ارسال نماید. عموما اینکار توسط یک header سفارشی Authorization به همراه Bearer schema صورت می‌گیرد و یک چنین شکلی را دارد:
 Authorization: Bearer <token>
این روش اعتبارسنجی، بدون حالت (stateless) است؛ از این جهت که وضعیت کاربر، هیچگاه در سمت سرور ذخیره نمی‌گردد. API سمت سرور، ابتدا به دنبال هدر Authorization فوق، در درخواست دریافتی می‌گردد. اگر یافت شد و اصالت آن تائید شد، کاربر امکان دسترسی به منبع محافظت شده را پیدا می‌کند. نکته‌ی مهم اینجا است که چون این توکن‌ها «خود شمول» هستند و تمام اطلاعات لازم جهت اعطای دسترسی‌های کاربر به او، در آن وجود دارند، دیگر نیازی به رفت و برگشت به بانک اطلاعاتی، جهت تائید این اطلاعات تصدیق شده، نیست. به همین جهت کارآیی و سرعت بالاتری را نیز به همراه خواهند داشت.


نگاهی به محل ذخیره سازی JWT و نکات مرتبط با آن

محل متداول ذخیره‌ی JWT ها، در local storage مرورگرها است و در اغلب سناریوها نیز به خوبی کار می‌کند. فقط باید دقت داشت که local storage یک sandbox است و محدود به دومین جاری برنامه و از طریق برای مثال زیر دامنه‌های آن قابل دسترسی نیست. در این حالت می‌توان JWT را در کوکی‌های ایجاد شده‌ی در سمت کاربر نیز ذخیره کرد که چنین محدودیتی را ندارند. اما باید دقت داشت که حداکثر اندازه‌ی حجم کوکی‌ها 4 کیلوبایت است و با افزایش claims ذخیره شده‌ی در یک JWT و انکد شدن آن، این حجم ممکن است از 4 کیلوبایت بیشتر شود. بنابراین باید به این نکات دقت داشت.
امکان ذخیره سازی توکن‌ها در session storage مرورگرها نیز وجود دارد. session storage بسیار شبیه است به local storage اما به محض بسته شدن مرورگر، پاک می‌شود.
اگر از local storage استفاده می‌کنید، حملات Cross Site Request Forgery در اینجا دیگر مؤثر نخواهند بود. اما اگر به حالت استفاده‌ی از کوکی‌ها برای ذخیره‌ی توکن‌ها سوئیچ کنید، این مساله همانند قبل خواهد بود و مسیر است. در این حالت بهتر است طول عمر توکن‌ها را تاحد ممکن کوتاه تعریف کنید تا اگر اطلاعات آن‌ها فاش شد، به زودی بی‌مصرف شوند.


انقضاء و صدور مجدد توکن‌ها به چه صورتی است؟

توکن‌های بدون حالت، صرفا بر اساس بررسی امضای پیام رسیده کار می‌کنند. به این معنا که یک توکن می‌تواند تا ابد معتبر باقی بماند. برای رفع این مشکل باید exp یا تاریخ انقضای متناسبی را به توکن اضافه کرد. برای برنامه‌های حساس این عدد می‌تواند 15 دقیقه باشد و برای برنامه‌های کمتر حساس، چندین ماه.
اما اگر در این بین قرار به ابطال سریع توکنی بود چه باید کرد؟ (مثلا کاربری را در همین لحظه غیرفعال کرده‌اید)
یک راه حل آن، ثبت رکورد‌های تمام توکن‌های صادر شده در بانک اطلاعاتی است. برای این منظور می‌توان یک فیلد id مانند را به توکن اضافه کرد و آن‌را صادر نمود. این idها را نیز در بانک اطلاعاتی ذخیره می‌کنیم. به این ترتیب می‌توان بین توکن‌های صادر شده و کاربران و اطلاعات به روز آن‌ها ارتباط برقرار کرد. در این حالت برنامه علاوه بر بررسی امضای توکن، می‌تواند به لیست idهای صادر شده و ذخیره شده‌ی در دیتابیس نیز مراجعه کرده و اعتبارسنجی اضافه‌تری را جهت باطل کردن سریع توکن‌ها انجام دهد. هرچند این روش دیگر آنچنان stateless نیست، اما با دنیای واقعی سازگاری بیشتری دارد.


حداکثر امنیت JWTها را چگونه می‌توان تامین کرد؟

- تمام توکن‌های خود را با یک کلید قوی، امضاء کنید و این کلید تنها باید بر روی سرور ذخیره شده باشد. هر زمانیکه سرور توکنی را از کاربر دریافت می‌کند، این سرور است که باید کار بررسی اعتبار امضای پیام رسیده را بر اساس کلید قوی خود انجام دهد.
- اگر اطلاعات حساسی را در توکن‌ها قرار می‌دهید، باید از JWE یا JSON Web Encryption استفاده کنید؛ زیرا JWTها صرفا دارای امضای دیجیتال هستند و نه اینکه رمزنگاری شده باشند.
- بهتر است توکن‌ها را از طریق ارتباطات غیر HTTPS، ارسال نکرد.
- اگر از کوکی‌ها برای ذخیره سازی آن‌ها استفاده می‌کنید، از HTTPS-only cookies استفاده کنید تا از Cross-Site Scripting XSS attacks در امان باشید.
- مدت اعتبار توکن‌های صادر شده را منطقی انتخاب کنید.
نظرات مطالب
ModelBinder سفارشی در ASP.NET MVC
سلام؛ با تشکر از مقاله شما.
میخواستم بپرسم override کردن BindModel یا BindProperty برای زمانییه که ما به تمام دیتا هامون دسترسی داریم حالا شکل برگرداندنمون فرق میکنه؟
اگر اینطوره سوالم اینه که برای حالتی که مدل ما به شکل زیر هست چگونه Items را Bind کنم چون از هر روشی میرم null هست!
public class Model 
{
  public Model()
  {
     Items = new List<ItemModel>();
  }
 public Guid Id { get; set; }
 public Guid ProductId { get; set; }
  public List<ItemModel> Items { get; set; }
}

public class ItemModel
{
        Public Guid Id
        public string  Title{ get; set; }
        public int Value { get; set; }
}
و من در view مدل زیر را احتیاج دارم.
@model  List<Model>
در اکشن  HttpPost مربوط به این مدل ItemsProperty Is Null.
نظرات مطالب
React 16x - قسمت 28 - احراز هویت و اعتبارسنجی کاربران - بخش 3 - فراخوانی منابع محافظت شده و مخفی کردن عناصر صفحه
- اگر احتمالا پروژه‌ی پیوست را اجرا کرده باشید، مشاهده کردید که پس از لاگین، یک refresh کامل صورت می‌گیرد و مشکل خاصی از این لحاظ وجود ندارد (چندین بار هم آزمایش شد).
- در پروژه‌ی سفارشی و خاص خودتان نیاز است هدرهای ارسالی به سمت سرور را در برگه‌ی network ابزارهای توسعه دهندگان مرورگر، بررسی کنید. محتوای آن را همانند روشی که در نکته‌ی «نگاهی به محتوای JSON Web Token تولیدی » عنوان شد، دقیقا بررسی کنید که آیا به همراه claims مدنظر شما هست یا خیر؟ سمت سرور فقط بر اساس این محتوا هست که سشنی را ایجاد می‌کند. اگر این محتوا ناقص باشد، اطلاعات مدنظر هم قابل استخراج نخواهند بود. همچنین آیا سمت سرور عملیات اعتبارسنجی ثانویه‌ای هم صورت می‌گیرد و آیا ساختار JWT ارسالی، اطلاعات مدنظر آن‌را تامین می‌کند یا خیر. این‌ها را باید مرحله به مرحله دیباگ کنید.
- همچنین طول عمرهای توکن‌های تولیدی را هم باید مدنظر داشته باشید. در مثال جاری، این عدد در فایل appsettings.json به 20 دقیقه تنظیم شده:
  "BearerTokens": {
    "Key": "This is my shared key, not so secret, secret!",
    "Issuer": "https://localhost:5001/",
    "Audience": "Any",
    "AccessTokenExpirationMinutes": 20
  }
در مثالی دیگر به 2 دقیقه که خیلی کوتاه است.
نظرات مطالب
سفارشی سازی ASP.NET Core Identity - قسمت سوم - نرمال سازها و اعتبارسنج‌ها
ارتقاء به ASP.NET Core Identity 3.0

امضای اینترفیس ILookupNormalizer، از حالت کلی زیر، که هم ایمیل و هم نام را شامل می‌شد:
    public interface ILookupNormalizer
    {
        string Normalize(string key);
    }
به حالت اختصاصی‌تر زیر تغییر کرده‌است:
    public interface ILookupNormalizer
    {
        string NormalizeEmail(string email);
        string NormalizeName(string name);
    }
نظرات مطالب
ASP.NET MVC #18
- مقاله عنوان کرده اگر کار شما سورس باز است ترکیب فایده‌ای نداره چون مشخص است چکار کردید. (البته این رو برای ساده‌تر کردن کار خودش عنوان کرده!)
- key stretching یا هر روش دیگری، بحث و هدف اصلی من طرح یک نکته بود: از الگوریتم‌های هش عمومی مستقیما استفاده نکنید. روش پیچ و تاب آن باشد بر اساس روشی که انتخاب می‌کنید.
- من از روش ترکیبی استفاده می‌کنم. حتما هم استفاده می‌کنم. چون دقیقا می‌دونم اون کسانیکه این هش‌ها رو زمانیکه از دیتابیس شما بیرون کشیدند، چه ابزارهایی در اختیار دارند.
- حتی زمانیکه کار شما سورس باز است نیز از روش ترکیبی استفاده کنید. پردازش‌های موازی سنگین و استفاده از GPU برای الگوریتم‌های معمولی و متداول تهیه شده. حتی بانک‌های اطلاعاتی بزرگی که برای نگهداری هش‌های آماده تهیه شدن برمبنای هش‌های عمومی هستند. گیرم حتی اگر کار شما سورس باز باشد، تبدیل الگوریتم‌های ترکیبی آن به الگوریتم‌های بهینه قابل اجرای بر روی GPU کار هرکسی نیست.


استفاده مستقیم از الگور‌یتم‌های هش‌های متداول در یک پروژه عمومی با تعداد کاربر بالا = عین حماقت
نظرات مطالب
مدیریت دانلود‌های همزمان از یک سایت و بحث تایم آوت
در این مورد خیر.
اگر سرور یا حتی برنامه برای این نوع حملات آماده نشده باشند، بله. این روش‌ها می‌تونه عملیات سایت رو مختل کنه. البته هدف من فقط دریافت فید از یک سایت مادر بود :)
مطلبی رو چند وقت پیش در سایت آقای Omar AL Zabir دیدم که در همین ارتباط بود. نحوه ایجاد این نوع حملات و نحوه دفاع توسط یک برنامه هوشمند که برای این موارد آماده شده:
مشاهده مطلب:
http://msmvps.com/blogs/omar/archive/2007/03/24/prevent-denial-of-service-dos-attacks-in-your-web-application.aspx
مثالی هم که در سایت ایشون برای حمله عنوان شده عملا با پیش فرض‌های دات نت (حداکثر 2 کانکشن همزمان) کار خاصی رو انجام نمیده و نهایتا timeout خواهند گرفت، مگر اینکه ...