Writing in the front

Hello, I’m Cary, welcome to my blog, full of good stuff.

The “front-end watermarking anti-tamper” method mentioned in this article was originally intended to be submitted to the company as a patent. However, before I wrote this article, I searched on the domestic patent search website and found that the exact same scheme had already been applied, which was submitted by a byteDance friend at the beginning of this year.

Well, since the pit’s already occupied, I won’t roll it.

But considering that this solution is simple and effective, I share it with you here.

Watermarking implementation scheme

The need for front-end watermarking actually exists all the time, and the most frequent scenario is the internal system of the company to prevent information leakage. If the implementation is at the front end, the mainstream implementation methods are divided into the following two categories:

  • Images such as SVG/PNG are combined with CSS background attributes
  • Canvas

For example, open a well-known online material editing website and check the implementation of its watermark, is the first kind.

It is important to know that the front end of the writing style takes this watermark very seriously.

Here I just took a screenshot of the CSS, and the corresponding HTML is a DIV element that specifies the background image.

Another kind of watermarking based on Canvas is also easy to understand. It can be done by painting directly, which will not be described here.

Watermarking cracking

The early years were quiet until someone opened Devtools…

Once you open the browser’s developer tools, the watermark on the page can be broken by directly modifying the CSS properties of the element.

If the watermark is based on Canvas, it looks difficult, but in fact, directly delete the entire Canvas element in the element area of the console, and the watermark will no longer exist.

Watermarking anti-cracking

Recall that the watermarking solution described below is either by modifying the ELEMENT’s CSS properties or directly modifying the DOM structure, so can we try to use love to persuade the user not to modify it? Of course not. One of the principles of human-computer interaction is to “assume the worst about your users.”

However, when you think about it, whether you modify CSS or DOM, you have to open devTools in your browser. Is devTools not allowed?

B: Sure.

Devtools is prohibited

In Windows, for example, there are only two ways for users to access the console:

  1. Keyboard F12.
  2. Right-click and select Check Elements

That’s easy to do:

// Prevent F12 events
document.addEventListener('keydown'.event= > {
	return 123! == event.keyCode || event.returnValue =false;
});

// Block the right mouse button event
document.addEventListener('contextmenu'.event= > {
	return event.returnValue = false;
});
Copy the code

This does block devTools from being opened, but it’s a bit simplistic, as there are other browser functions beyond “check elements” with the right mouse button, and too much of a one-size-fits-all approach would hurt the user experience.

Listen for devTools open events

Unfortunately, the browser doesn’t have a native DevTools open event, but we can save the country by checking the difference between the browser’s viewable area and the browser window to determine if the user has DevTools open. In fact, devTools-Detect, an open source solution with 1.5K + Star on Github, does just that.

The core implementation is also simple:

const resize = () = > {
	const threshold = 200;
	const width = window.outerWidth - window.innerWidth > threshold;
	const height = window.outerHeight - window.innerHeight > threshold;
	if (width || height) {
		console.log('Console open, user ready to crack watermark!! ');
	}
}

resize();
window.addEventListener('resize', resize);
Copy the code

However, there is a big flaw in this scheme: it can only be used to detect when DevTools is opened inline in a browser page, but almost all browsers now provide devTools in a new window, so this detection can be easily circumvented.

MutationObserver

With that in mind, it’s time to come up with the coolest solution (the patented solution I mentioned at the beginning) : element attribute change monitoring based on MutationObserver.

The MutationObserver interface provides the ability to watch for changes being made to the DOM tree. It is designed as a replacement for the older Mutation Events feature, which was part of the DOM3 Events specification.

In short, a MutationObserver can monitor changes to any attribute on a DOM element and, if necessary, to its children. Isn’t that what we need?

When a user changes the attributes of a watermark element using DevTools, MutationObserver can notify us in a timely manner so that we can restore our watermarks in the first place. One thing to note is that MutationObserver listens for attributes of elements, so our CSS style should be embedded in THE HTML as the element’s style attribute.

The following code is the concrete implementation of this scheme:

// 

const options = { childList: true.attributes: true.subtree: true.attributesOldValue: true.characterData: true.characterDataOldValue: true,}const reset = (expression = () => {}) = > { setTimeout(() = > { observer.disconnect(); // Execute the recovery method expression(); observer.observe(h1, options); }, 0); } const callback = (records) = > { const record = records[0]; if (record.type === 'attributes' && record.attributeName === 'style') { reset(() = > { h1.setAttribute('style'.'margin:100px; '); }); } else if (record.type === 'characterData') { reset(() = > { h1.textContent = 'Don't change me.'}); }}const observer = new MutationObserver(callback); observer.observe(h1, options); Copy the code

The style and textContent of h1 elements are forbidden. You can copy them directly to the IDE.

Here, the value of style can be directly extracted as a constant. Whenever the user modifies the style attribute of the element, this code will automatically cover the modified value with the fixed constant just now, thus realizing the tamper-proof of the front-end watermark.

The last

Please add me to my wechat “K-i2Ving” to make friends, and I can also help you with internal promotion (any well-known company in Shenzhen). I suggest you follow my “blog”, it’s all good stuff.