[Step-By-Step] One-week questions in-depth analysis/weekly 03

  Front end, html5, javascript, node.js, Programmer

This week’s interview questions list:

  • What is XSS attack and what kinds of XSS attacks can be divided into? How do we prevent XSS attacks?
  • How do I hide an element in a page?
  • What is the principle of browser event proxy mechanism?
  • Why is there an error in setTimeout countdown?

11. What is XSS attack and what kinds of XSS attacks can be divided into? How do we prevent XSS attacks?

1. XSS attack

XSS(Cross-Site Scripting) is a code injection attack. The attacker injects malicious code into the target website, and the malicious code will be executed when the attacker logs on the website. These scripts can read cookie, session tokens, or other sensitive website information, carry out phishing fraud on users, and even launch worm attacks.

The essence of XSS is that malicious code is not filtered and mixed with normal code of websites. The browser cannot distinguish which scripts are trusted, resulting in malicious scripts being executed. Because it is executed directly at the user’s terminal, malicious code can directly obtain the user’s information and use this information to impersonate the user to initiate an attacker-defined request to the website.

XSS classification

According to the source of the attack, XSS attacks can be divided into three types: storage type (persistent), reflection type (non-persistent) and DOM type. Let’s take a closer look at these three XSS attacks:

1.1 reflective XSS

When a user clicks on a malicious link, submits a form, or enters a malicious website, the injection script enters the attacked website. The Web server will inject scripts, such as an error message, search results, etc., and return them directly to the user’s browser without filtering.

Attack Steps of Reflective XSS:

  1. The attacker constructed a specialURLWhich contains malicious code.
  2. The user opens the with malicious codeURLWhen, the website server will malicious code fromURLTake it out and splice it in HTML and return it to the browser.
  3. After receiving the response, the user browser parses and executes, and malicious code mixed in it is also executed.
  4. Malicious code steals user data and sends it to the attacker’s website, or impersonates the user and calls the target website interface to perform the operation specified by the attacker.

Reflective XSS vulnerabilities are common throughURLFunctions of passing parameters, such as website search, jump, etc. Due to the need for users to actively open maliciousURLIn order to be effective, attackers often combine various means to induce users to click.

The content of POST can also trigger reflective XSS, but its triggering conditions are rather harsh (form submission pages need to be constructed and users need to be guided to click), so it is very rare.

If you don’t want the front end to get the cookie, the back end can set ithttpOnly(but this is notcross site scriptingThe solution, can only reduce the scope of damage)

How to Prevent Reflective XSS Attacks

Encodes strings.

Escape the query parameters of the url before outputting to the page.

app.get('/welcome', function(req, res) {
    //对查询参数进行编码,避免反射型 XSS攻击
    res.send(`${encodeURIComponent(req.query.type)}`); 
});

1.2 DOM XSS

DOM-type XSS attack is actually the front endJavaScriptThe code is not rigorous enough to insert untrusted content into the page. In use.innerHTML.outerHTML.appendChilddocument.write()When waiting for API, be careful not to insert untrusted data as HTML on the page and use it as much as possible..innerText.textContent.setAttribute()Wait.

Dom-type XSS attack steps:

  1. Attackers construct special data containing malicious code.
  2. The user browser executed malicious code.
  3. Malicious code steals user data and sends it to the attacker’s website, or impersonates the user and calls the target website interface to perform the operation specified by the attacker.

How to prevent DOM-type XSS attacks

The core of preventing DOM-type XSS attacks is to escape the input content (both inline event listeners and link jumps in DOM can run strings as code, and their contents need to be checked).

1. RegardingurlLinks (e.g. of picturessrcProperty), then use it directlyencodeURIComponentTo escape.

2. Nourl, we can code like this:

function encodeHtml(str) {
    return str.replace(/"/g, '"')
            .replace(/'/g, ''')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;');
}

In DOM-type XSS attacks, the removal and execution of malicious code is completed by the browser, which is a security vulnerability of the front-end JavaScript itself.

1.3 Storage XSS

Malicious scripts are permanently stored on the target server. When the browser requests data, the script is returned from the server and executed, with a larger scope of influence than reflection and DOM XSS. The reason for the storage XSS attack is still that the data is not filtered properly: when the front end submits the data to the server end, the data is not filtered properly; When the server receives the data, it does not filter it before storing it. The front end requests data from the server without filtering the output.

Attack Steps for Storage XSS:

  1. The attacker submitted malicious code to the database of the target website.
  2. When the user opens the target website, the website server takes out the malicious code from the database, splices it in HTML and returns it to the browser.
  3. After receiving the response, the user browser parses and executes, and malicious code mixed in it is also executed.
  4. Malicious code steals user data and sends it to the attacker’s website, or impersonates the user and calls the target website interface to perform the operation specified by the attacker.

This kind of attack is common in websites with users’ data storage functions, such as forum posting, merchandise comment, and users’ private letters.

How to Prevent Storage XSS Attacks:

  1. Escape/filter the front-end data before passing it to the server (it cannot prevent the data from being modified by grabbing packets)
  2. The server receives the data and escapes/filters it before storing it in the database.
  3. The front end receives the data transmitted by the server and escapes/filters it before displaying it on the page.

In addition to careful escape, we also need other means to prevent XSS attacks:

1.Content Security Policy

In the server using HTTPContent-Security-PolicyHead to specify the policy, or set at the front endmetaLabel.

For example, the following configuration only allows loading resources under the same domain:

Content-Security-Policy: default-src 'self'
<meta http-equiv="Content-Security-Policy" content="form-action 'self';">

The effect of setting CSP at the front end and the service end is the same, butmetaNot availablereport

Strict CSP can play the following roles in XSS prevention:

  1. It is forbidden to load foreign code to prevent complex attack logic.
  2. Foreign domain submission is prohibited. After the website is attacked, the user’s data will not be leaked to foreign domain.
  3. Execution of inline scripts is prohibited (the rules are stricter and GitHub is currently found to be used).
  4. Prohibit unauthorized script execution (new feature, Google Map mobile version in use).
  5. Reasonable use and reporting can discover XSS in time and help to repair the problem as soon as possible.

2. Input content length control

For untrusted input, a reasonable length should be defined. Although XSS cannot be completely prevented, it can increase the difficulty of XSS attacks.

3. Input content restrictions

For partial input, it can be limited not to contain special characters or only to enter numbers, etc.

4. Other security measures

  • HTTP-only Cookie: JavaScript is prohibited from reading some sensitive Cookies, and the attacker cannot steal this Cookie after completing XSS injection.
  • Verification Code: Prevent scripts from posing as users to submit dangerous operations.

Click to view more

12. How to hide an element in a page?

Hidden type

The screen is not the only output mechanism, for example, invisible elements (hidden elements) on the screen, some of which can still be read by the screen reading software (because the screen reading software depends on the accessibility tree to elaborate). In order to eliminate the ambiguity between them, we classify them into three categories:

  • Completely Hidden: Elements disappear from the rendering tree and do not occupy space.
  • Visual Hiding: Not visible on the screen, occupying space.
  • Semantic Hiding: The screen reading software is unreadable, but normally occupies empty space.

Completely hidden

1.display 属性(不占据空间)
display: none;
2.hidden 属性 (不占据空间)

HTML5 adds attributes equivalent todisplay: none

<div hidden>
</div>

Visual concealment

1.利用 position 和 盒模型 将元素移出可视区范围
  1. Set upposoitionForabsoluteOrfixedBy setting thetopleftEquivalent, move it out of the visible area. (visible area not occupied)
position:absolute;
left: -99999px;
  1. Set uppositionForrelativeBy setting thetopleftEquivalent, move it out of the visible area. (placeholder for visible area)
position: relative;
left: -99999px;

If you want it not to occupy a position in the visible area, you need to set it at the same time.height: 0;

  1. Set the margin value and move it out of the visible area (visible area placeholder).
margin-left: -99999px;

If you want it not to occupy the visible area, you need to set it at the same time.height: 0;

2.利用 transfrom
  1. Zoom (take up space)
transform: scale(0);

If you want to occupy no space, you need to set it at the same time.height: 0

  1. mobiletranslateX,translateY(Occupy Space)
transform: translateX(-99999px);

If you want to occupy no space, you need to set it at the same time.height: 0

  1. Rotationrotate(Occupy Space)
transform: rotateY(90deg);
3.设置其大小为0

Width and height are 0 and font size is 0:

height: 0;
width: 0;
font-size: 0;

Width and height are 0, beyond hiding:

height: 0;
width: 0;
overflow: hidden;
4.设置透明度为0 (占据空间)
opacity: 0;
5.visibility属性 (占据空间)
visibility: hidden
6.层级覆盖,z-index 属性 (占据空间)
position: relative;
z-index: -999;

Set a higher level element to cover this element.

7.clip-path 裁剪 (占据空间)
clip-path: polygon(0 0, 0 0, 0 0, 0 0);

Semantic concealment

aria-hidden 属性 (占据空间)

The screen reading software is unreadable, occupying space and visible.

<div aria-hidden="true">
</div>

11. Use JS to remove elements from the page

Click to view more

13. What is the principle of browser event proxy mechanism?

Event flow

Before talking about the principle of browser event proxy mechanism, let’s first understand the concept of event flow. In early browsers, IE used event capture event flow, while Netscape used event bubbling. “DOM2 level event” divides the event flow into three stages: capture stage, target stage and bubbling stage. Modern browsers also follow this standard.

Principle of Event Proxy Mechanism

Event proxy is also called event proxy. An event is bound to an ancestor DOM element. When an event of a descendant DOM element is triggered, the event bound to the ancestor DOM is triggered by the principle of event bubbling. Because events bubble from the target element to the document object layer by layer.

Why do you want event proxies?

  1. The number of events added to the page will affect the running performance of the page. If too many events are added, the performance of the page will decrease. Using event proxy can greatly reduce the number of registered events.
  2. At the time of the event proxy, a child sun element was added dynamically, and there was no need to bind it again.
  3. There is no need to worry that a DOM element registered with an event may not be able to recycle its event handler after it is removed. We can avoid this problem by delegating the event handler to a higher level element.
  4. Allows multiple listeners to be registered for an event.
  5. It provides a finer means of control.listenerThe trigger phase of the (can choose to capture or bubble).
  6. For anyDOMElements are valid, not just rightHTMLElement is valid.

addEventListener

AddEventListener accepts 3 parameters, namely, the name of the event to be processed, the object that implements the EventListener interface, or a function, an object/a Boolean value.

target.addEventListener(type, listener[, options]);
target.addEventListener(type, listener[, useCapture]);

Options | Optional

  • capture:Boolean. True means trigger during capture phase, false means trigger during bubbling phase. The default is false.
  • once:Boolean. True indicates that the listener will be called at most once after it is added, and the listener will be automatically removed after it is called. The default is false.
  • passive:Boolean. True means listener will never callpreventDefault(). If listener still calls this function, the client will ignore it and throw a console warning. The default is false.

UseCapture(Boolean) | optional

useCaptureFalse by default. Indicates that the event handler is called in the bubbling phase; if set to true, it indicates that the event handler is called in the capturing phase.

For example, proxy all click events in the page to document:

document.addEventListener('click', function (e) {
    console.log(e.target);
    /**
    * 捕获阶段调用调用事件处理程序,eventPhase是 1; 
    * 处于目标,eventPhase是2 
    * 冒泡阶段调用事件处理程序,eventPhase是 3;
    */ 
    console.log(e.eventPhase);
    
}, false);

AndaddEventListenerCorrespondinglyremoveEventListenerTo remove event listening.

Click to view more

14. Why is there an error in SetTimeout countdown?

setTimeoutIt can only ensure that the delay or interval is not less than the set time. Because it actually just adds callbacks to the macro task queue, but if there are tasks on the main thread that have not yet completed execution, it must wait.

If you don’t understand this sentence very well, then it is necessary to understand the operation mechanism of JS.

JS operation mechanism

(1) All synchronization tasks are executed on the main thread to form an execution context stack.

(2) Besides the main line, there is also a “task queue”.

(3) Once all synchronous tasks in the “execution stack” are completed, the system will read the “task queue” to see what events are in it. The corresponding asynchronous tasks end the waiting state, enter the execution stack, and begin execution.

(4) The main thread repeats the third step above.

Such assetTimeout(()=>{callback(); }, 1000)That is, after 1s, thecallbackIn the macro task queue, when 1s arrives, if there are other tasks executing on the main thread, thencallbackYou have to wait, in additioncallbackThe implementation of also needs time, thereforesetTimeoutThere is an error in the time interval of, it can only ensure that the delay is not less than the set time.

How to reducesetTimeoutError of

We can only reduce the number of executionssetTimeoutFor example, the countdown function.

The countdown time is usually obtained from the server. Cause of error:

1. Error time (time of function execution/blocking of other codes) is not considered

2. The browser’s “sleep” is not considered.

Complete eliminationsetTimeoutThe error of is impossible, but we reduce itsetTimeoutThe error of. The error is reduced by correcting the call time of the next task.

let count = 0;
let countdown = 5000; //服务器返回的倒计时时间
let interval = 1000;
let startTime = new Date().getTime();
let timer = setTimeout(countDownStart, interval); //首次执行
//定时器测试
function countDownStart() {
    count++;
    const offset = new Date().getTime() - (startTime + count * 1000);
    const nextInterval = interval - offset; //修正后的延时时间
    if (nextInterval < 0) {
        nextInterval = 0;
    }
    countdown -= interval;
    console.log("误差:" + offset + "ms,下一次执行:" + nextInterval + "ms后,离活动开始还有:" + countdown + "ms");
    if (countdown <= 0) {
        clearTimeout(timer);
    } else {
        timer = setTimeout(countDownStart, nextInterval);
    }
}

If the current page is not visible, an error time greater than 100ms will appear in the countdown. Therefore, when the page is displayed, the remaining time should be retrieved from the server to count down. Of course, for better performance, when the countdown is not visible (Tab page switch/countdown content is not in the visible area), you can choose to stop the countdown.

To this end, we can monitorvisibityChangeEvents are handled.

Click to view more

Reference articles:

[1]MDN addEventListener

[2]https://www.ecma-internationa …

[3]http://www.xuanfengge.com/js- …

Thank you for your friends’ willingness to spend precious time reading this article. If this article gives you some help or inspiration, please don’t be stingy with your praise and Star. Your affirmation is my greatest motivation to move forward.https://github.com/YvetteLau/ …

Recommend to pay attention to my public number:

clipboard.png