[javascript] DOM에 임의의 JSON을 포함하는 모범 사례?

다음과 같이 DOM에 임의의 JSON을 포함하는 것에 대해 생각하고 있습니다.

<script type="application/json" id="stuff">
    {
        "unicorns": "awesome",
        "abc": [1, 2, 3]
    }
</script>

이는 나중에 JavaScript 템플릿 엔진에서 사용하기 위해 임의의 HTML 템플릿을 DOM에 저장하는 방식과 유사합니다. 이 경우 나중에 JSON을 검색하고 다음과 같이 구문 분석 할 수 있습니다.

var stuff = JSON.parse(document.getElementById('stuff').innerHTML);

이것은 작동 하지만 가장 좋은 방법입니까? 이것이 모범 사례 또는 표준을 위반합니까?

참고 : DOM에 JSON을 저장하는 대안을 찾고있는 것이 아닙니다. 내가 겪고있는 특정 문제에 대한 최상의 솔루션이라고 이미 결정했습니다. 나는 그것을 할 가장 좋은 방법을 찾고 있습니다.



답변

원래 방법이 최고라고 생각합니다. HTML5 사양은 이러한 용도를 다룹니다.

“데이터 블록 (스크립트와 반대)을 포함하는 데 사용되는 경우 데이터는 인라인으로 포함되어야하며 데이터 형식은 type 속성을 사용하여 제공되어야하며 src 속성은 지정되지 않아야하며 스크립트 요소의 내용은 사용 된 형식에 대해 정의 된 요구 사항을 준수하십시오. “

여기에서 읽으십시오 : http://dev.w3.org/html5/spec/Overview.html#the-script-element

당신은 정확히 그렇게했습니다. 사랑하지 않는 것은 무엇입니까? 속성 데이터에 필요한 문자 인코딩이 없습니다. 원하는 경우 포맷 할 수 있습니다. 표현력이 풍부하고 용도가 명확합니다. 해킹처럼 느껴지지 않습니다 (예 : “운송 업체”요소를 숨기기 위해 CSS를 사용하는 것과 같이). 완벽하게 유효합니다.


답변

일반적인 방향으로 HTML5 데이터 속성을 대신 사용해 보겠습니다 . 유효한 JSON을 입력하는 것을 막을 수는 없습니다. 예 :

<div id="mydiv" data-unicorns='{"unicorns":"awesome", "abc":[1,2,3]}' class="hidden"></div>

jQuery를 사용하는 경우 검색은 다음과 같이 쉽습니다.

var stuff = JSON.parse($('#mydiv').attr('data-unicorns'));


답변

스크립트 태그에 json을 포함하는이 방법에는 잠재적 인 보안 문제가 있습니다. json 데이터가 사용자 입력에서 비롯된 것이라고 가정하면 실제로 스크립트 태그에서 벗어나 DOM에 직접 삽입 할 수있는 데이터 멤버를 만들 수 있습니다. 여기를 보아라:

http://jsfiddle.net/YmhZv/1/

여기 주사입니다

<script type="application/json" id="stuff">
{
    "unicorns": "awesome",
    "abc": [1, 2, 3],
    "badentry": "blah </script><div id='baddiv'>I should not exist.</div><script type="application/json" id='stuff'> ",
}
</script>

이스케이프 / 인코딩 방법은 없습니다.


답변

OWASP의 XSS 방지 치트 시트의 규칙 # 3.1 을 참조하십시오 .

이 JSON을 HTML에 포함하고 싶다고 가정 해 보겠습니다.

{
    "html": "<script>alert(\"XSS!\");</script>"
}

<div>HTML 에서 숨김 을 만듭니다 . 다음으로, 안전하지 않은 엔티티 (예 : &, <,>, “, ‘, 및 /)를 인코딩하여 JSON을 이스케이프하고 요소 안에 넣습니다.

<div id="init_data" style="display:none">
        {&#34;html&#34;:&#34;&lt;script&gt;alert(\&#34;XSS!\&#34;);&lt;/script&gt;&#34;}
</div>

이제 textContentJavaScript를 사용하여 요소를 읽고 파싱하여 액세스 할 수 있습니다 .

var text = document.querySelector('#init_data').textContent;
var json = JSON.parse(text);
console.log(json); // {html: "<script>alert("XSS!");</script>"}


답변

함수 콜백 (일종의 JSONP )을 사용하여 JSON을 인라인 스크립트에 넣는 것이 좋습니다 .

<script>
someCallback({
    "unicorns": "awesome",
    "abc": [1, 2, 3]
});
</script>

실행중인 스크립트가 문서 다음에로드되면 추가 식별자 인수를 사용하여 어딘가에 저장할 수 있습니다. someCallback("stuff", { ... });


답변

내 권장 사항은 JSON 데이터를 외부 .json파일 에 보관 한 다음 Ajax를 통해 해당 파일을 검색하는 것입니다. 웹 페이지 (인라인)에 CSS 및 JavaScript 코드를 넣지 않는데 왜 JSON으로 하시겠습니까?


답변

HTML5에는 기계가 읽을 수있는 데이터를 유지하기위한 <data>요소 가 포함되어 있습니다. 더 안전한 방법 으로 해당 요소 <script type="application/json">value속성 내에 JSON 데이터를 포함 할 수 있습니다 .

const jsonData = document.querySelector('.json-data');
const data = JSON.parse(jsonData.value);

console.log(data)
<data class="json-data" value='
  {
    "unicorns": "awesome",
    "abc": [1, 2, 3],
    "careful": "to escape &#39; quotes"
  }
'></data>

이 경우 값을 큰 따옴표로 묶으려면 모든 작은 따옴표를 &#39;또는 로 바꿔야 &quot;합니다. 그렇지 않으면 다른 답변과 같은 위험 XSS 공격이 제안했습니다.