preface

Web security has always been an unavoidable topic in the front-end field, but many front-end personnel only stay in the interview process of the relevant security policies of the Web, this paper is mainly on the online process of security problems encountered in the pit of a summary, in order to have a more three-dimensional personal experience of the Web security related problems. I also hope to provide you with some reference when stepping pits.

background

XSS vs CSRF

XSS

XSS is an abbreviation for Cross-site Scripting, to distinguish it from Cascading Style Sheets, and hence 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.

As can be seen from the definition given by MDN, XSS realizes the attack scheme by injecting harmful code, that is to say, the attack scheme of XSS is injection. Generally, the attack scheme of XSS is injection script. Since DOM and BOM provide interfaces for JS in the browser, JS can operate HTML and CSS. It can also insert HTML fragments and so on.

CSRF

Many people don’t know the difference between CSRF and CSRF, but they usually use XSS to get some permissions before CSRF. CSRF stands for Cross-site Request Forgery:

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

As can be seen from the DEFINITION of MDN, CSRF attacks through forgery, that is, its essential purpose is to use all means to disguise itself to obtain access to resources that do not belong to it

The difference between

The name of the purpose note
XSS Tampering with the content Don’t care about permissions
CSRF Access to resources All you care about is permissions

XSS classification

The name of the store Intrusive way scenario
Storage (persistent) Back-end database HTML Web sites with user-saved data, such as forum posts, product reviews, and user messages
Reflective (non-persistent) URL HTML Site search, jump
The DOM model Back-end database/front-end storage /URL js Front-end JS execution, such as writing eval, etc

XSS defense scheme

XSS prevention is divided into two main 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:

methods steps type
Leveraging the template engine 1 Storage type, reflection type
Restrict and escape input 1 Storage type, reflection type
Restrict js execution methods 2 The DOM model
Content Security Policy 1, 2, Storage, reflection, DOM

It can be seen from the above list that Content Security Policy has a good defense against XSS. Then, it is the key Content of this article. The next part will focus on cSP-related Content

CSP

Content Security Policy is an important part of modern browser Security mechanism. It can be seen from the figure that except the old IE only supports CSP sandbox, other mainstream browsers have already supported CSP, and W3C has also made unified requirements for the whole. For details, see the W3C’s Content Security Policy Level 2

Introduction to the

Content-security-policy is a response header field that modern browsers use to enforce document Security by limiting the loading of resources such as JS, CSS, and other browser-required resources. That is to say, the essence of CSP is a strategy to limit resource loading. It restricts specific resources by analyzing CSP instructions and values. Specific implementation can be seen in the chromium related implementation in the last part of the source code. In addition to adding CSP to the header, you can also use meta tags in the HTML DOM to restrict the resource. However, when the resource directives and values are the same, the priority of the header is higher.

instruction

instruction version annotation
default-src 1 Most resources read this configuration when they are not defined, but a few, such as frame-rooted, have a low priority
script-src 1 Define valid JS resources
style-src 1 Define valid CSS resources
img-src 1 Define valid image resources
connect-src 1 Load XMLHttpRequest, WebSocket, fetch,<a ping>
And the EventSource resource, which returns a 400 status code if not allowed
font-src 1 Define a valid font resource and load it with @font-face
object-src 1 Define valid plug-in resources, such as:<object>
.<embed>
or<applet>
media-src 1 Define effective audio and video resources such as:<audio>
.<video>
Elements such as
frame-src 1 Define a valid frame loading resource. In CSP2, frame-src is deprecated and child-src is used. In CSP3, it is enabled again, and exists at the same time as child-src. If child-src does not exist, frame-src also takes effect
sandbox 1 Sandbox allows the sandbox property of iframe. Sandbox uses the same origin policy to prevent pop-ups, plug-ins, and scripts from executing. Instead, allow-scripts, allow-popups, allow-modals, allow-orientation-lock, allow-pointer-lock, allow-presentation, allow-popups-to -escape-sandbox, allow-top-navigation specifies the sandbox field limits
report-uri 1 To send a failure Report to this URI, you can also use Content-security-policy-report-only as an HTTP header without blocking the resolution of network resources. In CSP3, the report-URI is deprecated and replaced with the report-to directive
child-src 2 Define Web workers and resource loads that contain nested contexts, such as<frame>
As well as<iframe>
form-action 2 Define valid HTML tags<form>
The action resource is loaded
frame-ancestors 2 Define valid inline tags such as<frame>
,<iframe>
,<object>
,<embd>
,<applet>
Resource loading, when ‘none’, can be roughly equivalent to x-frame-options: DENY
plugin-types 2 Defined by<object>
and<embd>
MIME resource type load for<applet>
The MIME must be application/ X-Java-applet
base-uri 2 Defined by<base>
Load the URL resource referenced by the SRC attribute in the HTML tag
report-to 3 Define the HTTP response header field for a report-to
worker-src 3 Restrict loading from Worker, SharedWorker, and ServiceWorker URL resources
manifest-src 3 Restrict SSE URL resource loading
prefetch-src 3 Define resource loads for prerendering and preloading requests, such as through<link>
The rel=”prefetch” or REL =” PRERender “attribute of the tag
navigate-to 3 This rule restricts document jumping to the URL in any way, such as via link, or window.location being executed. If form-action is set, this rule is replaced, i.e., for forms, form-action takes precedence

value

value version describe The sample
* 1 Unknown, allows any URL resource to load except data, blob, Filesystem, and Schemes img-src *
‘none’ 1 No resources are allowed to be loaded object-src ‘none’
‘self’ 1 Only same-origin resources can be loaded script-src ‘self’
‘data:’ 1 Allows data format resources to be loaded, such as Base64 image encoding img-src ‘self’ data:
xx.xxx.com 1 Allows resources to be loaded with specific domain names img-src domain.example.com
*.xxx.com 1 Allows loading of any resource under subdomain such as example.com img-src *.example.com
xxx.com 1 Only resources in HTTPS domain names can be loaded img-src cdn.com
https: 1 Allows to load resources from any domain name under HTTPS img-src https:
‘unsafe-inline’ 1 Allows you to load resources using inline elements, such as cascading styles, handle methods, script content tags, and javascript:URIs script-src ‘unsafe-inline’
‘unsafe-eval’ 1 Allows insecure dynamic JS code execution script-src ‘unsafe-eval’
‘sha256-‘ 2 Allows inline script and CSS to be executed after matching the hash value script-src ‘sha256-xyz… ‘
‘nonce-‘ 2 Inline script and CSS execution is allowed with the nonce attribute, which should be a safe, arbitrary value and should not be reused script-src ‘nonce-r@nd0m’
‘strict-dynamic’ 3 Allows non-parsing script resources to be loaded, such as document.createElement(‘script’) script-src ‘strict-dynamic’
‘unsafe-hashes’ 3 Event handles are allowed for resource loading, but inline scripts and javascript: execution are not allowed script-src ‘unsafe-hashes’ ‘sha256-abc… ‘

case

Through the introduction of the last part, we have a general understanding of the usage of CSP. Now let’s take a look at the specific practice 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;
}
Copy the code

Let’s take a look at all the tightly controlled situations in Nginx and test them by creating a tag in v8 on the Console

And then we see that the browser is reporting

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

The error; At the same time, we open the request connection in any network, and we find that, in the response header, it appears

Content-security-policy: XXX fields are shown above

Next, we release the CSP restrictions moderately based on the returned errors

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;
}
Copy the code

After the modification, the previous error disappeared and the test was successful

html

Finally, let’s look at one use of meta tags in HTML

<! DOCTYPEhtml>
<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>
Copy the code

In the case of CSP configuration without nginx, configuring meta in HTML can serve the same purpose, but when both exist and the fields are the same, the response in the header will be parsed first

The source code

This part we look at chrome through chromium source code is how to achieve CSP

content_security_policy_parsers

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

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

The commands and values in content-Security-policy are obtained 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;
    }

    returnpolicy ! = RevalidationPolicy::kUse || resource->StillNeedsLoad(a); }Copy the code

Check 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();
    }
}
Copy the code

We saw some logic for executing the relevant 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(a);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(a); content_settings_manager_->OnContentBlocked(render_frame_id_, ContentSettingsType::JAVASCRIPT);
        return false;
    }

    return true;
}
Copy the code

Finally, we can take a quick look at whether some of the logic for loading content is allowed, using script loading as an example

conclusion

No matter whether it industry or not, as long as engineers, they need to pay attention to safety issues in engineering projects. For front-end engineering, common XSS, CSRF and other related knowledge also need us to explore principles in actual engineering projects and be familiar with common solutions. In this way, the stability and sustainability of application engineering can be achieved in the process of architecture design and engineering practice. Finally, an ER diagram of XSS information in Chrome is attached to experience the excellence and rigor of chrome’s architecture design and information link control for security issues

reference

  • Cross-site scripting
  • Front-end Security Series 1: How do I Prevent XSS attacks?
  • Front-end Security Series ii: How to Prevent CSRF Attacks?
  • Definition and difference between XSS attack and CSRF attack
  • How to make the front end safer? XSS attack and defense details
  • Predict the SameSite property of cookies in a recent interview
  • Content-Security-Policy
  • Content security Policy (CSP) details
  • The CHROME extension notes rejection of unsafe-eval evaluation
  • CSP content security policy
  • Module ngx_http_headers_module
  • Content Security Policy Reference
  • Content Security Policy Level 2
  • Inside WebKit technology
  • How to land the front-end CSP & CSP