将此 "code playground" 添加到我的 WordPress 网站是否存在安全风险?

Is adding this "code playground" to my WordPress website a security risk?

所以我打算将这种“代码游乐场”类的交互式代码片段演示添加到我网站上的一些教程中。

我想知道这里是否存在安全隐患

代码字段是可编辑的。

显然人们可以轻松地注射 JavaScript。

但是,这与我们从控制台选项卡注入 JS 时有什么不同吗?这里有任何安全问题吗?

感谢您对此的任何帮助。

PS。您可以 运行 下面的代码片段,或在此处查看代码笔:https://codepen.io/elementhow/pen/dyJKYoB

let examples = document.querySelectorAll(".prog-example");

examples.forEach((example, i, arr) => {
   let pres = example.querySelectorAll(".examples pre");
   if (pres.length < 1) document.querySelector('.examples').remove();
   let htmlOfPreview = example.querySelector(".preview-parent pre");
   let preview = example.querySelector(".preview");
   htmlOfPreview.innerHTML = escapeHTML(preview.innerHTML);
   htmlOfPreview.addEventListener('input',function(){
      preview.innerHTML = htmlOfPreview.textContent;
   });

   let CSSdiv = document.createElement("style");
   document.getElementsByTagName("head")[0].appendChild(CSSdiv);
   pres.forEach((pre, i, arr) => {
      pre.addEventListener("click", function () {
         arr.forEach((e) => e.classList.remove("label-active"));
         pre.classList.add("label-active");
         CSSdiv.innerHTML = pre.textContent;
      });
      pre.setAttribute('contenteditable',"");
      if (pre.hasAttribute("contenteditable")){
         pre.addEventListener('input', function(){
         CSSdiv.innerHTML = pre.textContent;
      });
      }
   });
   if (pres[0]) pres[0].click();
});

function escapeHTML(html) {
   return document.createElement("div").appendChild(document.createTextNode(html)).parentNode.innerHTML;
}
*, *::after {
   box-sizing: border-box;
}
.prog-example {
   display: flex;
   width: 100%;
   background:#cecece;
}
.prog-example .examples {
   max-height: 440px;
   overflow-y: auto;
   padding: 0 10px;
   background-color:#eee8ab;
   min-width:170px;
   position:relative;
}

.prog-example .preview-parent {
   margin: 10px;
   display: flex;
   flex-direction: column;
   flex-grow: 1;
}
.prog-example .examples pre {
   font-size: 12px;
   padding: 6px;
   border: 1px solid #999;
   margin: 14px 0;
   border-radius: 8px;
   cursor: pointer;
   background-color:#fff;
   min-width:170px;
}
.prog-example .examples pre[contenteditable]{
       /* cursor: text; */
}
.prog-example .examples pre.label-active {
   outline: 2px solid #333;
}
.prog-example .preview-parent pre {
   background-color: #eee;
   margin: 0 0 10px;
   padding: 0 10px;
   position:relative;
}
.prog-example .preview-parent .preview {
   border: 1px solid #999;
   flex-grow: 1;
   position:relative;
   min-height:130px;
   background-color:#fff;
}
.prog-example .preview-parent > pre::after,.prog-example .preview-parent .preview::after,  .prog-example .examples::after {
   content:'HTML';
   position:absolute;
   background-color:#777;
   font-family:monospace;
   font-size:13px;
   color:#fff;
   padding:4px;
    border-bottom-left-radius:6px;
   top:0;
   right:0;
}
.prog-example .preview-parent .preview::after {
   content:'PREVIEW';
}
.prog-example .examples::after {
   content:'CSS';
}

/* scroll bar if there is overflow */
.prog-example .examples::-webkit-scrollbar-track {
   background-color: #f4f4f4;
}
.prog-example .examples::-webkit-scrollbar {
   width: 6px;
   background-color: #f4f4f4;
}
.prog-example .examples::-webkit-scrollbar-thumb {
   background-color: #00000044;
}
<div class="prog-example">
   <div class="examples">
      <pre>
.test-button{
   font-size:16px;
}</pre>
      <pre>
.test-button{
   font-size:21px;
}      </pre>
      <pre>
.test-button{
   font-size:44px;
}      </pre>
      <pre>
.test-button{
   font-size:16px;
}</pre>
      <pre>
.test-button{
   font-size:21px;
}      </pre>
      <pre>
.test-button{
   font-size:44px;
}      </pre>
      <pre>
.test-button{
   font-size:16px;
}</pre>
      <pre>
.test-button{
   font-size:21px;
}      </pre>
      <pre>
.test-button{
   font-size:44px;
}      </pre>
      <pre>
.test-button{
   font-size:16px;
}</pre>
      <pre>
.test-button{
   font-size:21px;
}      </pre>
      <pre contenteditable>
.test-button{
   font-size:44px;
}      </pre>
      </div>
   <div class="preview-parent">
      <pre contenteditable></pre>
      <div class="preview">
<div class="wrapper">
<button class='test-button'>click me</button>
</div>
         </div>
   </div>
   </div>

简答:只要没有可以向您的服务器发送 http 请求的输入,都是客户端并且安全的。

长:

在攻击面的 HTTP 世界中,您需要一个“输入字段”(不是 UI 元素),您可以在其中发送一些将由服务器解析的数据。这是通过 http 请求完成的,您将一些数据放在 header 和 body 中,将它们发送到服务器,然后您期望从服务器得到某种响应。如果您不为服务器可接受的数据形式创建策略,则可能会注入使服务器行为不同于业务逻辑的代码。

在您的情况下,您从服务器获取游乐场,并在您的浏览器 javascript 引擎(客户端)上获取游乐场 运行s 中的脚本,但没有任何内容被发送回服务器。

例如,一个大问题是,如果没有任何安全措施,您可以将恶意游乐场发送回服务器以保存它(如 codepen)。通过这种方式,您可以在不同级别注入代码:服务器框架、数据库(SQL 注入)。如果其他人能够打开您的恶意游乐场,那么危险脚本将 运行 在他们的客户端(XSS 和 CSRF 攻击)。

因此,每个输入都可能是您必须在 server-side 上安全处理的威胁,方法是 input sanitization and output escaping