2014-09-22 3 views
10

나는 모든 입력을 불신하는 것이 웹에서 잘 알려진 우수 사례라고 생각합니다. 문장JSON의 위생 처리가 필요합니까?

"모든 입력은 악합니다."

은 아마도 입력 유효성 검사와 관련하여 가장 많이 인용 된 인용문 일 것입니다. 자, HTML의 경우 DOMPurify과 같은 도구를 사용하여 위생 처리 할 수 ​​있습니다.

내 질문에 Express를 실행하는 Node.js 서버와 JSON을 수신하고 구문 분석하기 위해 body-parser 미들웨어가있는 경우 어떤 위생도 실행해야합니까?

JSON은 데이터, 코드가 없으며 누군가가 잘못된 JSON을 보내면 body-parser (JSON.parse()를 내부적으로 사용함)가 실패 할 것이므로 내 앱이 유효한 JavaScript 객체를 수신합니다. 내가 평가판을 실행하거나 함수를 호출하지 않는 한, 나는 괜찮을 것이다. 안된다.

내가 누락 된 항목이 있습니까?

+2

그것은 소리 : 예를 들어


, 여기에 이러한 검사의 일부를 적용하는 속성이있는 객체를 기대하고 당신에게 속성 만 당신이 기대했던이 포함 된 필터링 된 결과를 제공하는 구문 분석 함수의 나에게 몸을 파서가 이미 입력을 살균하는 것처럼 보이므로 스스로 그렇게 할 필요는 없습니다. 반면 성능 병목이 아닌 한 입력을 이중으로 소독해도 아무런 해가 없습니다. –

답변

14

이 코드를 실행하지 않습니다 불구하고 구문 분석 결과에서 수용 할 값 쌍을 데이터의 분석, 그래서 eval() 인 방법으로 취약하지 않습니다,하지만 같은 당신이 당신의 서버 및 응용 프로그램의 무결성을 보호하기 위해해야 ​​할 것들이 아직 없습니다 수 :

  1. 예외 핸들러를 적용은 적절한 장소에 JSON.parse() 같이 예외를 throw 할 수 있습니다.
  2. 어떤 데이터가 있는지 가정하지 마십시오. 데이터를 사용하기 전에 데이터를 명시 적으로 테스트해야합니다.
  3. 당신이 특별히 찾고있는 프로세스 속성 만 (JSON에있을 수있는 다른 것들을 피함).
  4. 들어오는 모든 데이터를 합법적 인 허용 가능한 값으로 확인합니다.
  5. 너무 긴 데이터로 인한 DOS 문제를 방지하기 위해 데이터 길이를 살균하십시오.
  6. 들어오는 데이터를 페이지의 HTML에 직접 평가하거나 더 이상 위생하지 않고 SQL 문에 직접 주입하여 더 이상 평가할 수없는 장소에 두지 마십시오. 해당 환경에 안전합니다.

그래서 직접 질문에 답하기 위해 body-parser를 사용하는 것보다 "예"할 수 있습니다. 데이터를 처음으로 처리하는 데 아주 좋은 프론트 라인입니다. 보디 파서 (body-parser)에서 데이터를 얻은 후 데이터로 수행하는 작업의 다음 단계는 많은 경우에 중요하며 별도의주의가 필요할 수 있습니다.

// pass expected list of properties and optional maxLen 
// returns obj or null 
function safeJSONParse(str, propArray, maxLen) { 
    var parsedObj, safeObj = {}; 
    try { 
     if (maxLen && str.length > maxLen) { 
      return null; 
     } else { 
      parsedObj = JSON.parse(str); 
      if (typeof parsedObj !== "object" || Array.isArray(parsedObj)) { 
       safeObj = parseObj; 
      } else { 
       // copy only expected properties to the safeObj 
       propArray.forEach(function(prop) { 
        if (parsedObj.hasOwnProperty(prop)) { 
         safeObj[prop] = parseObj[prop]; 
        } 
       }); 
      } 
      return safeObj; 
     } 
    } catch(e) { 
     return null; 
    } 
} 
4

괜찮을 것입니다. JSON 초기 사용자는 수신 된 문자열에서 eval()을 호출하는 경우가 많았지 만 이는 엄청난 보안 허점이었습니다. 하지만 JSON.parse는 상태에 따라 이러한 종류의 온 전성 검사를 처리합니다.

받은 JSON 개체에서 뭔가를 가져 와서 SQL 쿼리에 직접 전달하지 않는 한, 괜찮을 것입니다.

+2

수신 된 JSON에서 SQL 쿼리로 직접 전달하지 않는 힌트는 특히 유용합니다. 감사합니다 :-)! –

2

당신은 당신은 여전히 ​​아무 키나 화이트리스트해야 더 코드가

평가되지 않습니다 JSON.parse를 사용하고있는 한 : 당신이 JSON.parse() 이후

+4

Crockford의 [json2.js] (https://github.com/douglascrockford/JSON-js/blob/master/json2.js)와 같은 JSON.parse의 일부 폴리필은'eval'을 사용합니다. – Oriol

+3

언급 해 주셔서 감사합니다. 그러나 해결책은 간단합니다. 사용하지 마십시오. – naomik

+3

@Oriol - 게다가,이 질문은 특히 node.js에서 실제'JSON.parse()를 사용하는 코드에 관한 것입니다. 여기에는 polyfill이 포함되어 있지 않습니다. – jfriend00