programing

MongoDB의 JavaScript NoSQL 주입 방지

coolbiz 2023. 7. 9. 21:53
반응형

MongoDB의 JavaScript NoSQL 주입 방지

어떻게 하면 MongoDB에 자바스크립트 NoSQL 주입을 방지할 수 있습니까?

저는 Node.js 애플리케이션에서 일하고 있으며 합격하고 있습니다.req.bodymongoose 모델의 저장 함수에 json 객체입니다.막후에 안전장치가 있는 줄 알았는데 이게 아닌 것 같습니다.

수잔트의 대답은 정확하지 않습니다.MongoDB에서 NoSQL injection을 알고 있어야 합니다.

(여기서 발췌)

User.findOne({
    "name" : req.params.name, 
    "password" : req.params.password
}, callback); 

한다면req.params.password이라{ $ne: 1 }사용자는 암호를 알지 못한 채 검색됩니다.$ne1)과 같지 않음을 의미합니다.

MongoDB 드라이버

mongo-sanitize를 사용할 수 있습니다.

입력에서 '$'로 시작하는 모든 키를 제거하므로 악의적인 사용자의 덮어쓰기에 대한 걱정 없이 MongoDB에 전달할 수 있습니다.

var sanitize = require('mongo-sanitize');

var name = sanitize(req.params.name);
var password = sanitize(req.params.password);

User.findOne({
    "name" : name, 
    "password" : password
}, callback); 

몽구스 드라이버

스키마를 따르므로 암호가 문자열 필드인 경우 개체를 변환합니다.{ $ne: 1 }끈으로 묶으면 손상이 발생하지 않습니다.이 경우에는 검사할 필요가 없으며 적절한 스키마를 설정해야 합니다.

비록 그 게시물은 쓸모가 없지만, 저는 답하고 있습니다.

저는 세 가지 방법을 알고 있습니다.

번째: 다목적 콘텐츠 필터가 있습니다.필터링 방식으로 MongoDB 주입 보호 기능도 제공합니다.

번째: mongo-sanitize, 쿼리 선택기 주입에 대해 mongodb 쿼리를 검사하는 Helper.

번째: 저는 여기서 MongoDB에도 적용할 수 있는 이 솔루션을 보았습니다.구현이 정말 간단합니다.기본 제공 기능만 사용escape()JavaScript 함수입니다.

escape()문자열을 로 변환합니다.ascii암호를$ne로 변환됩니다.%24ne.

var privateKey = escape(req.params.privateKey);

App.findOne({ key: privateKey }, function (err, app) {
  //do something here
}

알 수 없는 구조의 데이터 개체로부터 쿼리 선택기 주입을 방지하려면 다음과 같이 하십시오.

mongo-sanitize를 사용하여 재귀를 통해 자세히 검사합니다.

const deepSanitize = (value) => {
    if(Array.isArray(value)){
        value.forEach(elm=>deepSanitize(elm))
    }
    if(typeof(value) === 'object' && value !== null){
        Object.values(value).forEach((elm)=>{
            deepSanitize(elm)
        })
    }
    return sanitize(value)
}

예를 들어 다음과 같습니다.sanitize(req.query)중첩된 쿼리 선택기는 제거되지 않습니다.

const req = {} 
req.query = { _id : { $ne: 1 } } 

console.log(req.query))               // { _id: { '$ne': 1 } }
console.log(sanitize(req.query))      // { _id: { '$ne': 1 } }

사용.deepSanitize(req.query)검역된 개체(내스트 포함)가 변형됩니다.

console.log(deepSanitize(req.query))       // { _id: {} }
console.log(req.query)                     // { _id: {} }

를 사용하여 개체 변환 제거{...req.query}:

console.log(deepSanitize({...req.query}))  // { _id: {} }
console.log(req.query)                     // { _id: { '$ne': 1 } }

사용 중인 경우MongooseMongoose 6그들은 살균제를 도입했습니다.다음과 같이 사용할 수 있는 필터 옵션(문서 참조):

const obj = { username: 'val', pwd: { $ne: null } };
sanitizeFilter(obj);
obj; // { username: 'val', pwd: { $eq: { $ne: null } } });

이름이 $로 시작하는 속성을 가진 중첩된 개체를 $eq로 묶어서 쿼리 선택기 주입 공격에 대한 쿼리 필터를 검사합니다.

기본적으로 감도를 조정하도록 설정할 수도 있습니다.

mongoose.set('sanitizeFilter', true);

또한 다음을 사용하여 기본 감도를 건너뛸 수 있습니다.trusted():

const user = await User.findOne({
  // Tell Mongoose to not sanitize `{ $ne: true }`
  deleted: mongoose.trusted({ $ne: true }),
  email: req.body.email,
  hashedPassword: req.body.hashedPassword
}).setOptions({ sanitizeFilter: true }); 

참고 내 대답은 틀렸습니다.다른 답변을 참고하시기 바랍니다.

--

클라이언트 프로그램은 MongoDB에서 쿼리를 조립할 때 문자열이 아닌 BSON 개체를 작성합니다.따라서 기존 SQL 주입 공격은 문제가 되지 않습니다.

자세한 내용은 설명서를 참조하십시오.

갱신하다

▁like와 같은 표현은 .eval임의의 JS를 실행할 수 있습니다.이 사용자로부터 실행하고 .eval입력을 정리하지 않고 식과 같은 식을 사용하면 실수할 수 있습니다.JoBu1324가 지적한 것처럼, 다음과 같은 운영.where,mapReduce그리고.groupJS 식을 직접 실행할 수 있습니다.

언급URL : https://stackoverflow.com/questions/13436467/javascript-nosql-injection-prevention-in-mongodb

반응형