正在添加这个“代码游乐场”我的 WordPress 网站存在安全风险吗?

发布于 2025-01-20 03:50:17 字数 4897 浏览 1 评论 0原文

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

我想知道这里是否有安全风险。

代码字段是可编辑的。

显然,人们可以轻松注入JavaScript。

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

感谢您对此的任何帮助。

PS。您可以在下面运行代码段,也可以在此处查看Codepen: https://codepen.io/elementhow/笔/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>

So I'm planning to add this "code playground" kind of interactive code snippets demo to some tutorials on my website.

I was wondering if there were security risks here.

The code fields are editable.

Clearly people can inject JavaScript easily.

However, is that any different at all than when we inject JS from the console tab? Is there any security concerns here?

Thank you for any help with this.

PS. You can run the code snippet below, or see the codepen here : 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>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

醉梦枕江山 2025-01-27 03:50:17

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

长篇:

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

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

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

因此,每个输入都可能构成威胁,您必须​​通过执行输入清理在服务器端安全处理输出转义

Short answer: As long as there is no inputs that could send http requests to your server, it is all client side and safe.

Long:

In the HTTP world for an attack surface you need an "input field" (not UI element) where you can send some data that will be parsed by the server. This is done through http requests, where you put some data in the header and body, send them to the server and you expect some kind of response from the server. If you don't create policies for what forms of data is acceptable for the server, then it's possible to inject code that will make the server behave differently from the business logic.

In your case, you get the playground from the server, and the script in the playground runs on your browsers javascript engine (client side), but nothing is sent back to the server.

For example a big problem would be if without any security measure you could send back your malicious playground to the server to save it (like codepen). This way you can inject code on different levels: server framework, database (SQL injection). And if someone else is able to open your malicious playground then the dangerous script will run on their client side (XSS and CSRF attack).

So every input potentially a threat that you have to handle securely on the server-side by doing input sanitization and output escaping.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文