source

Node.js에서 SQL 주입 방지

goodcode 2023. 1. 9. 21:36
반응형

Node.js에서 SQL 주입 방지

PHP가 Node.js에 대해 보호한 Prepared 스테이트먼트를 가진 것과 같은 방법으로 SQL 주입을 방지할 수 있습니까?

만약 그렇다면, 어떻게?그렇지 않은 경우 제공된 코드를 무시할 수 있는 예는 무엇입니까(아래 참조).


일부 컨텍스트:

node-mysql 모듈을 사용하여 Node.js + MySql로 구성된 백엔드 스택을 사용하여 웹 애플리케이션을 만들고 있습니다.조작성의 관점에서 보면, 모듈은 훌륭하지만, PHP의 준비 스테이트먼트와 같은 것을 아직 실장하고 있지 않습니다(실행하고 있는 것은 알고 있습니다만).

제가 알기로는 PHP의 준비된 스테이트먼트 구현은 무엇보다도 SQL 주입을 막는 데 큰 도움이 되었습니다.다만, 디폴트로 제공되는 문자열 이스케이프(아래 코드 스니펫과 같이)에서도, 제 node.js 앱이 유사한 공격에 노출되지 않을까 걱정입니다.

node-mysql은 node.js에서 가장 인기 있는 mysql 커넥터인 것 같습니다.그래서 이 문제를 해결하기 위해 다른 사람들이 무엇을 하고 있는지, 아니면 node.js에 대해서도 문제가 있는지 궁금했습니다(사용자/클라이언트 측 입력이 관련되어 있기 때문에 어떤 문제가 있는지).

node-mysql-native는 준비된 스테이트먼트를 제공하므로 당분간 node-mysql-native로 전환해야 합니까?node-mysql만큼 활성화되지 않은 것 같기 때문에 이 작업을 수행하는 것이 망설여집니다(단, 완료되었다는 의미일 수도 있습니다).

다음은 사이트 간 스크립팅과 SQL 주입을 방지하기 위해 sanitizer 모듈을 사용하는 사용자 등록 코드의 일부와 node-mysql이 준비한 스테이트먼트와 같은 구문(위에서 설명한 바와 같이 문자 이스케이프)을 각각 사용합니다.

// Prevent xss
var clean_user = sanitizer.sanitize(username);

// assume password is hashed already
var post = {Username: clean_user, Password: hash};

// This just uses connection.escape() underneath
var query = connection.query('INSERT INTO users SET ?', post,
   function(err, results)
   {
       // Can a Sql injection happen here?
   });

node-mysql라이브러리는 이미 사용하고 있는 것처럼 자동으로 이스케이프를 수행합니다.https://github.com/felixge/node-mysql#escaping-query-values 를 참조해 주세요.

도서관에는 탈출에 관한 섹션이 있습니다.Javascript 네이티브이므로 node-mysql 네이티브로 변경하는 것은 권장하지 않습니다.문서에는 이스케이프 시 다음 가이드라인이 기재되어 있습니다.

편집: node-mysql-native도 순수 자바스크립트 솔루션입니다.

  • 숫자는 그대로다
  • 은 不 are음음음음음음음음 boole boole boole boole boole boole boole로 된다.truefalse
  • 가 ""로 됩니다.YYYY-mm-dd HH:ii:ss
  • 문자열: 문자열)로됩니다.X'0fa5'
  • 문자열은 안전하게 이스케이프됩니다.
  • 목록으로 변환됩니다).['a', 'b']'a', 'b'
  • 네스트된 된 목록의 경우)으로 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " 등).[['a', 'b'], ['c', 'd']]('a', 'b'), ('c', 'd')
  • key = 'val' 네스트된 . 이치노
  • undefinednullNULL
  • NaNInfinity대로남남 남남남다다MySQL은 이러한 기능을 지원하지 않으므로 값으로 삽입하려고 하면 지원을 구현할 때까지 MySQL 오류가 트리거됩니다.

이를 통해 다음과 같은 작업을 수행할 수 있습니다.

var userId = 5;
var query = connection.query('SELECT * FROM users WHERE id = ?', [userId], function(err, results) {
  //query.sql returns SELECT * FROM users WHERE id = '5'
});

이것과 함께:

var post  = {id: 1, title: 'Hello MySQL'};
var query = connection.query('INSERT INTO posts SET ?', post, function(err, result) {
  //query.sql returns INSERT INTO posts SET `id` = 1, `title` = 'Hello MySQL'
});

이러한 기능 외에 이스케이프 기능도 사용할 수 있습니다.

connection.escape(query);
mysql.escape(query);

쿼리 식별자를 이스케이프하려면:

mysql.escapeId(identifier);

그리고 준비된 진술에 대한 귀하의 코멘트에 대한 답변으로:

조작성의 관점에서 보면 모듈은 훌륭하지만, 아직 PHP의 준비 스테이트먼트와 같은 것을 실장하지 않았습니다.

준비된 문은 이 커넥터의 ToDo 목록에 있지만 이 모듈에서는 준비된 문과 매우 유사한 사용자 지정 형식을 지정할 수 있습니다.다음은 Readme의 예입니다.

connection.config.queryFormat = function (query, values) {
  if (!values) return query;
  return query.replace(/\:(\w+)/g, function (txt, key) {
    if (values.hasOwnProperty(key)) {
      return this.escape(values[key]);
    }
    return txt;
  }.bind(this));
};

이렇게 하면 다음과 같은 쿼리를 사용할 수 있도록 연결 쿼리 형식이 변경됩니다.

connection.query("UPDATE posts SET title = :title", { title: "Hello MySQL" });
//equivalent to
connection.query("UPDATE posts SET title = " + mysql.escape("Hello MySQL");

사용하고 있는 모듈이 안전한지 어떤지를 테스트하기 위해 선택할 수 있는 루트가 몇 가지 있습니다.각각의 장점과 단점을 짚어보고 좀 더 정보에 입각한 결정을 내리실 수 있도록 하겠습니다.

현재 사용하고 있는 모듈에는 취약성이 없습니다.다만, 사용하고 있는 모듈/소프트웨어 패키지를 부정 이용하는 취약성이 있는 경우가 많아, 벤더가 수정/패치를 적용할 때까지 문제의 경고를 받지 않습니다.

  1. 취약성에 대응하려면 메일링 리스트, 포럼, IRC 및 기타 해킹 관련 논의를 따라야 합니다.PRO: 벤더에게 경고를 받거나 소프트웨어에 대한 잠재적인 공격 경로를 수정하기 위한 수정/패치를 발행하기 전에 라이브러리 내의 잠재적인 문제를 발견할 수 있는 경우가 많습니다.단점: 이 작업은 매우 많은 시간과 자원을 필요로 합니다.RSS 피드, 로그 해석(IRC 채팅로그) 및 프레이퍼(이 경우 node-mysql-native)를 사용하여 봇을 라우팅하면 이러한 자원의 트롤링에 소비하는 시간을 단축할 수 있습니다.

  2. fuzzer를 만들고 fuzzer 또는 metaspload, sqlMap 등의 기타 취약성 프레임워크를 사용하여 벤더가 미처 찾지 못한 문제를 테스트합니다.PRO: 구현 중인 모듈/소프트웨어가 일반인의 접근에 안전한지 여부를 확인하는 확실한 방화 방법이 될 수 있습니다.단점: 시간도 많이 걸리고 비용도 많이 듭니다.다른 문제는 문제가 존재하지만 알아차리지 못한 결과에 대한 교육되지 않은 검토뿐만 아니라 잘못된 긍정에서 발생할 수 있습니다.

보안 및 애플리케이션 보안은 일반적으로 매우 많은 시간과 리소스를 필요로 합니다.관리자가 항상 사용하는 것은 위의 두 가지 옵션을 실행하는 경우의 비용 효과(인력, 자원, 시간, 보수 등)를 결정하는 공식입니다.

어쨌든, 이것은 「예」또는 「아니오」라고 하는 대답이 아닌 것은 알고 있습니다만, 문제의 소프트웨어에 대한 분석을 실시하지 않는 한, 아무도 당신에게 그것을 줄 수 없다고 생각합니다.

Mysql 네이티브는 오래되어 MySQL2가 되었습니다.Mysql은 원래 MySQL 모듈 팀의 도움을 받아 만든 새로운 모듈입니다.이 모듈에는 더 많은 기능이 있으며, (사용으로) 문장을 작성했기 때문에 당신이 원하는 것을 가지고 있다고 생각합니다.execute()를 사용하여 보안을 강화합니다.

또한 매우 활발합니다(지난번 변경은 2-1일) 전에는 시도하지 않았지만, 당신이 원하는 것 이상이라고 생각합니다.

SQL 주입 방지

SQL 주입은 데이터베이스를 파괴하거나 오용하기 위한 일반적인 웹 해킹 기법입니다.SQL 주입을 방지하려면 쿼리 값이 사용자가 제공한 변수인 경우 값 이스케이프를 사용해야 합니다.

mysql.escape() 메서드를 사용하여 쿼리 값을 이스케이프합니다.

var adr = 'Mountain 21';
var sql = 'SELECT * FROM customers WHERE address = ' + mysql.escape(adr);
con.query(sql, function (err, result) {
  if (err) throw err;
  console.log(result);
});

placeholder ? 메서드를 사용하여 쿼리 값을 이스케이프합니다.

var adr = 'Mountain 21';
var sql = 'SELECT * FROM customers WHERE address = ?';
con.query(sql, [adr], function (err, result) {
  if (err) throw err;
  console.log(result);
});

상세

언급URL : https://stackoverflow.com/questions/15778572/preventing-sql-injection-in-node-js

반응형