- The Guide to Finding and Reporting Web Vulnerabilities
- About the Author
- About the Tech Reviewer
- Foreword
- Introduction
- Who This Book Is For
- What Is In This Book
- Happy Hacking!
- 1 Picking a Bug Bounty Program
- 2 Sustaining Your Success
- 3 How the Internet Works
- 4 Environmental Setup and Traffic Interception
- 5 Web Hacking Reconnaissance
- 6 Cross-Site Scripting
- 7 Open Redirects
- 8 Clickjacking
- 9 Cross-Site Request Forgery
- 10 Insecure Direct Object References
- 11 SQL Injection
- 12 Race Conditions
- 13 Server-Side Request Forgery
- 14 Insecure Deserialization
- 15 XML External Entity
- 16 Template Injection
- 17 Application Logic Errors and Broken Access Control
- 18 Remote Code Execution
- 19 Same-Origin Policy Vulnerabilities
- 20 Single-Sign-On Security Issues
- 21 Information Disclosure
- 22 Conducting Code Reviews
- 23 Hacking Android Apps
- 24 API Hacking
- 25 Automatic Vulnerability Discovery Using Fuzzers
What Are APIs?
In simple terms, an API is a set of rules that allow one application to communicate with another. They enable applications to share data in a controlled way. Using APIs, applications on the internet can take advantage of other applications’ resources to build more complex features.
简单来说,API 是一组规则,允许一个应用程序与另一个应用程序进行通信。它们使应用程序以控制的方式共享数据。使用 API,互联网上的应用程序可以利用其他应用程序的资源来构建更复杂的功能。
For example, consider Twitter’s API ( https://developer.twitter.com/en/docs/twitter-api/ ). This public API allows outside developers to access Twitter’s data and actions. For example, if a developer wants their code to retrieve the contents of a tweet from Twitter’s database, they can use a Twitter API endpoint that returns tweet information by sending a GET request to the Twitter API server located at api.twitter.com :
例如,考虑 Twitter 的 API(https://developer.twitter.com/en/docs/twitter-api/)。这个公共 API 允许外部开发人员访问 Twitter 的数据和操作。例如,如果开发人员希望他们的代码从 Twitter 的数据库中检索一条推文的内容,他们可以使用 Twitter API 端点,通过向位于 api.twitter.com 的 Twitter API 服务器发送 GET 请求返回推文信息:
GET /1.1/statuses/show.json?id=210462857140252672
Host: api.twitter.com
This URL indicates that the developer is using Twitter’s API version 1.1 and requesting the resource called statuses
(which is what Twitter calls its tweets) with the ID 210462857140252672. The id
field in the URL is a request parameter required by the API endpoint. API endpoints often require certain parameters to determine which resource to return.
此 URL 表示开发者正在使用 Twitter API 版本 1.1 并请求名为 statuses 的资源 (这是 Twitter 称其推文的内容),并带有 ID 210462857140252672。URL 中的 id 字段是 API 连接点所需的请求参数。API 端点通常需要特定参数以确定要返回的资源。
Twitter’s API server would then return the data in JSON format to the requesting application (this example is taken from Twitter’s public API documentation):
Twitter 的 API 服务器将以 JSON 格式将数据返回给请求应用程序(此示例摘自 Twitter 的公共 API 文档):
1 {
2 "created_at": "Wed Oct 10 20:19:24 +0000 2018",
"id": 1050118621198921728,
"id_str": "1050118621198921728",
"text": "To make room for more expression, we will now count all emojis
as equal—including those with gender... and skin t... https://t.co/MkGjXf9aXm",
"truncated": true,
"entities": {
3 "hashtags": [],
"symbols": [],
"user_mentions": [],
"urls": [
{
"url": "https://t.co/MkGjXf9aXm",
"expanded_url": "https://twitter.com/i/web/status/1050118621198921728",
"display_url": "twitter.com/i/web/status/1...",
"indices": [
117,
140
]
}
]
},
4 "user": {
"id": 6253282,
"id_str": "6253282",
"name": "Twitter API",
"screen_name": "TwitterAPI",
"location": "San Francisco, CA",
"description": "The Real Twitter API. Tweets about API changes, service issues and our Developer Platform.
Don't get an answer? It's on my website.",
[...]
1 }
APIs usually return data in JSON or XML format. JSON is a way to represent data in plaintext, and it’s commonly used to transport data within web messages. You’ll often see JSON messages when you’re testing applications, so it’s helpful to learn how to read them.
API 通常以 JSON 或 XML 格式返回数据。JSON 是一种以纯文本形式表示数据的方式,常用于在 Web 消息中传输数据。在测试应用程序时,您经常会看到 JSON 消息,因此学习如何阅读它们很有帮助。
JSON objects start and end with a curly bracket 1 . Within these curly brackets, the properties of the represented object are stored in key-value pairs. For example, in the preceding data block representing a tweet, the created_at
property has the value Wed Oct 10 20:19:24 +0000 2018
. This indicates that the tweet was created on Wednesday, October 10, 2018 at 8:19 PM 2 .
JSON 对象以左右花括号开始和结束。在这些花括号内,表示对象的属性以键值对的形式存储。例如,在上面的推文数据块中,created_at 属性的值为 Wed Oct 10 20:19:24 +0000 2018。这表示推文创建于 2018 年 10 月 10 日星期三晚上 8:19。
JSON objects can also contain lists or other objects. Curly brackets denote objects. The preceding tweet contains a user
object indicating the user who created the tweet 4 . Lists are denoted with square brackets. Twitter returned an empty list of hashtags in the preceding JSON block, which means no hashtags were used in the tweet 3 .
JSON 对象还可以包含列表或其他对象。花括号表示对象。上一个推文包含一个用户对象,表示创建推文的用户。 4.列表用方括号表示。Twitter 在前面的 JSON 块中返回了一个空的 hashtag 列表,这意味着该推文中没有使用 hashtag。 3.
You might be wondering how the API server decides who can access data or execute actions. APIs often require users to authenticate before accessing their services. Typically, users include access tokens in their API requests to prove their identities. Other times, users are required to use special authentication headers or cookies. The server would then use the credentials presented in the request to determine which resources and actions the user should access.
API 服务器是如何决定谁可以访问数据或执行操作的,你可能会感到困惑。API 通常要求用户在访问其服务之前进行身份验证。通常,用户在 API 请求中包含访问令牌以证明其身份。其他情况下,用户需要使用特殊的身份验证头或 Cookie。服务器会利用请求中提供的凭据来确定用户应该访问哪些资源和操作。
REST APIs
There are multiple kinds of APIs. The Twitter API discussed here is called a Representational State Transfer ( REST ) API. REST is one of the most commonly used API structures. Most of the time, REST APIs return data in either JSON or plaintext format. REST API users send requests to specific resource endpoints to access that resource. In Twitter’s case, you send GET requests to https://api.twitter.com/1.1/statuses/show/ to retrieve tweet information, and GET requests to https://api.twitter.com/1.1/users/show/ to retrieve user information.
有多种类型的 API。在这里讨论的 Twitter API 被称为 Representational State Transfer(REST)API。REST 是最常用的 API 结构之一。大多数情况下,REST API 会以 JSON 或纯文本格式返回数据。REST API 用户发送请求到特定的资源端点来访问该资源。在 Twitter 的情况下,您发送 GET 请求到 https://api.twitter.com/1.1/statuses/show/以检索推文信息,并发送 GET 请求到 https://api.twitter.com/1.1/users/show/以检索用户信息。
REST APIs usually have defined structures for queries that make it easy for users to predict the specific endpoints to which they should send their requests. For example, to delete a tweet via the Twitter API, users can send a POST request to https://api.twitter.com/1.1/statuses/destroy/ , and to retweet a tweet, users can send a POST request to https://api.twitter.com/1.1/statuses/retweet/ . You can see here that all of Twitter’s API endpoints are structured in the same way ( https://api.twitter.com/1.1/RESOURCE/ACTION ):
REST API 通常具有定义良好的查询结构,使用户可以轻松预测应该将请求发送到哪些特定端点。例如,通过 Twitter API 删除推文,用户可以发送 POST 请求至 https://api.twitter.com/1.1/statuses/destroy/,而转发推文,则可以发送 POST 请求至 https://api.twitter.com/1.1/statuses/retweet/。可以看到,所有 Twitter 的 API 端点都以相同的方式结构化(https://api.twitter.com/1.1/RESOURCE/ACTION)。
https://api.twitter.com/1.1/users/show
https://api.twitter.com/1.1/statuses/show
https://api.twitter.com/1.1/statuses/destroy
https://api.twitter.com/1.1/statuses/retweet
REST APIs can also use various HTTP methods. For example, GET is usually used to retrieve resources, POST is used to update or create resources, PUT is used to update resources, and DELETE is used to delete them.
REST API 也可以使用不同的 HTTP 方法。例如,GET 通常用于检索资源,POST 用于更新或创建资源,PUT 用于更新资源,DELETE 用于删除它们。
SOAP APIs
SOAP is an API architecture that is less commonly used in modern applications. But plenty of older apps and IoT apps still use SOAP APIs. SOAP APIs use XML to transport data, and their messages have a header and a body. A simple SOAP request looks like this:
SOAP 是一种 API 架构,现代应用程序中不常用。但许多老应用程序和物联网应用程序仍然使用 SOAP API。SOAP API 使用 XML 来传输数据,它们的消息具有头和正文。一个简单的 SOAP 请求如下:
DELETE / HTTPS/1.1
Host: example.s3.amazonaws.com
<DeleteBucket xmlns="http://doc.s3.amazonaws.com/2006-03-01">
<Bucket>quotes</Bucket>
<AWSAccessKeyId> AKIAIOSFODNN7EXAMPLE</AWSAccessKeyId>
<Timestamp>2006-03-01T12:00:00.183Z</Timestamp>
<Signature>Iuyz3d3P0aTou39dzbqaEXAMPLE=</Signature>
</DeleteBucket>
This example request is taken from Amazon S3’s SOAP API documentation. It deletes an S3 bucket named quotes . As you can see, API request parameters are passed to the server as tags within the XML document.
此请求示例取自 Amazon S3 的 SOAP API 文档。它删除名为 quotes 的 S3 存储桶。正如您所看到的,API 请求参数以 XML 文档中的标签形式传递到服务器上。
The SOAP response looks like this:
SOAP 响应如下:
<DeleteBucketResponse xmlns="http://s3.amazonaws.com/doc/2006-03-01">
<DeleteBucketResponse>
<Code>204</Code>
<Description>No Content</Description>
</DeleteBucketResponse>
</DeleteBucketResponse>
This response indicates that the bucket is successfully deleted and no longer found.
该响应表示该存储桶已成功删除且不再存在。
SOAP APIs have a service called Web Services Description Language ( WSDL) , used to describe the structure of the API and how to access it. If you can find the WSDL of a SOAP API, you can use it to understand the API before hacking it. You can often find WSDL files by adding .wsdl or ?wsdl to the end of an API endpoint or searching for URL endpoints containing the term wsdl . In the WSDL, you will be able to find a list of API endpoints you can test.
SOAP APIs 有一个叫做 Web Services Description Language (WSDL) 的服务,用于描述 API 的结构和如何访问它。如果你能找到一个 SOAP API 的 WSDL,你可以在入侵前使用它来了解 API。你可以通过在 API 端点的末尾添加 .wsdl 或 ?wsdl,或者搜索包含 wsdl 术语的 URL 端点来找到 WSDL 文件。在 WSDL 中,你将能够找到你可以测试的 API 端点列表。
GraphQL APIs
GraphQL is a newer API technology that allows developers to request the precise resource fields they need, and to fetch multiple resources with just a single API call. GraphQL is becoming increasingly common because of these benefits.
GraphQL 是一种较新的 API 技术,能够让开发人员请求所需精确资源字段,并通过单个 API 调用获取多个资源。由于这些优势,GraphQL 正变得越来越普遍。
GraphQL APIs use a custom query language and a single endpoint for all the API’s functionality. These endpoints are commonly located at /graphql, /gql , or /g . GraphQL has two main kinds of operations: queries and mutations. Queries fetch data, just like the GET requests in REST APIs. Mutations create, update, and delete data, just like the POST, PUT, and DELETE requests in REST APIs.
GraphQL API 使用自定义查询语言和单个端点来实现所有 API 的功能。这些端点通常位于/graphql、/gql 或/g 处。GraphQL 有两种主要操作类型:查询和变更。查询获取数据,就像 REST API 中的 GET 请求一样。变更创建、更新和删除数据,就像 REST API 中的 POST、PUT 和 DELETE 请求一样。
As an example, take a look at the following API requests to Shopify’s GraphQL API. Shopify is an e-commerce platform that allows users to interact with their online stores via a GraphQL API. To access Shopify’s GraphQL API, developers need to send POST requests to the endpoint https://SHOPNAME.myshopify.com/admin/api/API_VERSION/graphql.json with the GraphQL query in the POST request body. To retrieve information about your shop, you can send this request:
例如,来看一下对 Shopify 的 GraphQL API 发送的以下 API 请求。Shopify 是一款电子商务平台,允许用户通过 GraphQL API 与他们的在线商店进行交互。开发人员需要向终端 https://SHOPNAME.myshopify.com/admin/api/API_VERSION/graphql.json 发送 POST 请求,并在 POST 请求正文中包含 GraphQL 查询才能访问 Shopify 的 GraphQL API。要检索有关您的商店的信息,您可以发送此请求:
query {
shop {
name
primaryDomain {
url
host
}
}
}
This GraphQL query indicates that we want to retrieve the name and primaryDomain
of the shop, and that we need only the primaryDomain
’s URL and host properties.
这个 GraphQL 查询表示我们想要检索店铺的名称和 primaryDomain,并且我们仅需要 primaryDomain 的 URL 和 host 属性。
Shopify’s server will return the requested information in JSON format:
Shopify 的服务器将以 JSON 格式返回请求的信息:
{
"data": {
"shop": {
"name": "example",
"primaryDomain": {
"url": "https://example.myshopify.com",
"host": "example.myshopify.com"
}
}
}
}
Notice that the response doesn’t contain all the object’s fields, but instead the exact fields the user has requested. Depending on your needs, you can request either more or fewer fields of the same data object. Here is an example that requests fewer:
请注意,响应并不包含所有对象的字段,而是用户请求的确切字段。根据您的需要,您可以请求相同数据对象的更多或更少的字段。这是一个请求更少字段的示例:
query {
shop {
name
}
}
You can also request the precise subfields of a resource’s properties and other nested properties. For example, here, you request only the URL of the primaryDomain
of a shop:
您还可以请求资源属性及其他嵌套属性的精确子域。例如,在此,您只请求店铺的 primaryDomain 的 URL:
query {
shop {
primaryDomain {
url
}
}
}
These queries are all used to retrieve data.
这些查询用于检索数据。
Mutations, used to edit data, can have arguments and return values. Let’s take a look at an example of a mutation taken from graphql.org . This mutation creates a new customer record and takes three input parameters: firstName
, lastName
, and email
. It then returns the ID of the newly created customer:
变异是用于编辑数据的,可以具有参数和返回值。让我们来看一下来自 graphql.org 的变异示例。这个变异创建一个新的客户记录,并接受三个输入参数:firstName、lastName 和 email。然后返回新创建的客户的 ID。
mutation {
customerCreate(
input: {
firstName: "John",
lastName: "Tate",
email: "john@johns-apparel.com" })
{
customer {
id
}
}
}
GraphQL’s unique syntax might make testing it hard at first, but once you understand it, you can test these APIs the same way that you test other types of APIs. To learn more about GraphQL’s syntax, visit https://graphql.org/ .
`GraphQL 的独特语法可能一开始让测试变得困难,但一旦你理解了它,你可以像测试其他类型的 API 一样测试这些 API。要了解有关 GraphQL 语法的更多信息,请访问 https://graphql.org/。`
GraphQL APIs also include a great reconnaissance tool for bug hunters: a feature called introspection that allows API users to ask a GraphQL system for information about itself. In other words, they’re queries that return information about how to use the API. For example, __schema
is a special field that will return all the types available in the API; the following query will return all the type names in the system. You can use it to find data types you can query for:
GraphQL API 还包括一个伟大的侦察工具,供漏洞猎人使用: 一种名为 introspection 的功能,允许 API 用户向 GraphQL 系统询问有关它自己的信息。换句话说,它们是返回有关如何使用 API 的信息的查询。例如,__schema 是一个特殊的字段,它将返回 API 中可用的所有类型;以下查询将返回系统中所有类型的名称。您可以使用它来查找可以查询的数据类型。
{
__schema {
types {
name
}
}
}
You can also use the __type
query to find the associated fields of a particular type:
你也可以使用 __type 查询来找到特定类型关联的字段:
{
__type(name: "customer") {
name
fields {
name
}
}
}
You will get the fields of a type returned like this. You can then use this information to query the API:
您将会得到该类型的字段返回信息,然后可以使用此信息查询 API:
{
"data": {
"__type": {
"name": "customer",
"fields": [
{
"name": "id",
},
{
"name": "firstName",
},
{
"name": "lastName",
},
{
"name": "email",
}
]
}
}
}
Introspection makes recon a breeze for the API hacker. To prevent malicious attackers from enumerating their APIs, many organizations disable introspection in their GraphQL APIs.
introspection 使得 API 黑客的侦查变得易如反掌。为了防止恶意攻击者枚举他们的 API,许多组织在他们的 GraphQL API 中禁用 introspection。
API-Centric Applications
Increasingly, APIs aren’t used as simply a mechanism to share data with outside developers. You’ll also encounter API-centric applications , or applications built using APIs. Instead of retrieving complete HTML documents from the server, API-centric apps consist of a client-side component that requests and renders data from the server by using API calls.
越来越多的情况是,API 不再仅仅被用作与外部开发者共享数据的机制。您也会遇到以 API 为中心的应用程序,或者使用 API 构建的应用程序。与从服务器检索完整 HTML 文档不同,以 API 为中心的应用程序包括一个客户端组件,通过使用 API 调用请求和呈现来自服务器的数据。
For example, when a user views Facebook posts, Facebook’s mobile application uses API calls to retrieve data about the posts from the server instead of retrieving entire HTML documents containing embedded data. The application then renders that data on the client side to form web pages.
例如,当用户查看 Facebook 的帖子时,Facebook 的移动应用程序使用 API 调用从服务器检索有关帖子的数据,而不是检索包含嵌入式数据的整个 HTML 文档。然后,应用程序在客户端端呈现该数据,以形成网页。
Many mobile applications are built this way. When a company already has a web app, using an API-centric approach to build mobile apps saves time. APIs allow developers to separate the app’s rendering and data-transporting tasks: developers can use API calls to transport data and then build a separate rendering mechanism for mobile, instead of reimplementing the same functionalities.
许多移动应用程序都是这样构建的。当公司已经拥有一个 Web 应用程序时,采用 API 中心化方法来构建移动应用程序可以节省时间。API 允许开发人员将应用程序的呈现和数据传输任务分离:开发人员可以使用 API 调用传输数据,然后为移动构建单独的呈现机制,而不是重新实现相同的功能。
Yet the rise of API-centric applications means that companies and applications expose more and more of their data and functionalities through APIs. APIs often leak sensitive data and the application logic of the hosting application. As you’ll see, this makes API bugs a widespread source of security breaches and a fruitful target for bug hunters.
然而,API 中心化应用的崛起意味着企业和应用通过 API 越来越多地暴露他们的数据和功能。API 经常泄露敏感数据和托管应用程序的应用程序逻辑。正如您将看到的,这使得 API 漏洞成为安全漏洞的普遍来源和漏洞猎人的有利目标。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论