Nhibenate - DOS Attack - PullRequest
       1

Nhibenate - DOS Attack

0 голосов
/ 05 октября 2011

Один из тестеров в моей компании обнаружил ошибку в моем решении ASP.Net MVC 3, которая, как мне кажется, встречается довольно часто.

Один пост на сервере, который он может обработать. Но если вы отправляете много сообщений, например, атака типа «отказ в обслуживании» (DoS атака) , возникает исключение:

Server Error in '/' Application.
Initializing[UseSoft.ProdMaster.Domain.Entities.CustomerOrderHeader#567]-failed to lazily initialize a collection of role: UseSoft.ProdMaster.Domain.Entities.CustomerOrderHeader.CustomerOrderLines, no session or session was closed
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: NHibernate.LazyInitializationException: Initializing[UseSoft.ProdMaster.Domain.Entities.CustomerOrderHeader#567]-failed to lazily initialize a collection of role: UseSoft.ProdMaster.Domain.Entities.CustomerOrderHeader.CustomerOrderLines, no session or session was closed

Source Error:

Line 880:
Line 881:
Line 882:            return
Line 883:                Json(
Line 884:                    new


Source File: C:\Projects\DavidPM\Hosts\ProdMaster.Hosts.Web\Areas\Sales\Controllers\CustomerOrderController.cs    Line: 882

Stack Trace:

[LazyInitializationException: Initializing[UseSoft.ProdMaster.Domain.Entities.CustomerOrderHeader#567]-failed to lazily initialize a collection of role: UseSoft.ProdMaster.Domain.Entities.CustomerOrderHeader.CustomerOrderLines, no session or session was closed]
   NHibernate.Collection.AbstractPersistentCollection.ThrowLazyInitializationException(String message) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Collection\AbstractPersistentCollection.cs:484
   NHibernate.Collection.AbstractPersistentCollection.ThrowLazyInitializationExceptionIfNotConnected() in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Collection\AbstractPersistentCollection.cs:474
   NHibernate.Collection.AbstractPersistentCollection.Initialize(Boolean writing) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Collection\AbstractPersistentCollection.cs:465
   NHibernate.Collection.AbstractPersistentCollection.Read() in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Collection\AbstractPersistentCollection.cs:264
   NHibernate.Collection.Generic.PersistentGenericBag`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Collection\Generic\PersistentGenericBag.cs:142
   System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +63
   System.Linq.Buffer`1..ctor(IEnumerable`1 source) +217
   System.Linq.Enumerable.ToArray(IEnumerable`1 source) +78
   UseSoft.ProdMaster.Hosts.Web.Areas.Sales.Controllers.CustomerOrderController.SaveOrUpdateOrderLines(CustomerOrderModel customerOrderModel) in C:\Projects\DavidPM\Hosts\ProdMaster.Hosts.Web\Areas\Sales\Controllers\CustomerOrderController.cs:882
   lambda_method(Closure , ControllerBase , Object[] ) +162
   System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +17
   System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +208
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +27
   System.Web.Mvc.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12() +55
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +263
   System.Web.Mvc.<>c__DisplayClass17.<InvokeActionMethodWithFilters>b__14() +19
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +191
   System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +343
   System.Web.Mvc.Controller.ExecuteCore() +116
   System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +97
   System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +10
   System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +37
   System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +21
   System.Web.Mvc.Async.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) +12
   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62
   System.Web.Mvc.<>c__DisplayClasse.<EndProcessRequest>b__d() +50
   System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7
   System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22
   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +60
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8862381
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184

Описано ниже:

Нажмите на кнопку много раз. Или нажмите один раз и нажмите Enter, он отправит много запросов на сервер «Пост».

Модель в основном:

public class CustomerOrderModel
{
    public CustomerOrderModel()
    {
        this.CustomerOrderLines = new List<CustomerOrderLineModel>();
        this.CustomerOrderHeader = new CustomerOrderHeaderModel();
    }

    public CustomerOrderHeaderModel CustomerOrderHeader
    { get; set; }

    public List<CustomerOrderLineModel> CustomerOrderLines
    { get; set; }

}

Контроллер:

[HttpPost]
        public JsonResult SaveOrUpdateOrderLines(  CustomerOrderModel customerOrderModel)
        {

  if (customerOrderModel.CustomerOrderHeader.OrderNumber == 0)
             {
                 customerOrderModel.CustomerOrderHeader.OrderNumber = this.CustomerOrderService.CreateOrUpdate(customerOrderHeader, false);
             }

возврат Json ( новый { OrderNumber = customerOrderModel.CustomerOrderHeader.OrderNumber, CustomerOrderLines = новый { CustomerOrderLine = ( от ordeline в custOrderHeader.CustomerOrderLines выберите новый { Id = ordeline.Id, LineNumber = ordeline.LineNumber, LineStatus = ordeline.LineStatus }

                            ).ToArray()

                        }
                }, 
                JsonRequestBehavior.AllowGet
            );

}

Служба CustomerOrder:

 public class CustomerOrderService : ServiceBase, ICustomerOrderService
    {

 public long CreateOrUpdate(CustomerOrderHeader customerOrderHeader, bool updateCustomerOrderHeader)
        {
            using (var session = this.SessionManager.OpenSession())
            {
                var transaction = session.BeginTransaction();

                try
                {
                    //TODO: CHECKS IF PARTNER EXISTS
                    bool existsPartner = false;
                    long number = 0;
                    if (this.PartnerService.FindByName(customerOrderHeader.Partner.Name) != null)
                    {
                        existsPartner = true;
                    }

                    //CREATE PARTNER AND PARTNER ADDRESSES
                    if (!existsPartner)
                    {
                        this.PartnerService.Create(customerOrderHeader.Partner as Partner);
                    }



                    if (!updateCustomerOrderHeader)
                    {
                        number = this.CustomerOrderHeaderService.Create(customerOrderHeader, true);
                    }
                    else
                    {
                        this.CustomerOrderHeaderService.Create(customerOrderHeader, false);
                    }
                    transaction.Commit();
                    return number;


                }

                catch (Exception ex)
                {

                    transaction.Rollback();
                    throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }



        /// <summary>
        /// Initializes a new instance of the <see cref="CustomerOrderService"/> class.
        /// </summary>
        /// <param name="sessionManager">
        /// The session manager.
        /// </param>
        public CustomerOrderService(ISessionManager sessionManager)
        {
            this.SessionManager = sessionManager;
        }
}

Служба CustomerOrderHeaderService:

public long Create(CustomerOrderHeader customerOrderHeader, bool firstTime)
        {


            using (var session = this.SessionManager.OpenSession())
            {
            //    var transaction = session.BeginTransaction();

            //    try
            //    {




                    if (firstTime)
                    {
                        foreach (var customerOrderLine in customerOrderHeader.CustomerOrderLines)
                        {
                            customerOrderLine.CustomerOrderHeader = customerOrderHeader;
                        }

                        customerOrderHeader.OrderNumber = this.NextOrderNumber();
                        session.Save(customerOrderHeader);
                    }
                    else
                    {

                        CustomerOrderHeader customerOrderHeaderToBeChanged =
                            this.FindByOrderNumber(customerOrderHeader.OrderNumber);

                        customerOrderHeaderToBeChanged.CopyDomainProperties(
                            customerOrderHeader, new[]
                                                     {
                                                         "Id", 
                                                         "Partner", 
                                                         "DataOwner", 
                                                         "dataOwner", 
                                                         "SysCreatedOn",
                                                         "SysCreatedBy",
                                                         "CustomerOrderLines"
                                                     });
                        customerOrderHeaderToBeChanged = UpdateLines(customerOrderHeader, customerOrderHeaderToBeChanged);
                        List<ICustomerOrderLine> linestoBeInserted = GetTheLineNumbersToBeInserted(customerOrderHeader);

                        foreach (var customerOrderLine in linestoBeInserted)
                        {
                            customerOrderHeaderToBeChanged.CustomerOrderLines.Add(customerOrderLine);
                            customerOrderLine.CustomerOrderHeader = customerOrderHeaderToBeChanged;
                        }

                        session.Update(customerOrderHeaderToBeChanged);
                    }

            //        transaction.Commit();
            }
            //    catch (Exception ex)
            //    {
            //        transaction.Rollback();
            //        throw ex;
            //    }
            //    finally
            //    {
            //        session.Close();
            //    }
            //}
            //throw new System.ArgumentException();

            return customerOrderHeader.OrderNumber;
        }


public class CustomerOrderHeaderService : ServiceBase, ICustomerOrderHeaderService
    {
        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="CustomerOrderHeaderService"/> class.
        /// </summary>
        /// <param name="sessionManager">
        /// The session manager.
        /// </param>
        public CustomerOrderHeaderService(ISessionManager sessionManager)
        {
            this.SessionManager = sessionManager;
        }

        #endregion

 public long Create(CustomerOrderHeader customerOrderHeader, bool firstTime)
        {


            using (var session = this.SessionManager.OpenSession())
            {
            //    var transaction = session.BeginTransaction();

            //    try
            //    {




                    if (firstTime)
                    {
                        foreach (var customerOrderLine in customerOrderHeader.CustomerOrderLines)
                        {
                            customerOrderLine.CustomerOrderHeader = customerOrderHeader;
                        }

                        customerOrderHeader.OrderNumber = this.NextOrderNumber();
                        session.Save(customerOrderHeader);
                    }
                    else
                    {

                        CustomerOrderHeader customerOrderHeaderToBeChanged =
                            this.FindByOrderNumber(customerOrderHeader.OrderNumber);

                        customerOrderHeaderToBeChanged.CopyDomainProperties(
                            customerOrderHeader, new[]
                                                     {
                                                         "Id", 
                                                         "Partner", 
                                                         "DataOwner", 
                                                         "dataOwner", 
                                                         "SysCreatedOn",
                                                         "SysCreatedBy",
                                                         "CustomerOrderLines"
                                                     });
                        customerOrderHeaderToBeChanged = UpdateLines(customerOrderHeader, customerOrderHeaderToBeChanged);
                        List<ICustomerOrderLine> linestoBeInserted = GetTheLineNumbersToBeInserted(customerOrderHeader);

                        foreach (var customerOrderLine in linestoBeInserted)
                        {
                            customerOrderHeaderToBeChanged.CustomerOrderLines.Add(customerOrderLine);
                            customerOrderLine.CustomerOrderHeader = customerOrderHeaderToBeChanged;
                        }

                        session.Update(customerOrderHeaderToBeChanged);
                    }

            //        transaction.Commit();
            }
            //    catch (Exception ex)
            //    {
            //        transaction.Rollback();
            //        throw ex;
            //    }
            //    finally
            //    {
            //        session.Close();
            //    }
            //}
            //throw new System.ArgumentException();

            return customerOrderHeader.OrderNumber;
        }
}

Ответы [ 2 ]

1 голос
/ 05 октября 2011

Увеличение лимитов пула соединений может помочь продлить его в этом случае, если вы не насыщаете сервер / сеть слишком большим количеством.

Открывайте и закрывайте соединения с базой данных как можно позже и раньше (соответственно). Возможно, вы захотите переключить сеанс открытия / закрытия с каждого запроса (или того, что вы используете) на использование.

В вашем случае, поскольку это кнопка на интерфейсе, вы можете временно отключить ее (с помощью JavaScript) на некоторое время, чтобы пользователь не мог продолжать нажимать на нее быстрее, чем это когда-либо требовалось.

В любом случае, вы должны ограничить количество входящих запросов на уровне сети или IIS.

0 голосов
/ 01 января 2012

Убедитесь, что вы не делитесь объектами в нескольких сеансах NHibernate.

Эта ошибка может произойти, если Сессия # 1 загружает объект, который Сессия # 2 пытается зафиксировать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...