HTML 문서의 특정 부분에서 JavaScript를 실행하지 않도록 브라우저에 지시 할 수 있습니까?
처럼:
<div script="false"> ...
추가 보안 기능으로 유용 할 수 있습니다. 내가 원하는 모든 스크립트는 문서의 특정 부분에로드됩니다. 문서의 다른 부분에는 스크립트가 없어야하며 스크립트가있는 경우 실행해서는 안됩니다.
HTML 문서의 특정 부분에서 JavaScript를 실행하지 않도록 브라우저에 지시 할 수 있습니까?
처럼:
<div script="false"> ...
추가 보안 기능으로 유용 할 수 있습니다. 내가 원하는 모든 스크립트는 문서의 특정 부분에로드됩니다. 문서의 다른 부분에는 스크립트가 없어야하며 스크립트가있는 경우 실행해서는 안됩니다.
script-src:"self"
도메인의 스크립트 만 페이지에서 실행되도록 지정 하면됩니다. 관심이 있으시면 Mike West의 CSP 관련 기사를 읽어보십시오 .
</div>
그들이이 DOM 요소를 닫기 위해를 주입 한 다음 <div>
스크립트가 실행되지 않는 것의 형제가 될 새로운 것을 시작하는 것을 어떻게 막을 것인가?
답변:
예, 할 수 있습니다. :-) 대답은 CSP ( 콘텐츠 보안 정책 )입니다.
대부분의 최신 브라우저 는 신뢰할 수있는 외부 파일에서 JavaScript 코드를로드하고 모든 내부 JavaScript 코드를 허용하지 않도록 브라우저에 지시하는 이 플래그를 지원 합니다. 유일한 단점은 전체 페이지에서 인라인 자바 스크립트를 사용할 수 없다는 것입니다 (단일 <div>
). 다른 보안 정책을 사용하여 외부 파일의 div를 동적으로 포함하여 해결 방법이있을 수 있지만 확실하지 않습니다.
그러나 외부 자바 스크립트 파일에서 모든 자바 스크립트를로드하도록 사이트를 변경할 수 있다면이 헤더와 함께 인라인 자바 스크립트를 모두 비활성화 할 수 있습니다!
다음은 예제가 포함 된 멋진 튜토리얼입니다. HTML5Rocks Tutorial
이 HTTP-Header 플래그를 보내도록 서버를 구성 할 수 있다면 세상이 더 나은 곳이 될 것입니다!
이벤트를 <script>
사용하여에서 로드 한 자바 스크립트를 차단할 수 있습니다 beforescriptexecute
.
<script>
// Run this as early as possible, it isn't retroactive
window.addEventListener('beforescriptexecute', function(e) {
var el = e.target;
while(el = el.parentElement)
if(el.hasAttribute('data-no-js'))
return e.preventDefault(); // Block script
}, true);
</script>
<script>console.log('Allowed. Console is expected to show this');</script>
<div data-no-js>
<script>console.log('Blocked. Console is expected to NOT show this');</script>
</div>
참고 beforescriptexecute
HTML 5.0에 정의되어 있지만, HTML 5.1에서 제거되었습니다. Firefox는이를 구현 한 유일한 주요 브라우저입니다.
페이지에 신뢰할 수없는 HTML 묶음을 삽입하는 경우 해당 요소 내부의 차단 스크립트는 더 많은 보안을 제공하지 않습니다. 신뢰할 수없는 HTML이 샌드 박스 요소를 닫을 수 있으므로 스크립트가 외부에 배치되어 실행되기 때문입니다.
그리고 이것은 같은 것을 차단하지 않습니다 <img onerror="javascript:alert('foo')" src="//" />
.
beforescriptexecute
이벤트를 지원하지 않을 것 입니다. Firefox에서 작동합니다.
beforescriptexecute
지원되지 않으며 대부분의 주요 브라우저에서 지원되지 않는 것 같습니다. developer.mozilla.org/en-US/docs/Web/Events/beforescriptexecute
흥미로운 질문은 가능하지 않다고 생각합니다. 하지만 그렇다고해도 해킹처럼 들립니다.
해당 div의 콘텐츠를 신뢰할 수없는 경우 HTTP 응답으로 전송되고 브라우저에서 렌더링되기 전에 서버 측에서 데이터를 이스케이프해야합니다.
<script>
태그 를 제거 하고 다른 html 태그 만 허용하려면 콘텐츠에서 제거하고 나머지는 그대로 두십시오.
XSS 예방을 살펴보십시오.
https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet
JavaScript는 "인라인"으로 실행됩니다. 즉, DOM에 나타나는 순서대로 실행됩니다 (그렇지 않은 경우 처음 사용할 때 다른 스크립트에 정의 된 일부 변수가 표시되는지 확인할 수 없습니다. ).
그래서 이론적으로 의미 당신은 페이지의 시작 부분에서 스크립트 (즉, 첫째 가질 수있는 <script>
DOM을 통해 요소) 외모와 제거 모든 <script>
당신의 내부 요소와 이벤트 핸들러 <div>
.
그러나 현실은 더 복잡합니다. DOM과 스크립트 로딩은 비동기 적으로 발생합니다. 즉, 브라우저는 스크립트가 그 앞에 있는 DOM 부분 (예 : 지금까지의 헤더)을 볼 수 있음을 보증합니다 . 그 이상에 대한 보장은 없습니다 (과 관련됨 document.write()
). 따라서 다음 스크립트 태그가 표시되거나 표시되지 않을 수 있습니다.
onload
문서 의 이벤트에 래치 하여 전체 DOM을 확보 할 수 있지만 그 당시에는 악성 코드가 이미 실행되었을 수 있습니다. 다른 스크립트가 DOM을 조작하여 거기에 스크립트를 추가하면 상황이 악화됩니다. 따라서 DOM의 모든 변경 사항도 확인해야합니다.
따라서 @cowls 솔루션 (서버에서 필터링)은 모든 상황에서 작동하도록 만들 수있는 유일한 솔루션입니다.
브라우저에 JavaScript 코드를 표시하려는 경우 :
JavaScript 및 HTML을 사용하면 HTML 엔터티 를 사용 하여 JavaScript 코드를 표시하고이 코드가 실행되는 것을 방지해야합니다. 여기에서 HTML 엔티티 목록을 찾을 수 있습니다.
서버 측 스크립팅 언어 (PHP, ASP.NET 등)를 사용하는 경우 문자열을 이스케이프하고 특수 문자를 HTML 엔티티로 변환하는 함수가있을 것입니다. PHP에서는 "htmlspecialchars ()"또는 "htmlentities ()"를 사용합니다. 후자는 모든 HTML 문자를 다룹니다.
JavaScript 코드를 멋지게 표시하려는 경우 코드 하이 라이터 중 하나를 사용해보십시오.
나는 이론이 있습니다.
noscript
태그 안에 감습니다.script
태그 내부의 모든 태그 를 삭제 noscript
한 다음 해당 내용을 풉니 다.개념 증명 예 :
window.onload = function() {
var noscripts = /* _live_ list */ document.getElementsByTagName("noscript"),
memorydiv = document.createElement("div"),
scripts = /* _live_ list */ memorydiv.getElementsByTagName("script"),
i,
j;
for (i = noscripts.length - 1; i >= 0; --i) {
memorydiv.innerHTML = noscripts[i].textContent || noscripts[i].innerText;
for (j = scripts.length - 1; j >= 0; --j) {
memorydiv.removeChild(scripts[j]);
}
while (memorydiv.firstChild) {
noscripts[i].parentNode.insertBefore(memorydiv.firstChild, noscripts[i]);
}
noscripts[i].parentNode.removeChild(noscripts[i]);
}
};
body { font: medium/1.5 monospace; }
p, h1 { margin: 0; }
<h1>Sample Content</h1>
<p>1. This paragraph is embedded in HTML</p>
<script>document.write('<p style="color: red;">2. This paragraph is generated by JavaScript</p>');</script>
<p>3. This paragraph is embedded in HTML</p>
<h1>Sample Content in No-JavaScript Zone</h1>
<noscript>
<p>1. This paragraph is embedded in HTML</p>
<script>document.write('<p style="color: red;">2. This paragraph is generated by JavaScript</p>');</script>
<p>3. This paragraph is embedded in HTML</p>
</noscript>
<noscript>
<p>1. This paragraph is embedded in HTML</p>
<script>document.write('<p style="color: red;">2. This paragraph is generated by JavaScript</p>');</script>
<p>3. This paragraph is embedded in HTML</p>
</noscript>
<noscript>
태그하고 그들이 무엇을 좋아 주사한다.
나중에 스크립트 태그를 다시 활성화하려면 브라우저 환경을 중단하여 실행되는 모든 스크립트에서 오류가 상당히 일찍 발생하도록하는 것이 제 해결책이었습니다. 그러나 완전히 신뢰할 수는 없으므로 보안 기능으로 사용할 수 없습니다.
전역 속성에 액세스하려고하면 Chrome에서 예외가 발생합니다.
setTimeout("Math.random()")
// => VM116:25 Uncaught Error: JavaScript Execution Inhibited
에서 덮어 쓸 수있는 모든 속성을 덮어 window
쓰지만 다른 기능을 중단하도록 확장 할 수도 있습니다.
window.allowJSExecution = inhibitJavaScriptExecution();
function inhibitJavaScriptExecution(){
var windowProperties = {};
var Object = window.Object
var console = window.console
var Error = window.Error
function getPropertyDescriptor(object, propertyName){
var descriptor = Object.getOwnPropertyDescriptor(object, propertyName);
if (!descriptor) {
return getPropertyDescriptor(Object.getPrototypeOf(object), propertyName);
}
return descriptor;
}
for (var propName in window){
try {
windowProperties[propName] = getPropertyDescriptor(window, propName)
Object.defineProperty(window, propName, {
get: function(){
throw Error("JavaScript Execution Inhibited")
},
set: function(){
throw Error("JavaScript Execution Inhibited")
},
configurable: true
})
} catch (err) {}
}
return function allowJSExecution(){
for (var propName in window){
if (!(propName in windowProperties)) {
delete windowProperties[propName]
}
}
for (var propName in windowProperties){
try {
Object.defineProperty(window, propName, windowProperties[propName])
} catch (err) {}
}
}
}