如何增强我的会员网站的安全性 - 被黑客入侵

时间:2014-02-04 02:37:09

标签: asp.net sql-server vb.net security firebug

我有一个会员网站,会员可以使用预付卡添加信用卡。添加信用页面只包含一个文本字段,使成员可以输入卡号,然后我将CardNumber参数传递给函数以验证卡,并通过MS SQL 2008数据库上的存储过程充值成员帐户。

几天前,一名攻击者成功使用该卡为其帐户添加了信用额,而未更改卡的使用状态和UserId。他能够多次使用同一张卡来增加信用额度。

我想知道他是否使用Firebug或Fiddler软件,但我知道它不会影响存储过程代码。

以下是我的存储过程代码:

ALTER procedure [dbo].[UseCard]
(@CardNumber varchar(10), @Used bit, @UserId bigint)
as
if (@CardNumber NOT in (SELECT CardNumber FROM CardsList)) and 
    RAISERROR('Card not found',16,1)
else if (@Used in (select Used from CardsList WHERE CardNumber = @CardNumber))
    RAISERROR('Card used before',16,1)
else
begin
    Update CardsList
    set Used = 1, UserId = @UserId
    where (CardNumber = @CardNumber)

    UPDATE [Users]
    SET UserBalance = UserBalance + (select Amount from CardsList where CardNumber = @CardNumber)
    WHERE (ID = @UserId)
end

我的功能是

Public Sub UpdateCard(ByVal CardNumber As String, ByVal Used As Boolean)
        Dim Command As New SqlClient.SqlCommand
        With Command
            .CommandText = "UseCard"
            .CommandType = CommandType.StoredProcedure

            .Parameters.AddWithValue("@CardNumber", CardNumber)
.Parameters.AddWithValue("@Used", Used)
            .Parameters.AddWithValue("@UserId", UserId)

        End With

        DBProvider.ExecuteNonQuery(Command)

    End Sub

我的HTML代码是:

<h3>Account TopUp</h3>

<telerik:RadAjaxLoadingPanel ID="RadAjaxLoadingPanel1" runat="server" 
    Skin="Web20">
</telerik:RadAjaxLoadingPanel>

<telerik:RadAjaxPanel ID="RadAjaxPanel1" runat="server" Height="200px" 
    Width="300px" HorizontalAlign="NotSet" LoadingPanelID="RadAjaxLoadingPanel1">

<asp:Label ID="lbresult" runat="server"></asp:Label>
    <label for="your_name">Card Number</label><br/>
        <asp:TextBox ID="txtCardNumber" runat="server" Width="200px"></asp:TextBox>
        <asp:RegularExpressionValidator Text=" * " ID="RegularExpressionValidator1" runat="server" ValidationExpression="[a-zA-Z0-9]{8}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{2}"
                            ControlToValidate="txtCardNumber" />
        <asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" 
                    ControlToValidate="txtCardNumber" ErrorMessage="*" 
                    Font-Bold="True"></asp:RequiredFieldValidator>
        <asp:Button ID="btnAddCredits" runat="server" Text="ADD" />
</telerik:RadAjaxPanel>

2 个答案:

答案 0 :(得分:1)

如果我为存储过程的@Used参数传入0,我可以一遍又一遍地重复使用同一张卡。

我会从那里开始 - 如果@Used参数暴露给网络,那么你就有一个SQL注入漏洞。

答案 1 :(得分:1)

您应确保您的SP在交易中,否则检查该卡是否已被使用的查询可以在更新之前由两个单独的线程执行。

这将保护您UserBalance的更新,因此每张卡只能更新一次,如果在CardsList更新后但在UserBalance更新之前有任何失败,则会更新,回滚。

e.g。想象使用相同卡的以下事件序列

Request 1                            Request 2
Check card 123 has not been used
Card has not been used 
                                     Check card 123 has not been used
                                     Card has not been used 
Update card to mark as used
                                     Update card to mark as used
Update balance
                                     Update balance

正如您所看到的,根据并发请求发生的事件顺序,同一张卡可能会多次发生更新。

事务将锁定数据库表,直到提交事务为止,因此事件序列现在为:

Request 1                            Request 2
BEGIN TRANSACTION                   
Check card 123 has not been used
Card has not been used 
                                     BEGIN TRANSACTION
                                     Check card 123 has not been used  - SQL
                                         Server will
                                         suspend (pause) this thread as this 
                                         record
                                         has been
                                         locked by the other thread

Update card to mark as used

Update balance
COMMIT TRANSACTION                   Thread resumed
                                     Check card 123 has not been used - 
                                         it has so
                                         RAISERROR
                                     TRANSACTION aborted (rolled back, but as no
                                         changes were made it is simply marked as
                                         complete)

同样Used也不应该是参数,只是SP中的变量。

    ALTER procedure [dbo].[UseCard]



(@CardNumber varchar (10) , @UserId bigint)

AS

DECLARE @Used bit;


SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;

if (@CardNumber NOT in (SELECT CardNumber FROM CardsList)) and 
    RAISERROR('Card not found',16,1)

    else if (@Used in (select Used from CardsList WHERE CardNumber = @CardNumber))

    RAISERROR('Card used before',16,1)
    else

begin
Update CardsList

set

Used = 1 ,UserId = @UserId
where (CardNumber = @CardNumber)

UPDATE    [Users]
    SET
UserBalance = UserBalance + (select Amount from CardsList where CardNumber = @CardNumber)

    WHERE     (ID = @UserId)
end
COMMIT TRANSACTION;
相关问题