You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

我的CMS代码是否存在SQL注入漏洞?求安全检测

你的CMS代码SQL注入风险分析&优化建议

嘿,咱们来仔细拆解下你这段代码的情况:首先得给你吃个定心丸——你已经用了预处理语句(prepare + bind_param),这是防范SQL注入的黄金方案,核心的插入逻辑是安全的,不会存在SQL注入漏洞。不过代码里藏着不少小问题,可能导致数据异常或者逻辑出错,下面给你逐一梳理:

一、代码里的主要问题

  • 变量覆盖的低级错误:你处理$distrct(用户提交的地区字段)之后,居然把$division的处理结果又赋值给了$distrct!这直接导致用户提交的地区数据被覆盖,最后插入数据库的其实是分区(division)的值,完全不符合你的需求:
    $distrct = $_POST['distrct'];
    $distrct = strip_tags($distrct);
    $distrct = htmlentities($distrct);
    $distrct = mysqli_real_escape_string($con, $distrct);
    // 下面这三行全错了!应该给$division赋值,不是覆盖$distrct
    $division = $_POST['division'];
    $distrct = strip_tags($division); 
    $distrct = htmlentities($division);
    $distrct = mysqli_real_escape_string($con, $division);
    
  • 多余的转义/过滤操作:既然用了预处理语句,bind_param会自动帮你处理参数的转义,根本不需要额外调用strip_tagshtmlentitiesmysqli_real_escape_string。尤其是htmlentities会把<>这类特殊字符转成HTML实体,存进数据库后,要是取出来不转回来,显示的就是&lt;这种奇怪的字符,严重影响内容正常展示。
  • 主键处理不够合理:如果couts表的id是自增主键,你完全不需要手动传NULL,直接在INSERT语句里删掉id列就行,数据库会自动帮你生成主键值:
    INSERT INTO couts (name, distrct, division) VALUES(?,?,?)
    
    另外你绑定参数用的是'ssss'(四个字符串类型),但$id是NULL,虽然MySQL可能会自动转换,但严谨点的话,不需要传的字段就别放进SQL语句里。
  • 字符集设置的语法错误:你设置SESSION排序规则的语句写错了:
    mysqli_query($con, "SET SESSION collation collation='utf8_general_ci'");
    
    正确的写法应该是这样:
    // 更简洁的方式设置字符集和排序规则
    mysqli_set_charset($con, 'utf8');
    // 或者单独设置排序规则
    mysqli_query($con, "SET SESSION collation_connection = 'utf8_general_ci'");
    
  • 完全没做错误处理:代码里没有检查preparebind_paramexecute是否成功,要是数据库连接失败、SQL语句写错,直接就会抛出错误,既不友好也不利于排查问题。

二、优化后的安全代码示例

if(isset($_POST['cout'])){
    $servername = "localhost";
    $username = "root";
    $password = "";
    $db = "bangla";

    // 创建连接并检查连接状态
    $con = new mysqli($servername, $username, $password, $db);
    if ($con->connect_error) {
        die("数据库连接失败: " . $con->connect_error);
    }
    // 设置字符集(推荐用这种简洁方式)
    mysqli_set_charset($con, 'utf8');

    // 获取用户输入,用??语法避免未定义索引错误
    $name = $_POST['name'] ?? '';
    $distrct = $_POST['distrct'] ?? '';
    $division = $_POST['division'] ?? '';

    // 预处理SQL语句(省略自增主键id)
    $stmt = $con->prepare("INSERT INTO couts (name, distrct, division) VALUES(?,?,?)");
    if (!$stmt) {
        die("预处理SQL失败: " . $con->error);
    }

    // 绑定参数:s代表字符串类型,如果字段是整数可以用i,根据实际表结构调整
    $stmt->bind_param('sss', $name, $distrct, $division);
    if (!$stmt->execute()) {
        die("执行插入失败: " . $stmt->error);
    }

    echo "新记录创建成功";

    // 记得关闭语句和连接,养成好习惯
    $stmt->close();
    $con->close();
}

三、防范SQL注入的核心要点

  • 死磕预处理语句:这是目前最可靠的防注入手段,绝对不要把用户输入直接拼进SQL语句里,哪怕你觉得转义过也不行。
  • 别依赖转义函数mysqli_real_escape_string这类函数只能应付简单场景,稍微复杂一点的输入就可能出问题,预处理才是王道。
  • 一定要做输入验证:虽然预处理能防注入,但还是要对用户输入做合法性检查(比如检查长度、格式是否符合要求),别什么脏数据都往数据库里塞。
  • 数据库权限最小化:连接数据库的用户只给必要的权限(比如INSERT、SELECT),别用root这种超级权限用户,就算真出了漏洞,也能把危害降到最低。

内容的提问来源于stack exchange,提问作者Shamol Singha Extr

火山引擎 最新活动