Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js ORA-01036:通过nodejs运行查询时,变量名称/编号非法_Node.js_Oracle_Node Oracledb - Fatal编程技术网

Node.js ORA-01036:通过nodejs运行查询时,变量名称/编号非法

Node.js ORA-01036:通过nodejs运行查询时,变量名称/编号非法,node.js,oracle,node-oracledb,Node.js,Oracle,Node Oracledb,我正在使用oracledb nodejs包运行这个简单的查询'ALTER USER hr IDENTIFIED BY secret'。不确定为什么会出现非法变量名错误。我可以这样做吗“alteruser:USER-identifiedby:password”如果是,那么我的正确语法是什么 function get(req, res, next) { oracledb.getConnection( config.database, function(err,

我正在使用oracledb nodejs包运行这个简单的查询
'ALTER USER hr IDENTIFIED BY secret'
。不确定为什么会出现非法变量名错误。我可以这样做吗
“alteruser:USER-identifiedby:password”如果是,那么我的正确语法是什么

function get(req, res, next) {
    oracledb.getConnection(
        config.database,
        function(err, connection){
            if (err) {
                return next(err);
            }

            connection.execute(
                'ALTER USER :user IDENTIFIED BY :password'+

            {
                user: req.body.user
            },
            {
                password: req.body.password
            },

                {
                    outFormat: oracledb.OBJECT
                }


          });
        }

感谢您的帮助这里有几个问题:

  • SQL字符串中缺少空格,因此它的各个部分一起运行

  • 在任何情况下,语法都是由secret标识的ALTER USER hr,正如您在介绍中所说的那样;我认为
    WHERE
    子句不会有任何效果

  • 您可以在
    ALTER
    语句中查找用户名之类的内容。相反,您必须通过连接字符串来构造命令,并仔细检查组件是否格式正确,并且不能用于SQL注入攻击

  • 像这样的东西应该可以工作(但我还没有测试过):


    这里有几个问题:

  • SQL字符串中缺少空格,因此它的各个部分一起运行

  • 在任何情况下,语法都是由secret标识的ALTER USER hr,正如您在介绍中所说的那样;我认为
    WHERE
    子句不会有任何效果

  • 您可以在
    ALTER
    语句中查找用户名之类的内容。相反,您必须通过连接字符串来构造命令,并仔细检查组件是否格式正确,并且不能用于SQL注入攻击

  • 像这样的东西应该可以工作(但我还没有测试过):


    正如Matthew指出的,您必须使用字符串连接并防止SQL注入

    在某种程度上,我质疑这样做的必要性。我知道你已经知道这个帖子了:

    由于该解决方案使用表来存储用户凭据,而不是依赖于数据库用户,因此可以安全地绑定这些值,而不必担心SQL注入。为什么不使用这种方法呢

    将数据库用户与动态SQL一起使用要求密码中不允许使用单引号(')。坦率地说,我讨厌那种限制。密码规则应该存在以提高安全性(必须包含的内容),而不是确保代码可以安全执行(不允许的内容)。对于自定义表来说,这不是问题

    但是,这里有一个基于承诺的示例解决方案,它展示了如何使用dbms_assert来清理传入的值:

    const oracledb = require('oracledb');
    const config = require('./dbConfig.js');
    
    function get(req, res, next) {
      let conn;
      const user = req.body.user;
      const password = req.body.password; // Do not change case
    
      oracledb.getConnection(config)
        .then((c) => {
          conn = c;
    
          return conn.execute(
           `declare
    
              -- Use dbms_assert to sanitize values coming in to avoid SQL injection.
              l_user      varchar2(30) := dbms_assert.simple_sql_name(:user);
              l_password  varchar2(30) := dbms_assert.enquote_literal(:password);
              l_statement varchar2(100);
    
            begin
    
              -- Replace single quotes added by enquote_literal to left and right sides with double quotes
              l_password := '"' || substr(substr(l_password, 2, length(l_password)), 1, length(l_password) - 2) || '"';
    
              l_statement := 'alter user ' || l_user || ' identified by ' || l_password;
    
              execute immediate l_statement;
    
            end;`,
            {
              user: user,
              password: password
            }
          );
        })
        .then(result => {
          console.log('Password changed');
    
          // write to res
        })
        .catch(err => {
          console.log('Error changing password', err);
    
          next(err);
        })
        .then(() => {
          if (conn) { // conn assignment worked, need to close
            return conn.close();
          }
        })
        .catch(err => {
          console.log('Error during close', err);
        });
    }
    
    // Simulate run of 'get' function
    get(
      {
        body: {
          user: 'movie_budget',
          password: 'N0rm@l-P@sswOrd!' // This value will throw an error: '\'\; drop table users;'
        }
      }, 
      {},
      function() {}
    );
    

    最后,将数据库逻辑与控制器逻辑相结合可能会产生难以维护的代码。看看这段录音,了解一些更好地组织事情的技巧:

    正如Matthew所指出的,您必须使用字符串连接并防止SQL注入

    在某种程度上,我质疑这样做的必要性。我知道你已经知道这个帖子了:

    由于该解决方案使用表来存储用户凭据,而不是依赖于数据库用户,因此可以安全地绑定这些值,而不必担心SQL注入。为什么不使用这种方法呢

    将数据库用户与动态SQL一起使用要求密码中不允许使用单引号(')。坦率地说,我讨厌那种限制。密码规则应该存在以提高安全性(必须包含的内容),而不是确保代码可以安全执行(不允许的内容)。对于自定义表来说,这不是问题

    但是,这里有一个基于承诺的示例解决方案,它展示了如何使用dbms_assert来清理传入的值:

    const oracledb = require('oracledb');
    const config = require('./dbConfig.js');
    
    function get(req, res, next) {
      let conn;
      const user = req.body.user;
      const password = req.body.password; // Do not change case
    
      oracledb.getConnection(config)
        .then((c) => {
          conn = c;
    
          return conn.execute(
           `declare
    
              -- Use dbms_assert to sanitize values coming in to avoid SQL injection.
              l_user      varchar2(30) := dbms_assert.simple_sql_name(:user);
              l_password  varchar2(30) := dbms_assert.enquote_literal(:password);
              l_statement varchar2(100);
    
            begin
    
              -- Replace single quotes added by enquote_literal to left and right sides with double quotes
              l_password := '"' || substr(substr(l_password, 2, length(l_password)), 1, length(l_password) - 2) || '"';
    
              l_statement := 'alter user ' || l_user || ' identified by ' || l_password;
    
              execute immediate l_statement;
    
            end;`,
            {
              user: user,
              password: password
            }
          );
        })
        .then(result => {
          console.log('Password changed');
    
          // write to res
        })
        .catch(err => {
          console.log('Error changing password', err);
    
          next(err);
        })
        .then(() => {
          if (conn) { // conn assignment worked, need to close
            return conn.close();
          }
        })
        .catch(err => {
          console.log('Error during close', err);
        });
    }
    
    // Simulate run of 'get' function
    get(
      {
        body: {
          user: 'movie_budget',
          password: 'N0rm@l-P@sswOrd!' // This value will throw an error: '\'\; drop table users;'
        }
      }, 
      {},
      function() {}
    );
    

    最后,将数据库逻辑与控制器逻辑相结合可能会产生难以维护的代码。查看这段录音,了解一些更好地组织事情的技巧:

    如果密码包含a&引擎可能会将其视为用户变量;并等待用户输入。使用参数化查询可以消除任何其他错误;并等待用户输入。使用参数化查询可以消除任何其他错误。谢谢,丹。不幸的是,我不能使用用户表来存储凭据。我必须和数据库用户一起去。明白了。您计划如何在进行身份验证时验证凭据?谢谢,Dan。不幸的是,我不能使用用户表来存储凭据。我必须和数据库用户一起去。明白了。在进行身份验证时,您计划如何验证凭据?