返回介绍

Internet Security Controls

发布于 2024-10-11 20:33:54 字数 23412 浏览 0 评论 0 收藏 0

Now that you have a high-level understanding of how information is communicated over the internet, let’s dive into some fundamental security controls that protect it from attackers. To hunt for bugs effectively, you will often need to come up with creative ways to bypass these controls, so you’ll first need to understand how they work.

现在,您已经对互联网上如何传输信息有了高层次的理解,让我们深入了解一些基本的安全控制,以保护它免受攻击者的攻击。为了有效地搜寻漏洞,您通常需要想出创造性的方法来绕过这些控制,因此您首先需要了解它们是如何工作的。

Content Encoding

Data transferred in HTTP requests and responses isn’t always transmitted in the form of plain old text. Websites often encode their messages in different ways to prevent data corruption.

HTTP 请求和响应中传输的数据并非始终以纯文本形式传输。为了防止数据损坏,网站通常以不同的方式编码它们的消息。

Data encoding is used as a way to transfer binary data reliably across machines that have limited support for different content types. Characters used for encoding are common characters not used as controlled characters in internet protocols. So when you encode content using common encoding schemes, you can be confident that your data is going to arrive at its destination uncorrupted. In contrast, when you transfer your data in its original state, the data might be screwed up when internet protocols misinterpret special characters in the message.

数据编码用作一种可靠地在支持不同内容类型有限的机器之间传输二进制数据的方式。用于编码的字符是在互联网协议中不做控制字符使用的常见字符。因此,当您使用常见编码方案编码内容时,您可以确信数据将不会损坏地到达目的地。相比之下,当您以原始状态传输数据时,当互联网协议误解消息中的特殊字符时,数据可能会被损坏。

Base64 encoding is one of the most common ways of encoding data. It’s often used to transport images and encrypted information within web messages. This is the base64-encoded version of the string "Content Encoding" :

Base64 编码是编码数据最常用的方式之一。它经常用于在网络消息中传输图像和加密信息。这是字符串“Content Encoding”的 Base64 编码版本:

Q29udGVudCBFbmNvZGluZw==

Base64 encoding’s character set includes the uppercase alphabet characters A to Z, the lowercase alphabet characters a to z, the number characters 0 to 9, the characters + and /, and finally, the = character for padding. Base64url encoding is a modified version of base64 used for the URL format. It’s similar to base64, but uses different non-alphanumeric characters and omits padding.

Base64 编码的字符集包括大写字母 A 到 Z,小写字母 a 到 z,数字 0 到 9,字符+和/,最后,=字符用于填充。 Base64url 编码是用于 URL 格式的修改版本的 base64。它类似于 base64,但使用不同的非字母数字字符并省略填充。

Another popular encoding method is hex encoding. Hexadecimal encoding , or hex, is a way of representing characters in a base-16 format, where characters range from 0 to F. Hex encoding takes up more space and is less efficient than base64 but provides for a more human-readable encoded string. This is the hex-encoded version of the string "Content Encoding" ; you can see that it takes up more characters than its base64 counterpart:

另一种流行的编码方法是十六进制编码。十六进制编码(或简称为 hex)是一种将字符以基础 16 格式表示的方式,其中字符范围从 0 到 F。十六进制编码占用更多的空间,效率比 base64 低,但提供更易读的编码字符串。这是字符串“内容编码”的十六进制编码版本; 您可以看到它比其 base64 对应项占用更多的字符:

436f6e74656e7420456e636f64696e67

URL encoding is a way of converting characters into a format that is more easily transmitted over the internet. Each character in a URL-encoded string can be represented by its designated hex number preceded by a % symbol. See Wikipedia for more information about URL encoding: https://en.wikipedia.org/wiki/Percent-encoding .

URL 编码是将字符转换为更便于在互联网上传输的格式的一种方式。 URL 编码字符串中的每个字符都可以用其指定的十六进制数字表示,前面加上一个%符号。有关 URL 编码的更多信息,请参见维基百科:https://en.wikipedia.org/wiki/Percent-encoding。

For example, the word localhost can be represented with its URL-encoded equivalent, %6c%6f%63%61%6c%68%6f%73%74 . You can calculate a hostname’s URL-encoded equivalent by using a URL calculator like URL Decode and Encode ( https://www.urlencoder.org/ ).

例如,单词“localhost”可以用其 URL 编码的等效值“%6c%6f%63%61%6c%68%6f%73%74”表示。您可以使用 URL 计算器(如 URL 解码和编码器 https://www.urlencoder.org/)计算主机名的 URL 编码等效值。

We’ll cover a couple of additional types of character encoding—octal encoding and dword encoding—when we discuss SSRFs in Chapter 13 . When you see encoded content while investigating a site, always try to decode it to discover what the website is trying to communicate. You can use Burp Suite’s decoder to decode encoded content. We’ll cover how to do this in the next chapter. Alternatively, you can use CyberChef ( https://gchq.github.io/CyberChef/ ) to decode both base64 content and other types of encoded content.

在第 13 章讨论 SSRF 时,我们将介绍几种附加的字符编码方式——八进制编码和双字编码。在调查网站时,如果看到编码的内容,一定要尝试解码,以发现网站试图传达的信息。可以使用 Burp Suite 的解码器来解码编码的内容。我们将在下一章中讲解如何解码。另外,也可以使用 CyberChef(https://gchq.github.io/CyberChef/)来解码 base64 内容和其他类型的编码内容。

Servers sometimes also encrypt their content before transmission. This keeps the data private between the client and server and prevents anyone who intercepts the traffic from eavesdropping on the messages.

服务器有时会在传输之前对内容进行加密。这一举措可以保护客户端和服务器间的数据隐私,防止任何拦截流量的人窃听信息。

Session Management and HTTP Cookies

Why is it that you don’t have to re-log in every time you close your email tab? It’s because the website remembers your session. Session management is a process that allows the server to handle multiple requests from the same user without asking the user to log in again.

为什么关闭电子邮件选项卡后,您不必重新登录?这是因为该网站会记住您的会话。会话管理是一个过程,使服务器能够处理来自同一用户的多个请求,而无需要求用户再次登录。

Websites maintain a session for each logged-in user, and a new session starts when you log in to the website ( Figure 3-4 ). The server will assign an associated session ID for your browser that serves as proof of your identity. The session ID is usually a long and unpredictable sequence designed to be unguessable. When you log out, the server ends the session and revokes the session ID. The website might also end sessions periodically if you don’t manually log out.

网站为每个登录的用户维护一个会话,当您登录网站时开始一个新会话(图 3-4)。服务器会为您的浏览器分配一个关联的会话 ID,作为您身份的证明。会话 ID 通常是一个长而不可预测的序列,设计为难以猜测。当您登出时,服务器会结束会话并撤销会话 ID。如果您不手动退出,则网站可能会定期结束会话。

F03004

Figure 3-4 : After you log in, the server creates a session for you and issues a session ID, which uniquely identifies a session.

图 3-4: 登录后,服务器为您创建一个会话并发放一个会话 ID,该 ID 唯一标识一个会话。

Most websites use cookies to communicate session information in HTTP requests. HTTP cookies are small pieces of data that web servers send to your browser. When you log in to a site, the server creates a session for you and sends the session ID to your browser as a cookie. After receiving a cookie, your browser stores it and includes it in every request to the same server ( Figure 3-5 ).

大多数网站使用 Cookie 在 HTTP 请求中传递会话信息。HTTP Cookie 是 Web 服务器发送到浏览器的小数据片段。当您登录网站时,服务器会为您创建一个会话,并将会话 ID 作为 Cookie 发送到您的浏览器。收到 Cookie 后,您的浏览器会存储它,并在每次向同一服务器发送请求时包含它(图 3-5)。

That’s how the server knows it’s you! After the cookie for the session is generated, the server will track it and use it to validate your identity. Finally, when you log out, the server will invalidate the session cookie so that it cannot be used again. The next time you log in, the server will create a new session and a new associated session cookie for you.

那就是服务器知道你是谁的方式!生成会话 cookie 后,服务器将跟踪并使用它来验证你的身份。最后,当你退出时,服务器将使会话 cookie 无效,以防止它被再次使用。下次你登录时,服务器将为你创建一个新的会话和一个新的相关会话 cookie。

f03005

Figure 3-5 : Your session ID correlates with session information that is stored on the server.

图 3-5:您的会话 ID 与存储在服务器上的会话信息相关联。

Token-Based Authentication

In session-based authentication, the server stores your information and uses a corresponding session ID to validate your identity, whereas a token-based authentication system stores this info directly in some sort of token. Instead of storing your information server-side and querying it using a session ID, tokens allow servers to deduce your identity by decoding the token itself. This way, applications won’t have to store and maintain session information server-side.

在基于会话的身份验证中,服务器会存储您的信息并使用相应的会话 ID 来验证您的身份,而基于令牌的身份验证系统直接将此信息存储在某种令牌中。与使用会话 ID 在服务器端存储和查询您的信息不同,令牌允许服务器通过解码令牌本身来推断您的身份。这样,应用程序就不必在服务器端存储和维护会话信息了。

This system comes with a risk: if the server uses information contained in the token to determine the user’s identity, couldn’t users modify the information in the tokens and log in as someone else? To prevent token forgery attacks like these, some applications encrypt their tokens, or encode the token so that it can be read by only the application itself or other authorized parties. If the user can’t understand the contents of the token, they probably can’t tamper with it effectively either. Encrypting or encoding a token does not prevent token forgery completely. There are ways that an attacker can tamper with an encrypted token without understanding its contents. But it’s a lot more difficult than tampering with a plaintext token. Attackers can often decode encoded tokens to tamper with them.

该系统存在风险:如果服务器使用令牌中包含的信息来确定用户的身份,那么用户是否能够修改令牌中的信息并作为其他人登录?为了防止此类令牌伪造攻击,一些应用程序会加密其令牌或者将令牌编码,以便只有应用程序本身或其他授权方可以读取。如果用户无法理解令牌的内容,则很可能无法有效篡改它。加密或编码令牌并不能完全防止令牌伪造。攻击者有可能修改加密令牌的内容而不理解其内容,但这比篡改明文令牌要困难得多。攻击者经常可以对编码后的令牌进行解码,以便篡改它们。

Another more reliable way applications protect the integrity of a token is by signing the token and verifying the token signature when it arrives at the server. Signatures are used to verify the integrity of a piece of data. They are special strings that can be generated only if you know a secret key. Since there is no way of generating a valid signature without the secret key, and only the server knows what the secret key is, a valid signature suggests that the token is probably not altered by the client or any third party. Although the implementations by applications can vary, token-based authentication works like this:

应用程序保护令牌完整性的一种更可靠的方法是对令牌进行签名,并在其到达服务器时验证令牌签名。签名用于验证数据的完整性。它们是特殊的字符串,只有如果您知道秘密密钥才能生成。由于没有办法在不知道秘密密钥的情况下生成有效签名,而且只有服务器知道秘密密钥是什么,因此有效的签名表明令牌可能未被客户端或任何第三方更改。虽然应用程序的实现可能会有所不同,但基于令牌的身份验证的工作方式如下:

  1. The user logs in with their credentials.
  2. The server validates those credentials and provides the user with a signed token.
  3. The user sends the token with every request to prove their identity.
  4. Upon receiving and validating the token, the server reads the user’s identity information from the token and responds with confidential data.

JSON Web Tokens

The JSON Web Token ( JWT ) is one of the most commonly used types of authentication tokens. It has three components: a header, a payload, and a signature.

JSON Web Token(JWT)是最常用的身份验证令牌之一。它有三个组成部分:头部、负载和签名。

The header identifies the algorithm used to generate the signature. It’s a base64url-encoded string containing the algorithm name. Here’s what a JWT header looks like:

头部标识用于生成签名的算法。这是一个 base64url 编码的字符串,包含算法名称。以下是 JWT 头的样式:

eyBhbGcgOiBIUzI1NiwgdHlwIDogSldUIH0K

This string is the base64url-encoded version of this text:

这个字符串是这段文本的 base64url 编码版本:

{ "alg" : "HS256", "typ" : "JWT" }

The payload section contains information about the user’s identity. This section, too, is base64url encoded before being used in the token. Here’s an example of the payload section, which is the base64url-encoded string of { " user_name " : " admin ", } :

载荷部分包含有关用户身份的信息。在将该部分用于令牌之前,也会进行 base64url 编码。以下是载荷部分的示例,这是“{“user_name”:“admin”}”的 base64url 编码字符串:

eyB1c2VyX25hbWUgOiBhZG1pbiB9Cg

Finally, the signature section validates that the user hasn’t tampered with the token. It’s calculated by concatenating the header with the payload, then signing it with the algorithm specified in the header, and a secret key. Here’s what a JWT signature looks like:

最后,签名部分验证用户没有篡改令牌。它通过将头部与有效载荷串联起来,然后使用头部中指定的算法和秘钥进行签名来计算。以下是 JWT 签名的样式:

4Hb/6ibbViPOzq9SJflsNGPWSk6B8F6EqVrkNjpXh7M

For this specific token, the signature was generated by signing the string eyBhbGcgOiBIUzI1NiwgdHlwIDogSldUIH0K.eyB1c2VyX25hbWUgOiBhZG1pbiB9Cg with the HS256 algorithm using the secret key key . The complete token concatenates each section (the header, payload, and signature), separating them with a period ( . ):

该特定令牌的签名是使用 HS256 算法使用密钥 key 签名字符串 eyBhbGcgOiBIUzI1NiwgdHlwIDogSldUIH0K.eyB1c2VyX25hbWUgOiBhZG1pbiB9Cg 而生成的。完整的令牌将每个部分(标头,载荷和签名)连接起来,用句点(.)隔开:

eyBhbGcgOiBIUzI1NiwgdHlwIDogSldUIH0K.eyB1c2VyX25hbWUgOiBhZG1pbiB9Cg.4Hb/6ibbViPOzq9SJflsNGPWSk6B8F6EqVrkNjpXh7M

When implemented correctly, JSON web tokens provide a secure way to identify the user. When the token arrives at the server, the server can verify that the token has not been tampered with by checking that the signature is correct. Then the server can deduce the user’s identity by using the information contained in the payload section. And since the user does not have access to the secret key used to sign the token, they cannot alter the payload and sign the token themselves.

当 JSON Web Token 被正确实现时,它提供了一种安全的方式来识别用户。当令牌到达服务器时,服务器可以通过检查签名是否正确来验证令牌未被篡改。然后,服务器可以通过使用负载部分所包含的信息来推断用户的身份。由于用户无法访问用于签署令牌的秘钥,因此他们无法更改有效负载并签署令牌。

But if implemented incorrectly, there are ways that an attacker can bypass the security mechanism and forge arbitrary tokens.

但是,如果未正确实施,攻击者可以绕过安全机制并伪造任意令牌。

Manipulating the alg Field

Sometimes applications fail to verify a token’s signature after it arrives at the server. This allows an attacker to simply bypass the security mechanism by providing an invalid or blank signature.

有时,应用程序在接收到令牌后无法验证其签名。这使得攻击者可以通过提供无效或空白的签名来轻松绕过安全机制。

One way that attackers can forge their own tokens is by tampering with the alg field of the token header, which lists the algorithm used to encode the signature. If the application does not restrict the algorithm type used in the JWT, an attacker can specify which algorithm to use, which could compromise the security of the token.

攻击者可以通过篡改 token 头的"alg"字段来伪造自己的令牌。该字段列出用于编码签名的算法。如果应用程序不限制 JWT 中使用的算法类型,攻击者可以指定要使用的算法,从而危及令牌的安全性。

JWT supports a none option for the algorithm type. If the alg field is set to none , even tokens with empty signature sections would be considered valid. Consider, for example, the following token:

JWT 支持算法类型中的无选项。如果 alg 字段设置为 none,则即使签名部分为空的令牌也将被视为有效。例如,请考虑以下令牌:

eyAiYWxnIiA6ICJOb25lIiwgInR5cCIgOiAiSldUIiB9Cg.eyB1c2VyX25hbWUgOiBhZG1pbiB9Cg.

This token is simply the base64url-encoded versions of these two blobs, with no signature present:

这个令牌只是这两个 Blob 的 base64url 编码版本,没有签名。

{ "alg" : "none", "typ" : "JWT" } { "user" : "admin" }

This feature was originally used for debugging purposes, but if not turned off in a production environment, it would allow attackers to forge any token they want and impersonate anyone on the site.

该功能最初用于调试目的,但如果在生产环境中未关闭,则会允许攻击者伪造任何令牌并冒充站点上的任何人。

Another way attackers can exploit the alg field is by changing the type of algorithm used. The two most common types of signing algorithms used for JWTs are HMAC and RSA. HMAC requires the token to be signed with a key and then later verified with the same key. When using RSA, the token would first be created with a private key, then verified with the corresponding public key, which anyone can read. It is critical that the secret key for HMAC tokens and the private key for RSA tokens be kept a secret.

攻击者利用 alg 域的另一种方式是改变使用的算法类型。用于 JWT 的两种最常见的签名算法类型是 HMAC 和 RSA。HMAC 需要使用密钥对令牌进行签名,然后使用相同的密钥进行验证。在使用 RSA 时,令牌首先会使用私钥创建,然后使用对应的公钥进行验证,任何人都可以读取。重要的是,HMAC 令牌的密钥和 RSA 令牌的私钥必须保密。

Now let’s say that an application was originally designed to use RSA tokens. The tokens are signed with a private key A, which is kept a secret from the public. Then the tokens are verified with public key B, which is available to anyone. This is okay as long as the tokens are always treated as RSA tokens. Now if the attacker changes the alg field to HMAC, they might be able to create valid tokens by signing the forged tokens with the RSA public key, B. When the signing algorithm is switched to HMAC, the token is still verified with the RSA public key B, but this time, the token can be signed with the same public key too.

现在我们假设一个应用程序原本是设计用于使用 RSA 令牌。令牌使用私钥 A 进行签名,该私钥被保密不公开。然后使用公钥 B 进行令牌验证,而该公钥可供任何人使用。只要始终将令牌视为 RSA 令牌,这是可以的。现在,如果攻击者更改 alg 字段为 HMAC,则可能通过使用 RSA 公钥 B 对伪造令牌进行签名来创建有效令牌。当签名算法切换为 HMAC 时,令牌仍然使用 RSA 公钥 B 进行验证,但这次,令牌也可以使用相同的公钥进行签名。

Brute-Forcing the Key

It could also be possible to guess, or brute-force , the key used to sign a JWT. The attacker has a lot of information to start with: the algorithm used to sign the token, the payload that was signed, and the resulting signature. If the key used to sign the token is not complex enough, they might be able to brute-force it easily. If an attacker is not able to brute-force the key, they might try leaking the secret key instead. If another vulnerability, like a directory traversal, external entity attack (XXE), or SSRF exists that allows the attacker to read the file where the key value is stored, the attacker can steal the key and sign arbitrary tokens of their choosing. We’ll talk about these vulnerabilities in later chapters.

攻击者有可能通过猜测或暴力攻击密钥来签名 JWT。攻击者有很多信息可供参考:签名令牌使用的算法、已签名的有效负载以及签名结果。如果用于签名令牌的密钥不够复杂,他们可能很容易地进行暴力攻击。 如果攻击者无法暴力攻击密钥,他们可能会尝试泄露秘密密钥。 如果存在其他漏洞,例如目录遍历、外部实体攻击(XXE)或 SSRF,允许攻击者读取密钥值存储的文件,则攻击者可以窃取密钥并签名其选择的任意令牌。我们将在后面的章节中讨论这些漏洞。

Reading Sensitive Information

Since JSON web tokens are used for access control, they often contain information about the user. If the token is not encrypted, anyone can base64-decode the token and read the token’s payload. If the token contains sensitive information, it might become a source of information leaks. A properly implemented signature section of the JSON web token provides data integrity, not confidentiality.

由于 JSON Web 令牌用于访问控制,因此它们通常包含有关用户的信息。如果令牌未加密,则任何人都可以对其进行 base64 解码并读取其有效载荷。如果令牌包含敏感信息,则它可能成为信息泄漏的来源。JSON Web 令牌的正确实施的签名部分提供了数据完整性,而不是保密性。

These are just a few examples of JWT security issues. For more examples of JWT vulnerabilities, use the search term JWT security issues . The security of any authentication mechanism depends not only on its design, but also its implementation. JWTs can be secure, but only if implemented properly.

这些只是 JWT 安全问题的一些例子。如果想了解更多 JWT 漏洞的例子,请使用搜索词 JWT 安全问题。任何身份验证机制的安全性不仅取决于其设计,还取决于其实施。JWT 可以很安全,但前提是必须正确实施。

The Same-Origin Policy

The same-origin policy ( SOP) is a rule that restricts how a script from one origin can interact with the resources of a different origin. In one sentence, the SOP is this: a script from page A can access data from page B only if the pages are of the same origin. This rule protects modern web applications and prevents many common web vulnerabilities.

同源策略是一条规则,限制来自一个源的脚本与不同源的资源进行交互。简单来说,同源策略就是这样的:只有当页面 A 和 B 的源相同时,页面 A 的脚本才能访问页面 B 的数据。该规则保护现代 Web 应用程序,防止许多常见的 Web 漏洞。

Two URLs are said to have the same origin if they share the same protocol, hostname, and port number. Let’s look at some examples. Page A is at this URL:

如果两个 URL 共享相同的协议,主机名和端口号,则称它们具有相同的来源。让我们看一些示例。页面 A 在此 URL 上:

  1. https://medium.com/@vickieli

It uses HTTPS, which, remember, uses port 443 by default. Now look at the following pages to determine which has the same origin as page A, according to the SOP:

它使用 HTTPS,需要记住,默认使用 443 端口。现在查看以下页面,确定哪个页面与页面 A 拥有相同的来源,遵守 SOP。

  1. https://medium.com/
  2. http://medium.com/
  3. https://twitter.com/@vickieli7
  4. https://medium.com:8080/@vickieli

The https://medium.com/ URL is of the same origin as page A, because the two pages share the same origin, protocol, hostname, and port number. The other three pages do not share the same origin as page A. http://medium.com/ is of a different origin from page A, because their protocols differ. https://medium.com/ uses HTTPS, whereas http://medium.com/ uses HTTP. https://twitter.com/@vickieli7 is of a different origin as well, because it has a different hostname. Finally, https://medium.com:8080/@vickieli is of a different origin because it uses port 8080, instead of port 443.

`https://medium.com/` 和 `page A` 具有相同的源,因为它们共享相同的源、协议、主机名和端口号。其他三个页面与 `page A` 不共享相同的源。`http://medium.com/` 与 `page A` 来源不同,因为它们的协议不同。`https://medium.com/` 使用 HTTPS,而 `http://medium.com/` 使用 HTTP。`https://twitter.com/@vickieli7` 来源也不同,因为它有不同的主机名。最后,`https://medium.com:8080/@vickieli` 来源不同,因为它使用了 8080 端口,而不是 443 端口。

Now let’s consider an example to see how SOP protects us. Imagine that you’re logged in to your banking site at onlinebank.com . Unfortunately, you click on a malicious site, attacker.com , in the same browser.

现在让我们考虑一个例子,看看 SOP 如何保护我们。想象你正在 onlinebank.com 网站登录你的银行账户。不幸的是,你在同一个浏览器中点击了一个恶意网站 attacker.com。

The malicious site issues a GET request to onlinebank.com to retrieve your personal information. Since you’re logged into the bank, your browser automatically includes your cookies in every request you send to onlinebank.com , even if the request is generated by a script on a malicious site. Since the request contains a valid session ID, the server of onlinebank.com fulfills the request by sending the HTML page containing your info. The malicious script then reads and retrieves the private email addresses, home addresses, and banking information contained on the page.

恶意网站向 onlinebank.com 发出 GET 请求,以检索您的个人信息。由于您已登录银行,在您发送到 onlinebank.com 的每个请求中,您的浏览器会自动包含您的 Cookie,即使该请求是由恶意网站上的脚本生成的。由于请求包含有效的会话 ID,onlinebank.com 的服务器通过发送包含您信息的 HTML 页面来满足请求。恶意脚本然后读取和检索该页面上包含的私人电子邮件地址、家庭地址和银行信息。

Luckily, the SOP will prevent the malicious script hosted on attacker.com from reading the HTML data returned from onlinebank.com . This keeps the malicious script on page A from obtaining sensitive information embedded within page B.

幸运的是,SOP 可以防止攻击者.com 上托管的恶意脚本能阅读来自 onlinebank.com 的 HTML 数据,这可以保护页面 A 上的恶意脚本无法获得嵌入在页面 B 中的敏感信息。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文