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:
- Prevent attackers from submitting malicious code
- 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