萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 網路程式設計 >> ASP 程式設計

ASP 刪除記錄與資料庫連線程式碼解析

解析經典 ASP 刪除多筆記錄與資料庫連線的常見程式碼片段,說明各行用途、潛在風險 (SQL Injection) 與現代化改寫建議。

片段一:批次刪除記錄 (delete.asp)

<%@ Language=VBScript %><%
Option Explicit

'--- 1. 開啟資料庫連線 (假設在共用 include 檔中定義) ---
Call OpenDataConn()

'--- 2. 接收參數 ---
Dim xxlb, id, ids, i, tt
xxlb = RtnReplaceInt(Trim(Request("xxlb")), 0)  ' 自訂函數:整數驗證+預設值
id   = ChangeChr(Request("id"))                 ' 自訂函數:字元過濾/轉義

'--- 3. 分割 ID 字串 (格式: "1,2,3") ---
ids = Split(id, ",")

'--- 4. 迴圈刪除 ---
For i = 0 To UBound(ids)
    tt = Trim(ids(i))
    ' ⚠️ 風險:直接拼接 SQL,若 tt 含惡意代碼將導致 SQL Injection
    conn.Execute "DELETE FROM house WHERE id = " & tt
Next

'--- 5. 導回列表頁 ---
Response.Redirect "house.asp?xxlb=" & xxlb

'--- 6. 關閉連線 ---
Call CloseDataConn()
%>

片段二:資料庫連線共用模組 (conn.asp)

<%@ Language=VBScript %><%
Option Explicit

Dim conn
Dim char_str(20)  ' 未使用的陣列,可移除

Sub OpenDataConn()
    Dim connStr
    ' Access Jet OLEDB 4.0 連線字串,使用 Server.MapPath 取得實體路徑
    connStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & _
              Server.MapPath("../../data/fyhouse_free.mdb")
    
    Set conn = Server.CreateObject("ADODB.Connection")
    conn.Open connStr
End Sub

Sub CloseDataConn()
    If IsObject(conn) Then
        If conn.State = 1 Then conn.Close  ' adStateOpen = 1
        Set conn = Nothing
    End If
End Sub
%>

關鍵風險點分析

風險程式碼位置攻擊向量後果
SQL Injection`conn.Execute "DELETE ... WHERE id = " & tt``id=1; DROP TABLE house;--`資料表被刪除、資料外洩、權限提升
IDOR (不安全直接物件引用)無權檢查直接刪除橫向越權刪除他人資料資料完整性破壞
CSRF無 Token 驗證誘導管理員點擊惡意連結非預期刪除操作
連線物件全域變數`Dim conn` 在全域併發請求共用同一 Connection 物件「Operation is not allowed when the object is closed」錯誤、資料交叉
錯誤處理缺失無 `On Error Resume Next` / `Err.Number` 檢查資料庫鎖定、連線失敗時顯示詳細錯誤資訊資訊洩露、使用者體驗差

安全重構版 (參數化查詢 + 權限檢查 + 交易)

<%@ Language=VBScript %><%
Option Explicit
Response.Buffer = True

Dim conn, cmd, ids, i, tt, xxlb, userId, isAdmin

'--- 驗證登入與權限 ---
If Session("UserID") = "" Then Response.Redirect "login.asp"
userId = CLng(Session("UserID"))
isAdmin = (Session("Role") = "admin")

'--- 參數處理 ---
xxlb = CLng(Request("xxlb"))  ' 強制轉數字,非數字變 0
id = Request("id")
If id = "" Then Response.Redirect "house.asp?xxlb=" & xxlb

ids = Split(id, ",")

'--- 開啟連線 (區域變數,避免併發衝突) ---
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Server.MapPath("../../data/fyhouse_free.mdb")

On Error Resume Next
conn.BeginTrans

Set cmd = Server.CreateObject("ADODB.Command")
cmd.ActiveConnection = conn
cmd.CommandText = "DELETE FROM house WHERE id = ? AND (owner_id = ? OR ? = True)"
cmd.CommandType = 1 ' adCmdText
' 參數:@id, @owner_id, @is_admin
cmd.Parameters.Append cmd.CreateParameter("@id", 3, 1, 4)      ' adInteger
cmd.Parameters.Append cmd.CreateParameter("@owner_id", 3, 1, 4)
cmd.Parameters.Append cmd.CreateParameter("@is_admin", 11, 1, 1) ' adBoolean

For i = 0 To UBound(ids)
    tt = Trim(ids(i))
    If IsNumeric(tt) Then
        cmd.Parameters("@id").Value = CLng(tt)
        cmd.Parameters("@owner_id").Value = userId
        cmd.Parameters("@is_admin").Value = isAdmin
        cmd.Execute
        If Err.Number <> 0 Then Exit For
    End If
Next

If Err.Number = 0 Then
    conn.CommitTrans
    Response.Redirect "house.asp?xxlb=" & xxlb & "&msg=deleted"
Else
    conn.RollbackTrans
    Response.Write "刪除失敗: " & Err.Description
End If

Set cmd = Nothing
conn.Close: Set conn = Nothing
%>

現代化遷移對照

ASP 3.0ASP.NET Core / EF Core
`conn.Execute "DELETE ..."``await db.Houses.Where(h => ids.Contains(h.Id) && (h.OwnerId == userId || isAdmin)).ExecuteDeleteAsync();`
`Server.MapPath``IWebHostEnvironment.ContentRootPath` + `Path.Combine`
`Session("UserID")``User.FindFirst(ClaimTypes.NameIdentifier).Value`
`Response.Redirect``return RedirectToAction("Index", new { xxlb });`
核心原則:
1. **永不拼接 SQL** — 全站強制參數化查詢 (`Command.Parameters`)
2. **連線物件區域化** — 每個請求建立/關閉自己的連線,勿用全域變數
3. **授權檢查前置** — 刪除前驗證擁有權或管理員身分
4. **交易包裹批次操作** — 全成功或全失敗,保持資料一致性
5. **錯誤不外洩** — 生產環境關閉詳細錯誤,記錄 Log 供開發者追查
copyright © 萬盛學電腦網 all rights reserved