PHP가이를 방지하는 Prepared Statements를 가지고있는 것과 같은 방식으로 Node.js (가급적 모듈 사용)에서 SQL 주입을 방지 할 수 있습니까?
그렇다면 어떻게? 그렇지 않은 경우 내가 제공 한 코드를 우회 할 수 있는 몇 가지 예는 무엇입니까 (아래 참조).
일부 컨텍스트 :
node-mysql 모듈을 사용하여 Node.js + MySql로 구성된 백엔드 스택으로 웹 애플리케이션을 만들고 있습니다. 유용성의 관점에서, 모듈은 매우 중요하지만, 아직 PHP의 유사 뭔가를 구현하지 않은 문 준비 (나는 그것이에 알고 있어요하지만 할 일 ).
필자가 이해 한 바에 따르면 PHP의 준비된 명령문 구현은 무엇보다도 SQL 삽입을 방지 하는 데 크게 도움이되었습니다 . 하지만 기본적으로 제공되는 문자열 이스케이프 (아래 코드 스 니펫 참조)를 사용 하더라도 내 node.js 앱이 유사한 공격에 노출 될 수 있다는 점이 걱정 됩니다.
node-mysql은 node.js를위한 가장 인기있는 mysql 커넥터 인 것 같습니다. 그래서 다른 사람들이이 문제를 설명하기 위해 무엇을하는지 궁금합니다. (사용자 / 클라이언트 측 입력이 관련되어 있기 때문에 이것이 어떻게 될지 확실하지 않습니다).
준비된 명령문을 제공하므로 당분간 node-mysql-native 로 전환해야합니까 ? 이것은 node-mysql만큼 활동적이지 않은 것 같기 때문에 주저합니다.
다음은 새니 타이 저 모듈 을 사용하는 사용자 등록 코드 와 node-mysql의 준비된 문과 유사한 구문 (위에서 언급했듯이 문자 이스케이프를 수행함)을 사용하여 사이트 간 스크립팅 및 SQL 삽입을 각각 방지하는 코드입니다.
// 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-native이므로 node-mysql-native로 전환하는 것은 권장하지 않습니다 . 문서에는 이스케이프에 대한 다음 지침이 나와 있습니다.
편집 : node-mysql-native 는 또한 순수 자바 스크립트 솔루션입니다.
- 숫자는 그대로 둡니다.
- 부울은
true
/false
문자열 로 변환 됩니다. - 날짜 개체는
YYYY-mm-dd HH:ii:ss
문자열 로 변환 됩니다. - 버퍼는 16 진 문자열로 변환됩니다.
X'0fa5'
- 문자열은 안전하게 이스케이프됩니다.
- 배열은 목록
['a', 'b']
으로 변환됩니다.'a', 'b'
- 중첩 된 배열은 그룹화 된 목록 (대량 삽입 용)
[['a', 'b'], ['c', 'd']]
으로 변환됩니다.('a', 'b'), ('c', 'd')
- 개체는
key = 'val'
쌍 으로 바뀝니다. 중첩 된 개체는 문자열로 캐스팅됩니다. undefined
/null
변환NULL
NaN
/Infinity
그대로 둡니다. 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의 Prepared Statements와 유사한 것을 구현하지 않았습니다.
준비된 명령문은 이 커넥터의 할 일 목록에 있지만이 모듈은 최소한 준비된 명령문과 매우 유사한 사용자 정의 형식을 지정할 수 있도록합니다. 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");
답변
나는 이것이 오래된 게시물이라는 것을 알고 있지만 답변이 표시되지 않은 것 같아서 이것을 밖으로 던질 것입니다.
사용중인 모듈이 안전한지 여부를 테스트하는 것과 관련하여 취할 수있는 여러 경로가 있습니다. 더 많은 정보에 입각 한 결정을 내릴 수 있도록 각각의 장단점을 다루겠습니다.
현재 사용중인 모듈에 대한 취약점은 없지만, 현재 사용중인 모듈 / 소프트웨어 패키지를 악용하는 취약점이있을 수 있으며 경고를받지 못하므로 종종 잘못된 보안 감각으로 이어질 수 있습니다. 공급 업체가 수정 / 패치를 적용 할 때까지
-
취약성을 파악하려면 메일 링리스트, 포럼, IRC 및 기타 해킹 관련 토론을 따라야합니다. 장점 : 공급 업체가 경고를 받거나 소프트웨어에 대한 잠재적 인 공격 경로를 수정하기 위해 수정 / 패치를 발행하기 전에 라이브러리 내의 잠재적 문제를 인식하는 경우가 많습니다. 단점 : 이것은 매우 시간과 리소스를 많이 사용합니다. RSS 피드를 사용하는 봇, 로그 구문 분석 (IRC 채팅 로그) 및 또는 핵심 구문 (이 경우 node-mysql-native) 및 알림을 사용하는 웹 스크레이퍼를 사용하면 이러한 리소스를 트롤링하는 데 소요되는 시간을 줄이는 데 도움이 될 수 있습니다.
-
fuzzer를 만들고, fuzzer 또는 metasploit , sqlMap 등과 같은 기타 취약성 프레임 워크 를 사용하여 공급 업체가 찾지 못한 문제를 테스트하는 데 도움을줍니다. PRO : 이것은 구현중인 모듈 / 소프트웨어가 공개 액세스에 안전한지 여부를 허용 가능한 수준으로 보장하는 확실한 화재 방법임을 입증 할 수 있습니다. 단점 : 이것은 또한 시간과 비용이 많이 듭니다. 다른 문제는 잘못된 긍정과 문제가 존재하지만 알아 차리지 못한 결과에 대한 교육받지 못한 검토에서 비롯됩니다.
실제로 보안 및 일반적으로 애플리케이션 보안은 시간과 리소스를 많이 소모 할 수 있습니다. 관리자가 항상 사용하는 한 가지는 위의 두 가지 옵션을 수행하는 비용 효율성 (인력, 자원, 시간, 급여 등)을 결정하는 공식입니다.
어쨌든, 나는 이것이 바라고있을 수있는 ‘예’또는 ‘아니오’대답이 아니라는 것을 알고 있지만 문제의 소프트웨어에 대한 분석을 수행 할 때까지 아무도 당신에게 그것을 줄 수 있다고 생각하지 않습니다.
답변
나는이 질문이 오래되었다는 것을 알고 있지만 관심있는 사람이라면 Mysql-native가 구식이어서 원래 MySQL 모듈 팀의 도움으로 만든 새로운 모듈 인 MySQL2 가되었습니다 . 이 모듈은 더 많은 기능을 가지고 있으며 더 많은 보안을 위해 PHP에서와 같이 문을 준비 (using.execute ())했기 때문에 원하는 것을 가지고 있다고 생각합니다.
또한 매우 활동적입니다 (마지막 변경은 2-1 일이었습니다). 전에는 해본 적이 없지만 원하는 것 이상이라고 생각합니다.
답변
가장 쉬운 방법은 경로로 내보내는 자체 모듈에서 모든 데이터베이스 상호 작용을 처리하는 것입니다. 경로에 데이터베이스 컨텍스트가 없으면 SQL은 어쨌든 그것을 건드릴 수 없습니다.