头图

Preface

Web security issues have always been a topic that cannot be avoided in the front-end field, but many front-end personnel only stay in the interview process for web-related security strategies. This article mainly summarizes the security issues encountered during the online process. , Aims to have a more three-dimensional personal experience of Web security related issues, and hope to provide you with some references when stepping on the pit.

background

XSS vs CSRF

XSS

XSS is Cross-site scripting . In order Cascading Style Sheets , it is abbreviated as XSS:

Cross-site scripting (XSS) is a security exploit which allows an attacker to inject into a website malicious client-side code. This code is executed by the victims and lets the attackers bypass access controls and impersonate users.

From the definition given by MDN, it can be seen that XSS inject (injecting) harmful code. That is to say, the attack plan of XSS is injection. Here it is generally by injecting scripts, due to the dom and bomb in the browser. Provides an interface for js, so js can operate html and css, and it can also insert html fragments.

CSRF

Many people can't distinguish CSRF. In fact, they still have a big difference, but they usually use XSS to get some permissions before performing CSRF. CSRF is the abbreviation Cross-Site Request Forgery

CSRF (Cross-Site Request Forgery) is an attack that impersonates a trusted user and sends a website unwanted commands.

It can be seen from the definition of MDN that CSRF is attacked by forgery, that is, its essential purpose needs to use all means to pretend to obtain the authority resources that do not belong to it.

the difference

namePurposeRemark
XSSTampering with contentDon't care about permissions
CSRFAccess to resourcesOnly care about permissions

XSS classification

nameStoreIntrusion methodScenes
Storage type (persistent)Backend databaseHTMLWebsites with user saved data, such as forum posts, product reviews, user private messages
Reflective (non-persistent)URLHTMLWebsite search, jump
DOM typeBack-end database/front-end storage/URLjsFront-end js execution, such as writing eval, etc.

XSS defense plan

XSS prevention is mainly divided into two parts:

  1. Prevent attackers from submitting malicious code
  2. The browser executes malicious code

Different prevention ideas can be sorted out from these two parts:

methodstepTypes of
Use template engine1Storage type, reflective type
Restrict and escape input1Storage type, reflective type
Restrict js execution method2DOM type
Content Security Policy1、2Storage type, reflective type, DOM type

As can be seen from the above list, Content Security Policy is relatively good at preventing XSS, then the focus of this article will be the focus of this article. In the next part, we will focus on CSP related content.

CSP

图片

Content Security Policy (Content Security Policy) is an important part of the modern browser security mechanism. It can be seen from the figure that except for the old IE which only supports the sandbox of csp, other mainstream browsers have already supported csp. And w3c has also made unified requirements for the whole. For details, please refer to w3c's official document Content Security Policy Level 2

Introduction

Content-Security-Policy is a response header field used by modern browsers to enhance document security. It is used to restrict the loading of resources such as js, css and other browsers. In other words, the essence of csp is a strategy for restricting resource loading. It restricts specific resources by parsing the instructions and values of csp. The specific implementation can be seen in the relevant implementation of chromium in the last part source code. In addition to adding csp to the header, the dom of html can also be restricted by meta tags, but when the resource commands and values restricted by the two are the same, the priority in the header is higher.

instruction

instructionVersionAnnotation
default-src1Most resources will read this configuration when they are not defined, a few will not, such as frame-ancestors, with low priority
script-src1Define effective js resources
style-src1Define effective css resources
img-src1Define effective image resources
connect-src1Load XMLHttpRequest, WebSocket, fetch, <a ping> and EventSource resources, if not allowed, return 400 status code
font-src1Define valid font resources and load them via @font-face
object-src1Define valid plug-in resources, such as: <object> , <embed> or <applet>
media-src1Define effective audio and video resources, such as: <audio> , <video> and other elements
frame-src1Define a valid frame to load resources. In csp2, frame-src is discarded and child-src is used; in csp3, it is enabled again, and it exists at the same time as child-src. If child-src does not exist, frame-src will also start effect
sandbox1The sandbox attribute of the iframe is allowed. The sandbox will adopt the same-origin policy to prevent pop-ups, plug-ins and scripts from executing. You can pass the allow-scripts, allow-popups, allow-modals, allow-orientation-lock, allow-pointer-lock, allow-presentation, allow-popups-to-escape-sandbox, allow-top-navigation to limit the sandbox field
report-uri1To send a failure report to this uri, you can also use Content-Security-Policy-Report-Only to send as an http header without blocking the analysis of network resources. In csp3, the report-uri is discarded, and the report-to command is used instead
child-src2Define web workers and resource loading containing nested contexts, such as <frame> and <iframe>
form-action2Define a valid html tag <form> action resource loading
frame-ancestors2Define valid embedded tags such as <frame> , <iframe> , <object> , <embd> , <applet> resource loading, when the value is'none', it is roughly equivalent to X-Frame-Options: DENY
plugin-types2Define the MIME resource type loading <object> and <embd> <applet> , the MIME must be specified as application/x-java-applet
base-uri2Define the URL resource load referenced by the src attribute in the html tag of <base>
report-to3Define the HTTP response header field of Report-To
worker-src3Restrict loading of URL resources through Worker, SharedWorker and ServiceWorker
manifest-src3Restrict url resource loading of manifests
prefetch-src3Define pre-rendering and pre-loading request resource loading, for example, through the rel="prefetch" or rel="prerender" attribute of the <link>
navigate-to3Restrict document redirection in any way, such as link redirection, or window.location is executed. If form-action is set, this rule will be replaced, that is, for form, form-action has a higher priority

value

valueVersiondescribeSample
*1Unknown, allow any URL resource load except data, blob, filesystem, schemesimg-src *
'none'1Do not allow any resources to be loadedobject-src 'none'
'self'1Only allow same source resources to loadscript-src 'self'
'data:'1Allow loading of resources in data format, such as Base64 image encodingimg-src 'self' data:
xx.xxx.com1Allow resource loading with a clear domain nameimg-src domain.example.com
*.xxx.com1Allow to load any resource under example.com subdomainimg-src *.example.com
https://xxx.com1Only allow resource loading of domain names under the https protocolimg-src https://cdn.com
https:1Allow loading of resources of any domain name under httpsimg-src https:
'unsafe-inline'1Allows the use of inline elements to load resources, such as: cascading styles, handle methods, script content tags, and javascript:URIs, etc.script-src 'unsafe-inline'
'unsafe-eval'1Allow insecure dynamic js code executionscript-src 'unsafe-eval'
'sha256-'2Allow inline script and css to execute after matching the hash valuescript-src 'sha256-xyz...'
'nonce-'2It is allowed to use inline script and css execution that contains the nonce attribute. The nonce should be a safe arbitrary value and cannot be reusedscript-src 'nonce-r@nd0m'
'strict-dynamic'3Allow loading of non-parsed script resources, such as: document.createElement('script')script-src 'strict-dynamic'
'unsafe-hashes'3It is allowed to use event handlers for resource loading, but it is not allowed to use inline scripts and javascript: execution methodsscript-src 'unsafe-hashes' 'sha256-abc...'

Case

Through the introduction of the previous part, we have a general understanding of some usages related to CSP. Let’s take a look at the specific practices in the front-end business.

nginx

图片

server {
    listen 9080;
    server_name localhost;
    add_header Content-Security-Policy "default-src 'self'; script-src 'self'; frame-ancestors 'self'; object-src 'none'";
    add_header X-Content-Type-Options nosniff;
    add_header X-Frame-Options SAMEORIGIN;
}

Let’s take a look at the strictly controlled situation in nginx. Let’s test it by creating a label under the v8 instance in the console.

图片

At this time we found that the browser reported

Refused to apply xxx because it violates the following Content Security Policy directive...

Error; At the same time, we opened the request connection in any network, we found that in the response header, appeared

图片

The field Content-Security-Policy: xxx as shown in the figure above

Then, according to the returned error, we release the appropriate csp restriction

server {
    listen 9080;
    server_name localhost;
    add_header Content-Security-Policy "default-src *; script-src * 'unsafe-inline' 'unsafe-eval'; img-src * data:;";
    add_header X-Content-Type-Options nosniff;
    add_header X-Frame-Options SAMEORIGIN;
}

After the modification, it was found that the previous error had disappeared, and the test was successful

html

Finally, let’s take a look at a use case of meta tags in html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta http-equiv="Content-Security-Policy" content="default-src *; script-src 'unsafe-inline' 'unsafe-eval'; img-src *;">
    <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
    <meta http-equiv="Pragma" content="no-cache" />
    <meta http-equiv="Expires" content="0" />
    <meta name="format-detection" content="telephone=no" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0" />
    <link rel="icon" href="<%= BASE_URL %>favicon.ico" />
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>
  <body>
    <noscript>
      <strong
        >We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without
        JavaScript enabled. Please enable it to continue.</strong
      >
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

In the case of not using nginx to configure csp, configuring meta in html can also play the same role, but when the two exist at the same time and the fields are the same, the response in the header will be parsed first

Source code

图片

For this part, let’s take a look at how CSP is implemented in chrome through the chromium source code.

content_security_policy_parsers

bool IsCSPDirectiveNameCharacter(UChar c) {
    return IsASCIIAlpanumeric(c) || c == '-';
}

bool IsCSPDirectiveValueCharacter(UChar c) {
    return IsASCIISpace(c) || (IsASCIIPrintable(c) && c != ',' && c != ';');
}

Obtain the instructions and values in Content-Security-Policy by parsing key-value values in the network

resource_fetcher

bool ResourceFetcher::ResourceNeedsLoad(Resource* resource, const FetchParameters& params, RevalidationPolicy policy) {
    if(archive_) 
        return false;
    
    if(resource->GetType() == ResourceType::kFont && !params.IsLinkPreload())
        return false;
    
    if(resource->GetType() == ResourceType::kImage && (ShouldDeferImageLoad(resource->Url()) || params.GetImageRequestBehavior() == FetchParameters::kDeferImageLoad)) {
        return false;
    }

    return policy != RevalidationPolicy::kUse || resource->StillNeedsLoad();
}

Judge whether to load resources

http_equiv

void HttpEquiv::ProcessHttpEquivContentSecurityPolicy(LocalDOMWindow* window, const AtomicString& equiv, const AtomicString& content) {
    if(!window || !window->GetFrame())
        return;
    if(window->GetFrame()->GetSettings()->GetBypassCSP())
        return;
    if(EqualIgnoringASCIICase(equiv, "content-security-policy")) {
        Vector<network::mojom::blink::ContentSecurityPolicyPtr> parsed = ParseContentSecurityPolicies(content, network::mojom::blink::ContentSecurityPolicyType::kEnforce, network::mojom::blink::ContentSecurityPolicySource::kMeta, *(window->GetSecurityOrigin()));
        window->GetContentSecurityPolicy()->AddPolicies(mojo::Clone(parsed));
        window->GetPolicyContainer()->AddContentSecurityPolicies(std::move(parsed));
    } else if (EqualIgnoringASCIICase(equiv, "content-security-policy-report-only")) {
        window->GetContentSecurityPolicy()->ReportReportOnlyInMeta(content);
    } else {
        NOTREACHED();
    }
}

We see some logic of executing related csp in Document

worker_content_settings_client

bool WorkerContentSettingsClient::AllowScriptFromSource(bool enabled_per_settings, const blink::WebURL& script_url) {
    bool allow = enabled_per_settings;
    if(allow && content_setting_rules_) {
        GURL top_frame_origin_url = top_frame_origin_.GetURL();
        for(const auto& rule: content_setting_rules_->script_rules) {
            if(rule.primary_pattern.Matches(top_frame_origin_url) && rule.secondary_pattern.Matches(script_url)) {
                allow = rule.GetContentSetting() != CONTENT_SETTING_BLOCK;
                break;
            }
        }
    }

    if(!allow) {
        EnsureContentSettingsManager();
        content_settings_manager_->OnContentBlocked(render_frame_id_, ContentSettingsType::JAVASCRIPT);
        return false;
    }

    return true;
}

Finally, we can briefly look at some logic of whether to allow loading of content, take script loading as an example

Summarize

图片

Regardless of whether it is the IT industry or not, as long as you are engineers, you need to pay attention to safety issues in engineering projects. For front-end engineering, common XSS, CSRF and other related knowledge also require us to explore principles in actual engineering projects. And be familiar with common solutions, so that the application engineering can be stable and sustainable in the process of architecture design and engineering practice. Finally, attach an ER diagram of the xss information in chrome to experience chrome Excellent and rigorous architecture design and information link control for security issues

refer to


维李设论
1.1k 声望4k 粉丝

专注大前端领域发展