Oracle 选择查询是 C# 中的无效数字

Posted

技术标签:

【中文标题】Oracle 选择查询是 C# 中的无效数字【英文标题】:Oracle select query is invalid number in C# 【发布时间】:2020-10-28 13:59:11 【问题描述】:

我有一个用于登录的代码。 我用一种方法调用从文本框中获得的数据,并在 数据库。

当我按下按钮时,我会调用相关方法。

 private void btnGiris_Click(object sender, EventArgs e)
        
            LoginBilgiler lb = new LoginBilgiler();
            bool sonuc = lb.GirisKontrol(txtAd.Text, txtSifre.Text);
        

但我在下面的 cmd.ExecuteReader 中遇到错误。

    public bool GirisKontrol(string ad,string sifre)
    
        using (OracleConnection con = new OracleConnection(connectionString))
        


            string query = String.Format("SELECT count(*) from Z_LABEL_USER where USERNAME=(0) and PASSWORD=(1)", ad,sifre);
            OracleCommand cmd = new OracleCommand(query, con);
            con.Open();
            OracleDataReader dr = cmd.ExecuteReader();
          
            if (dr.HasRows)
            
                kAdi = ad;
                con.Close();
                return true;
            
            else
                con.Close();
                return false;
        
    

我用于选择查询的表。

Oracle.ManagedDataAccess.Client.OracleException: 'ORA-01722: 无效 号码'

【问题讨论】:

不要这样构造 SQL 字符串。这就是 SQL 注入攻击的发生方式。但是,在这种情况下,您可能最终得到了查询中的原始文本。 ADO.NET 允许您使用参数化查询而不是字符串连接。 你不应该存储明文密码,也不应该像这样测试有效性。尽管COUNT(*) 返回了所有记录,但有人可以轻松'moo') OR 1=1 // 作为用户名或密码并登录。不过,您无需编写自己的密码存储代码。 .NET 一直到 .NET 1.0,首先通过成员资格提供程序提供安全密码存储,现在通过身份和身份服务器提供安全的密码存储 代码甚至无法打开 SQL 注入 - 这本身就是一个缺陷,因为COUNT(*) 总是返回一行,所以dr.HasRows总是为真,无论是否您是否提供了错误的密码! @Hakanözel 加密也好不到哪里去。密码还在。这就是为什么十多年来它是哈希密码的标准指南。总是有人会在您的数据库中存储一个常见的泄露密码。使用 GPU,人们可以简单地尝试多个主密码组合,直到找到与其中一个常用密码匹配的解密密码。 Troy Hunt 的文章写于 2012 年。在此之前,密码加密至少有 7 年的历史。我认为 2010 年的 ASP.NET 提供商不再允许密码加密和恢复,即使允许,它也被认为是不安全的,并且出于兼容性原因 【参考方案1】:

请不要在 SQL 中硬编码参数;改为参数化它:

public bool GirisKontrol(string ad, string sifre) 
  //DONE: validate public methods' input
  if (string.IsNullOrEmpty(ad))
    return false; // or throw exception
  else if (string.IsNullOrEmpty(sifre))
    return false; // or throw exception

  using (OracleConnection con = new OracleConnection(connectionString)) 
    con.Open();

    //DONE: no need to count all the entires, just check if there's at least one 
    //DONE: keep query readable
    //DONE: paramterize queries   
    string query = 
      @"select 1 
          from Z_LABEL_USER 
         where USERNAME = :prm_UserName 
           and PASSWORD = :prm_Password";
    
    using (OracleCommand cmd = new OracleCommand(query, con)) 
      //TODO: this syntax can vary from library to library you use to work with Oracle
      cmd.Parameters.Add(":prm_UserName", OracleType.VarChar).Value = ad;
      cmd.Parameters.Add(":prm_Password", OracleType.VarChar).Value = sifre;

      using (OracleDataReader dr = cmd.ExecuteReader()) 
        if (dr.Read()) 
          //TODO: Side effect : it changes instance's state. Do you really want it?
          kAdi = ad;

          return true;
          
      
     
  
 
  return false;

【讨论】:

以上是关于Oracle 选择查询是 C# 中的无效数字的主要内容,如果未能解决你的问题,请参考以下文章

ORA-00904: 子查询中的无效标识符(在选择子句中)

Oracle DB - ORA-00904:选择时出现“无效标识符”错误

ORA-01722: 将值从内部选择查询传递到顶部选择查询时数字无效

ORA-01722: 尝试在接下来 30 秒内获取预定信号的 Oracle 查询中的无效数字

Oracle SQL 开发人员中的有效查询在 SSIS 中无效

什么是“oracle ORA-01722”无效数字?