The Beta endpoints for the new Email Activity APIs - functionality is subject to change without notice. You may not have access to this Beta endpoint. Email Activity offers filtering and search by event type for two days worth of data. There is an optional add-on to store 60 days worth of data. This add-on also gives you access to the ability to download a CSV of the 60 days worth of email event data. The Beta endpoints for the new Email Activity APIs - functionality is subject to change without notice. You may not have access to this Beta endpoint. Email Activity offers filtering and search by event type for two days worth of data. There is an optional add-on to store 60 days worth of data. This add-on also gives you access to the ability to download a CSV of the 60 days worth of email event data.
ShipEngine's easy-to-use REST API lets you manage all of your shipping needs without worrying about the complexities of different carrier APIs and protocols. We handle all the heavy lifting so you can focus on providing a first-class shipping experience for your customers at the best possible prices. Each of ShipEngine's features can be used by itself or in conjunction with each other to build powerful shipping functionality into your application or service. ## Getting Started If you're new to REST APIs then be sure to read our [introduction to REST](https://www.shipengine.com/docs/rest/) to understand the basics. Learn how to [authenticate yourself to ShipEngine](https://www.shipengine.com/docs/auth/), and then use our [sandbox environment](https://www.shipengine.com/docs/sandbox/) to kick the tires and get familiar with our API. If you run into any problems, then be sure to check the [error handling guide](https://www.shipengine.com/docs/errors/) for tips. Here are some step-by-step **tutorials** to get you started: - [Learn how to create your first shipping label](https://www.shipengine.com/docs/labels/create-a-label/) - [Calculate shipping costs and compare rates across carriers](https://www.shipengine.com/docs/rates/) - [Track packages on-demand or in real time](https://www.shipengine.com/docs/tracking/) - [Validate mailing addresses anywhere on Earth](https://www.shipengine.com/docs/addresses/validation/) ## Shipping Labels for Every Major Carrier ShipEngine makes it easy to [create shipping labels for any carrier](https://www.shipengine.com/docs/labels/create-a-label/) and [download them](https://www.shipengine.com/docs/labels/downloading/) in a [variety of file formats](https://www.shipengine.com/docs/labels/formats/). You can even customize labels with your own [messages](https://www.shipengine.com/docs/labels/messages/) and [images](https://www.shipengine.com/docs/labels/branding/). ## Real-Time Package Tracking With ShipEngine you can [get the current status of a package](https://www.shipengine.com/docs/tracking/) or [subscribe to real-time tracking updates](https://www.shipengine.com/docs/tracking/webhooks/) via webhooks. You can also create [custimized tracking pages](https://www.shipengine.com/docs/tracking/branded-tracking-page/) with your own branding so your customers will always know where their package is. ## Compare Shipping Costs Across Carriers Make sure you ship as cost-effectively as possible by [comparing rates across carriers](https://www.shipengine.com/docs/rates/get-shipment-rates/) using the ShipEngine Rates API. Or if you don't know the full shipment details yet, then you can [get rate estimates](https://www.shipengine.com/docs/rates/estimate/) with limited address info. ## Worldwide Address Validation ShipEngine supports [address validation](https://www.shipengine.com/docs/addresses/validation/) for virtually [every country on Earth](https://www.shipengine.com/docs/addresses/validation/countries/), including the United States, Canada, Great Britain, Australia, Germany, France, Norway, Spain, Sweden, Israel, Italy, and over 160 others.
# カラーミーショップアプリストア API
[アプリストア](https://app.shop-pro.jp/)にて公開するアプリに対して、一般公開している[カラーミーショップAPI](https://developer.shop-pro.jp/docs/colorme-api)に加えて、カラーミーショップアプリストアAPI(以下、アプリストアAPIといいます)を利用することが出来ます。アプリストアAPIでは以下のことが行えます。
- 課金データ(アプリ内課金、従量課金)の作成
- インラインスクリプトタグの取得・作成・更新・削除
- スクリプトタグの取得・作成・更新・削除
## 利用手順
アプリストアAPIを利用するには、OAuth認証が必要です。OAuth認証の基本的な流れについては[カラーミーショップAPIドキュメント](https://developer.shop-pro.jp/docs/colorme-api)を参照してください。
アプリストアAPIの利用のために、以下のscopeが追加で指定可能になります。[カラーミーショップAPIドキュメント](https://developer.shop-pro.jp/docs/colorme-api)に掲載されているscopeと合わせてご利用ください。
|スコープ|機能|
|---|---|
|`write_application_charge`|課金データの作成|
|`read_shop_script_tags`|ショップページのスクリプトタグを参照|
|`write_shop_script_tags`|ショップページへスクリプトタグを追加・更新|
|`read_inline_script_tags`|インラインスクリプトタグを参照|
|`write_inline_script_tags`|インラインスクリプトタグを追加・更新|
|`read_script_tags`|スクリプトタグを参照(deprecated)|
|`write_script_tags`|スクリプトタグを追加・更新(deprecated)|
(例) カラーミーショップアカウントの認証ページを表示
```
https://api.shop-pro.jp/oauth/authorize?client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&response_type=code&scope=read_products%20write_products%20write_application_charge
```
## 課金設定
料金プラン(月額課金・従量課金・買い切り)による課金や、アプリ内課金をご利用いただくにはアプリごとに課金設定の登録が必要です。
この設定は [カラーミーショップ デベロッパー](https://developer.shop-pro.jp) から行うことができます。
登録できる課金形式やその使い方の詳細については[アプリストア 開発ガイドのアプリ課金のページ](https://developer.shop-pro.jp/getting-started/appstore-billing/)をご覧ください
## アプリのインストール
ショップオーナーがアプリをインストールしたとき、以下の処理をカラーミーショップが行います。
- 選択された料金プランに基づき課金開始
- インストールフックの呼び出し
### インストールフック
アプリのインストール時に、インストールに関する情報を `POST` メソッド、 `application/json` 形式で通知します。
通知先のURLは[カラーミーショップ デベロッパー](https://developer.shop-pro.jp/)にログインし、各アプリストア アプリのアプリ設定から登録を行ってください。
以下のパラメータが送信されます。課金請求に必要なパラメータを含みますので、必ず受け取れるようにしてください。
|パラメータ|機能|形式|
|---|---|---|
|`account_id`|インストールしたショップオーナーのアカウントID|PA+8桁の整数|
|`application_charge_source_id`|プラン課金ID|数字と大文字アルファベットで構成される文字列(6桁以上)|
|`recurring_application_charge_id`|(買い切り以外の課金の場合)課金契約ID|数字と大文字アルファベットで構成される文字列(6桁以上)|
|`application_charge_id`|(買い切りの場合)課金契約ID|数字と大文字アルファベットで構成される文字列(6桁以上)|
|`trial_term`|(無料お試し期間がある場合)無料お試し期間|JSONオブジェクト|
|`mail`|ショップオーナーへの連絡メールアドレス|文字列|
`application_charge_source_id` はデベロッパーサイトで設定したプラン課金のIDです。インストールされた料金プランの判別にご利用いただけます。
`recurring_application_charge_id` と `application_charge_id` はインストールごとに発行されるユニークなIDです。ショップオーナーが一度アンインストールした後に、再度同じショップオーナーがアプリのインストールを行った際には新たに別のIDが発行されます。
`recurring_application_charge_id` は「買い切り」以外の課金である「無料」「月額」「月額+従量」「月額+初期費用」「従量のみ」のプラン課金のインストールの際に発行されます。
従量による課金を伴うプラン課金の場合は、従量分の料金を請求する際に 課金契約ID(`recurring_application_charge_id`) が必要になるので、必ず記録するようにしてください。
`mail` パラメータの値はショップオーナーへの連絡手段としてご利用いただけます。インストール後に認可フローが中断され、アクセストークンが得られない際のショップオーナーへの連絡手段としてご活用いただけます。このパラメータはカラーミーショップの非公開情報として登録されている値です。左記以外の用途でこの値をアプリの機能で使用しないでください。
例) 買い切りの場合
```
{
"account_id": "PA00000001",
"application_charge_source_id": "F3RN9A",
"application_charge_id": "A3FT4N",
"mail": "shop@example.com"
}
```
例) 月額課金の場合
```
{
"account_id": "PA00000001",
"application_charge_source_id": "F3RN9A",
"recurring_application_charge_id": "A3FT4N",
"mail": "shop@example.com"
}
```
無料お試し期間を設定した課金の場合、以下の情報を `trial_term` パラメータとして送信します。
無料お試し期間中は従量課金APIを呼び出して課金請求することはできません。
|パラメータ|機能|形式|
|---|---|---|
|`starts_at`|無料お試し開始日時|整数値(UNIXタイムスタンプ)|
|`ends_at`|無料お試し終了日時|整数値(UNIXタイムスタンプ)|
例) 無料お試し期間がある月額課金の場合
```
{
"account_id": "PA00000001",
"application_charge_source_id": "F3RN9A",
"recurring_application_charge_id": "A3FT4N",
"mail": "shop@example.com",
"trial_term" {
"starts_at": 1565017200,
"ends_at": 1567609200
}
}
```
受け取りに成功した場合は、以下のパラメータを `application/json` 形式でレスポンスボディに付与し、
ステータスコード `200` レスポンスをカラーミーショップへ返却してください。
ステータスコード `200` レスポンスをカラーミーショップが受け取れない場合、もしくは以下のパラメーターが返却されなかった場合、インストールを中止し、インストールによって発生した情報は破棄されます。
|パラメータ|機能|形式|
|---|---|---|
|`redirect_url`|インストール成功後に遷移するURL|文字列(URL)|
例)
```
{
"redirect_url": "https://example.com"
}
```
インストール完了後、インストールフックのレスポンスパラメータの `redirect_url` へ画面遷移しますので、APIを利用する場合は `redirect_url` より先の画面でOAuth認証の実装をお願いします。
## アプリのアンインストール
ショップオーナーがアプリをアンインストールしたとき、以下の処理をカラーミーショップが行います。
- OAuth認証のアクセストークンの無効化
- 登録したインラインスクリプトタグ・スクリプトタグの削除
- 月額課金形式の場合、継続課金の無効化
### アンインストールフック
アンインストール直後に `POST` メソッドで、以下の情報を `application/json` 形式で通知します。
通知先のURLは[カラーミーショップ デベロッパー](https://developer.shop-pro.jp/)にログインし、各アプリストア アプリのアプリ設定から登録を行ってください。
※ [アンインストールAPI](#operation/deleteInstallation)のご利用によるアンインストール時はアンインストールフックは通知されません。
受け取りに成功した場合はステータスコード `200` のレスポンスを返却してください。
|パラメータ|機能|形式|
|---|---|---|
|`account_id`|アンインストールしたショップオーナーのアカウントID|PA+8桁の整数|
|`application_charge_source_id`|プラン課金ID|数字と大文字アルファベットで構成される文字列(6桁以上)|
|`uninstalled_at`|アンインストール日時|整数値(UNIXタイムスタンプ)|
|`reason`|アンインストール理由| `by_shop_owner` (ショップオーナーによる)
`by_unpaid` (未払いによる) |
|`recurring_application_charge_id`|(買い切り以外の課金の場合)課金契約ID|数字と大文字アルファベットで構成される文字列(6桁以上)|
|`usage_charge`|(従量課金の場合)従量課金アンインストール情報|JSONオブジェクト|
アンインストールフックの通知が伴うアンインストールは以下の操作のいずれかによって行われます。アンインストールの理由を `reason` パラメータで確認できます。
|reasonパラメータの値|アンインストール理由|
|---|---|
|`by_shop_owner`|ショップオーナーによるアンインストール操作|
|`by_unpaid`|ポイント不足による利用料徴収の失敗による自動アンインストール|
課金契約ID `recurring_application_charge_id` はインストールフックで通知したIDと同じIDが通知されます。
料金プランが従量課金の場合、アンインストール後に従量課金データの作成を可能にするために、以下の情報を `usage_charge` パラメータとして送信します。
アンインストール後はOAuthのアクセストークンが無効化されているため、アクセストークンを利用して従量課金APIを呼び出すことができなくなります。
アンインストール後はアクセストークンの代わりに `api_token` をリクエストヘッダーに含め、従量課金APIを呼び出してください。
無料お試し期間中にアプリがアンインストールされた場合は、`api_token` は発行されません。
詳しくは、[従量課金データの作成](https://app.shop-pro.jp/open_api#operation/createUsageCharge)を参照してください。
`api_token` を利用した従量課金APIの呼び出しは、ポイント締め日 `closing_on` までとなっておりますので、ご注意ください。
|パラメータ|機能|形式|
|---|---|---|
|`api_token`|アンインストール後に従量課金APIを利用いただくために必要な情報|文字列|
|`closing_on`|ポイント締め日|整数値(UNIXタイムスタンプ)|
通常、 `closing_on` は、アンインストール直前まで利用されていた契約の期間の月末となります。以下に例を示します。
|アンインストール日|直前まで利用されていた契約の期間|closing_on の示す日時|
|---|---|---|
|2021/01/09|2021/12/10〜2021/01/09|2021/01/31|
|2021/01/10|2021/01/10〜2021/02/09|2021/02/28|
従量課金の場合のユーザーの契約期間については[こちら](https://shop-pro.jp/manual/appstore_fee)をご参照ください
アンインストールフックの例を以下に示します。
例) 買い切りの場合
```
{
"account_id": "PA00000001",
"application_charge_source_id": "Q21GPC",
"uninstalled_at": 1552022739,
"reason": "by_shop_owner"
}
```
例) 月額課金の場合
```
{
"account_id": "PA00000001",
"application_charge_source_id": "EW3V21",
"recurring_application_charge_id": "F3RN9A",
"uninstalled_at": 1552022740,
"reason": "by_shop_owner"
}
```
例) 従量課金を含む月額課金の場合
```
{
"account_id": "PA00000001",
"application_charge_source_id": "WA37CA",
"recurring_application_charge_id": "F3WQ1S",
"uninstalled_at": 1552022740,
"reason": "by_shop_owner",
"usage_charge": {
"api_token": "token",
"closing_on": 1552533465
}
}
```
### アンインストールフックのリトライ
ステータスコード `200` のレスポンスをカラーミーショップが受け取れない場合は、ステータスコード `200` をカラーミーショップが受け取るまで、以下の条件で再度アンインストール情報を送信します。
なお、カラーミーショップによるアンインストール処理は、アンインストールフックの送信結果の成否によらず、アンインストールが実行されたときに完了します。
- 2時間30分ごとにアンインストールフックの仕様に基づき再送します
- 最大で合計19回再送します
- すべての再送の試行でステータスコード `200` をカラーミーショップが受け取れない場合は、公認デベロッパー申請時に登録されたメールアドレス宛にメールを送信します
## インストール・アンインストールフックの署名検証
`X-Appstore-Signature` リクエストヘッダーに含まれる署名を検証して、リクエストがカラーミーショップから送信されたことを確認することを推奨します。
検証の手順は以下のとおりです。
1. カラーミーショップが発行した `webhook_secret` を秘密鍵として、HMAC-SHA256アルゴリズムを使用してリクエストボディのダイジェスト値を取得します。
2. ダイジェスト値をBase64エンコードした値とリクエストヘッダーに付与された署名( `X-Appstore-Signature` の値)が一致することを確認します。
サンプルコード(ruby)
```ruby
WEBHOOK_SECRET = 'my_webhook_secret'
payload_body = request.body.read
signature = Base64.strict_encode64(OpenSSL::HMAC.digest('sha256', WEBHOOK_SECRET, payload_body))
ActiveSupport::SecurityUtils.secure_compare(signature, request.env['HTTP_X_APPSTORE_SIGNATURE'])
```
### 発信元IPアドレスについて
発信元IPアドレスは固定ではありません。そのためIPアドレスが固定されていることを前提としてアプリケーションを開発しないでください。
インストールフックおよびアンインストールフックのリクエストの発信元を検証する場合は上記の署名検証を行なってください。
## Introduction The Shorten.rest API allows you to programmatically create short URLs (an 'alias') for longer URL (a 'destination'). Each alias you create can be used to redirect the end user (person clicking on the link) to one or more destination URLs A default destination is always set and specific destinations can be set to redirect the end user to preferred destinations based on the user's geographical location (country) and device Operating System. In order to use the Shorten.Rest URL Shortening API you can choose to bind your own branded domain, sub-domain or to use our default domain - Short.FYI ### Destination Matching When creating or editing a short URL ('alias') you can choose to specify a destination for each country and OS ([Supported OSes list](#tag/OperatingSystems)) combination. When a user clicks on the short link, Shorten.rest will examine the end user's country (determined by User's IP) and OS (User agent) and match the most suitable destination for each user. (*) If no destination is set for a specific request combination Shorten.rest will use the default destination that exists within each short URL (**) BRANDED DOMAINS: If the requested alias does not exist in our database - Shorten.rest will redirect the user to the default fallback you set within your dashboard under the ‘Alias Not Found Page Url’ value for a custom domain. (***) Operating System (OS) destinations are stronger than a country destination! For example - if you have a custom landing page that is targeting people in the USA and a second landing page that is hyper focused for people who use iOS devices - a person clicking on your link in the USA that is on an iPhone will be redirected to the iOS landing page, while all other devices will be redirected to the USA landing page. | OS | Country | Destination | | :------------: |:---------------:| -----| | iOS | | YourDestination.com/ios | | | US | YourDestination.com/usa | Shorten.rest will choose the YourDestination.com/ios url as the most suitable destination. ### Branded Domain Attributes When setting up your custom domain you can include optional metatags and snippets ([Supported snippets list](#tag/Snippets)). These parameters (such as retargeting, tracking and conversion pixels) are populated and fired on click - at the time of the redirect. By default the parameters you set in the domain setting will be included in all Short URLs associated with that domain. You can always override the domain defaults for each URL by passing the appropriate variables when creating or updating a short URL ### Setting a Custom string for an Alias (short.fyi/alias) While creating a short URL you can specify which domain to use. You can choose to use your own branded domain or our default domain - Short.fyi. Each Alias is unique within a domain they are related to. This means that if multiple accounts use you the same domain (for example short.fyi), if an alias is already taken you may not create a new destination for it. That said - If you would like to use a specific alias which is already taken - the only way to do so is to create it on a new domain you own and have attached to your Shorten.rest account. ### Random Aliases By default - unless you specify a vanity URI for your alias each URL that is shortened on our platform will have a random string generated by the API. This means that if the 'alias' attribute of a /aliases POST request is not provided, or is an empty string, a random string of seven characters will be generated and returned as part of the POST response. You can also place the @**rnd** macro within the alias field when you create a new alias, for example /vanity/@rnd, which might return an alias like /vanity/ZMAefRt, or /vanity@rnd, which might produce something like /vanityMRtvxadf. Only the first @rnd in an alias attribute will be replaced. ### NOTES ( * ) All methods of the Shorten.REST API require that your API key be provided in **x-api-key** header. (**) All API parameters are case sensitive
The Snyk API is available to customers on [Business and Enterprise plans](https://snyk.io/plans) and allows you to programatically integrate with Snyk.
## REST API
We are in the process of building a new, improved API (`https://api.snyk.io/rest`) built using the OpenAPI and JSON API standards. We welcome you to try it out as we shape and release endpoints until it, ultimately, becomes a full replacement for our current API.
Looking for our REST API docs? Please head over to [https://apidocs.snyk.io](https://apidocs.snyk.io)
## API vs CLI vs Snyk integration
The API detailed below has the ability to test a package for issues, as they are defined by Snyk. It is important to note that for many package managers, using this API will be less accurate than running the [Snyk CLI](https://snyk.io/docs/using-snyk) as part of your build pipe, or just using it locally on your package. The reason for this is that more than one package version fit the requirements given in manifest files. Running the CLI locally tests the actual deployed code, and has an accurate snapshot of the dependency versions in use, while the API can only infer it, with inferior accuracy. It should be noted that the Snyk CLI has the ability to output machine-readable JSON output (with the `--json` flag to `snyk test`).
A third option, is to allow Snyk access to your development flow via the existing [Snyk integrations](https://snyk.io/docs/). The advantage to this approach is having Snyk monitor every new pull request, and suggest fixes by opening new pull requests. This can be achieved either by integrating Snyk directly to your source code management (SCM) tool, or via a broker to allow greater security and auditability.
If those are not viable options, this API is your best choice.
## API url
The base URL for all API endpoints is https://api.snyk.io/api/v1/
## Authorization
To use this API, you must get your token from Snyk. It can be seen on https://snyk.io/account/ after you register with Snyk and login.
The token should be supplied in an `Authorization` header with the token, preceded by `token`:
```http
Authorization: token API_KEY
```
Otherwise, a 401 "Unauthorized" response will be returned.
```http
HTTP/1.1 401 Unauthorized
{
"code": 401,
"error": "Not authorised",
"message": "Not authorised"
}
```
## Overview and entities
The API is a REST API. It has the following entities:
### Test result
The test result is the object returned from the API giving the results of testing a package for issues. It has the following fields:
| Property | Type | Description | Example |
|----------------:|---------|-------------------------------------------------------|-----------------------------------------------------------------|
| ok | boolean | Does this package have one or more issues? | false |
| issues | object | The issues found. See below for details. | See below |
| dependencyCount | number | The number of dependencies the package has. | 9 |
| org | object | The organization this test was carried out for. | {"name": "anOrg", "id": "5d7013d9-2a57-4c89-993c-0304d960193c"} |
| licensesPolicy | object | The organization's licenses policy used for this test | See in the examples |
| packageManager | string | The package manager for this package | "maven" |
| | | | |
### Issue
An issue is either a vulnerability or a license issue, according to the organization's policy. It has the following fields:
| Property | Type | Description | Example |
|---------------:|---------------|----------------------------------------------------------------------------------------------------------------------------|----------------------------------------|
| id | string | The issue ID | "SNYK-JS-BACKBONE-10054" |
| url | string | A link to the issue details on snyk.io | "https://snyk.io/vuln/SNYK-JS-BACKBONE-10054 |
| title | string | The issue title | "Cross Site Scripting" |
| type | string | The issue type: "license" or "vulnerability". | "license" |
| paths | array | The paths to the dependencies which have an issue, and their corresponding upgrade path (if an upgrade is available). [More information about from and upgrade paths](#introduction/overview-and-entities/from-and-upgrade-paths) | [
{
"from": ["a@1.0.0", "b@4.8.1"],
"upgrade": [false, "b@4.8.2"]
}
] |
| package | string | The package identifier according to its package manager | "backbone", "org.apache.flex.blazeds:blazeds"|
| version | string | The package version this issue is applicable to. | "0.4.0" |
| severity | string | The Snyk defined severity level: "critical", "high", "medium" or "low". | "high" |
| language | string | The package's programming language | "js" |
| packageManager | string | The package manager | "npm" |
| semver | array[string] OR map[string]array[string] | One or more [semver](https://semver.org) ranges this issue is applicable to. The format varies according to package manager. | ["<0.5.0, >=0.4.0", "<0.3.8, >=0.3.6"] OR { "vulnerable": ["[2.0.0, 3.0.0)"], "unaffected": ["[1, 2)", "[3, )"] } |
### Vulnerability
A vulnerability in a package. In addition to all the fields present in an issue, a vulnerability also has these fields:
Property | Type | Description | Example |
----------------:|---------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------|
publicationTime | Date | The vulnerability publication time | "2016-02-11T07:16:18.857Z" |
disclosureTime | Date | The time this vulnerability was originally disclosed to the package maintainers | "2016-02-11T07:16:18.857Z" |
isUpgradable | boolean | Is this vulnerability fixable by upgrading a dependency? | true |
description | string | The detailed description of the vulnerability, why and how it is exploitable. Provided in markdown format. | "## Overview\n[`org.apache.logging.log4j:log4j-core`](http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22log4j-core%22)\nIn Apache Log4j 2.x before 2.8.2, when using the TCP socket server or UDP socket server to receive serialized log events from another application, a specially crafted binary payload can be sent that, when deserialized, can execute arbitrary code.\n\n# Details\nSerialization is a process of converting an object into a sequence of bytes which can be persisted to a disk or database or can be sent through streams. The reverse process of creating object from sequence of bytes is called deserialization. Serialization is commonly used for communication (sharing objects between multiple hosts) and persistence (store the object state in a file or a database). It is an integral part of popular protocols like _Remote Method Invocation (RMI)_, _Java Management Extension (JMX)_, _Java Messaging System (JMS)_, _Action Message Format (AMF)_, _Java Server Faces (JSF) ViewState_, etc.\n\n_Deserialization of untrusted data_ ([CWE-502](https://cwe.mitre.org/data/definitions/502.html)), is when the application deserializes untrusted data without sufficiently verifying that the resulting data will be valid, letting the attacker to control the state or the flow of the execution. \n\nJava deserialization issues have been known for years. However, interest in the issue intensified greatly in 2015, when classes that could be abused to achieve remote code execution were found in a [popular library (Apache Commons Collection)](https://snyk.io/vuln/SNYK-JAVA-COMMONSCOLLECTIONS-30078). These classes were used in zero-days affecting IBM WebSphere, Oracle WebLogic and many other products.\n\nAn attacker just needs to identify a piece of software that has both a vulnerable class on its path, and performs deserialization on untrusted data. Then all they need to do is send the payload into the deserializer, getting the command executed.\n\n> Developers put too much trust in Java Object Serialization. Some even de-serialize objects pre-authentication. When deserializing an Object in Java you typically cast it to an expected type, and therefore Java's strict type system will ensure you only get valid object trees. Unfortunately, by the time the type checking happens, platform code has already created and executed significant logic. So, before the final type is checked a lot of code is executed from the readObject() methods of various objects, all of which is out of the developer's control. By combining the readObject() methods of various classes which are available on the classpath of the vulnerable application an attacker can execute functions (including calling Runtime.exec() to execute local OS commands).\n- Apache Blog\n\n\n## References\n- [NVD](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2017-5645)\n- [jira issue](https://issues.apache.org/jira/browse/LOG4J2-1863)\n" |
isPatchable | boolean | Is this vulnerability fixable by using a Snyk supplied patch? | true |
isPinnable | boolean | Is this vulnerability fixable by pinning a transitive dependency | true |
identifiers | object | Additional vulnerability identifiers | {"CWE": [], "CVE": ["CVE-2016-2402]} |
credit | string | The reporter of the vulnerability | "Snyk Security Team" |
CVSSv3 | string | Common Vulnerability Scoring System (CVSS) provides a way to capture the principal characteristics of a vulnerability, and produce a numerical score reflecting its severity, as well as a textual representation of that score. | "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N" |
cvssScore | number | CVSS Score | 5.3 |
patches | array | Patches to fix this issue, by snyk | see "Patch" below. |
upgradePath | object | The path to upgrade this issue, if applicable | see below |
isPatched | boolean | Is this vulnerability patched? | false |
exploitMaturity | string | The snyk exploit maturity level
#### Patch
A patch is an object like this one:
```json
{
"urls": [
"https://snyk-patches.s3.amazonaws.com/npm/backbone/20110701/backbone_20110701_0_0_0cdc525961d3fa98e810ffae6bcc8e3838e36d93.patch"
],
"version": "<0.5.0 >=0.3.3",
"modificationTime": "2015-11-06T02:09:36.180Z",
"comments": [
"https://github.com/jashkenas/backbone/commit/0cdc525961d3fa98e810ffae6bcc8e3838e36d93.patch"
],
"id": "patch:npm:backbone:20110701:0"
}
```
### From and upgrade paths
Both from and upgrade paths are arrays, where each item within the array is a package `name@version`.
Take the following `from` path:
```
[
"my-project@1.0.0",
"actionpack@4.2.5",
"rack@1.6.4"
]
```
Assuming this was returned as a result of a test, then we know:
- The package that was tested was `my-project@1.0.0`
- The dependency with an issue was included in the tested package via the direct dependency `actionpack@4.2.5`
- The dependency with an issue was [rack@1.6.4](https://snyk.io/vuln/rubygems:rack@1.6.4)
Take the following `upgrade` path:
```
[
false,
"actionpack@5.0.0",
"rack@2.0.1"
]
```
Assuming this was returned as a result of a test, then we know:
- The package that was tested is not upgradable (`false`)
- The direct dependency `actionpack` should be upgraded to at least version `5.0.0` in order to fix the issue
- Upgrading `actionpack` to version `5.0.0` will cause `rack` to be installed at version `2.0.1`
If the `upgrade` path comes back as an empty array (`[]`) then this means that there is no upgrade path available which would fix the issue.
### License issue
A license issue has no additional fields other than the ones in "Issue".
### Snyk organization
The organization in Snyk this request is applicable to. The organization determines the access rights, licenses policy and is the unit of billing for private projects.
A Snyk organization has these fields:
Property | Type | Description | Example |
-----------:| ------ | ----------------------------- | -------------------------------------- |
name | string | The organization display name | "deelmaker" |
id | string | The ID of the organization | "3ab0f8d3-b17d-4953-ab6d-e1cbfe1df385" |
## Errors
This is a beta release of this API. Therefore, despite our efforts, errors might occur. In the unlikely event of such an error, it will have the following structure as JSON in the body:
Property | Type | Description | Example |
-----------:| ------ | ----------------------------- | -------------------------------------- |
message | string | Error message with reference | Error calling Snyk api (reference: 39db46b1-ad57-47e6-a87d-e34f6968030b) |
errorRef | V4 uuid | An error ref to contact Snyk with | 39db46b1-ad57-47e6-a87d-e34f6968030b |
The error reference will also be supplied in the `x-error-reference` header in the server reply.
Example response:
```http
HTTP/1.1 500 Internal Server Error
x-error-reference: a45ec9c1-065b-4f7b-baf8-dbd1552ffc9f
Content-Type: application/json; charset=utf-8
Content-Length: 1848
Vary: Accept-Encoding
Date: Sun, 10 Sep 2017 06:48:40 GMT
```
## Rate Limiting
To ensure resilience against increasing request rates, we are starting to introduce rate-limiting.
We are monitoring the rate-limiting system to ensure minimal impact on users while ensuring system stability.
Current limit is up to 2000 requests per minute, per user. This limit is above industry standards, and is subject to change. As such, we recommend calls to the API are throttled regardless of the current limit.
All requests above the limit will get a response with status code `429` - `Too many requests` until requests stop for the duration of the rate-limiting interval (currently a minute).
## Consuming Webhooks
Webhooks are delivered with a `Content-Type` of `application/json`, with the event payload as JSON in the request body. We also send the following headers:
- `X-Snyk-Event` - the name of the event
- `X-Snyk-Transport-ID` - a GUID to identify this delivery
- `X-Snyk-Timestamp` - an ISO 8601 timestamp for when the event occurred, for example: `2020-09-25T15:27:53Z`
- `X-Hub-Signature` - the HMAC hex digest of the request body, used to secure your webhooks and ensure the request did indeed come from Snyk
- `User-Agent` - identifies the origin of the request, for example: `Snyk-Webhooks/XXX`
---
After your server is configured to receive payloads, it listens for any payload sent to the endpoint you configured. For security reasons, you should limit requests to those coming from Snyk.
### Validating payloads
All transports sent to your webhooks have a `X-Hub-Signature` header, which contains the hash signature for the transport. The signature is a HMAC hexdigest of the request body, generated using sha256 and your `secret` as the HMAC key.
You could use a function in Node.JS such as the following to validate these signatures on incoming requests from Snyk:
```javascript
import * as crypto from 'crypto';
function verifySignature(request, secret) {
const hmac = crypto.createHmac('sha256', secret);
const buffer = JSON.stringify(request.body);
hmac.update(buffer, 'utf8');
const signature = `sha256=${hmac.digest('hex')}`;
return signature === request.headers['x-hub-signature'];
}
```
### Payload versioning
Payloads may evolve over time, and so are versioned. Payload versions are supplied as a suffix to the `X-Snyk-Event` header. For example, `project_snapshot/v0` indicates that the payload is `v0` of the `project_snapshot` event.
Version numbers only increment when a breaking change is made; for example, removing a field that used to exist, or changing the name of a field. Version numbers do not increment when making an additive change, such as adding a new field that never existed before.
**Note:** During the BETA phase, the structure of webhook payloads may change at any time, so we recommend you check the payload version.
### Event types
While consuming a webhook event, `X-Snyk-Event` header must be checked, as an end-point may receive multiple event types.
#### ping
The ping event happens after a new webhook is created, and can also be manually triggered using the ping webhook API. This is useful to test that your webhook receives data from Snyk correctly.
The `ping` event makes the following request:
```jsx
POST /webhook-handler/snyk123 HTTP/1.1
Host: my.app.com
X-Snyk-Event: ping/v0
X-Snyk-Transport-ID: 998fe884-18a0-45db-8ae0-e379eea3bc0a
X-Snyk-Timestamp: 2020-09-25T15:27:53Z
X-Hub-Signature: sha256=7d38cdd689735b008b3c702edd92eea23791c5f6
User-Agent: Snyk-Webhooks/044aadd
Content-Type: application/json
{
"webhookId": "d3cf26b3-2d77-497b-bce2-23b33cc15362"
}
```
#### project_snapshot
This event is triggered every time an existing project is tested and a new snapshot is created. It is triggered on every test of a project, whether or not there are new issues. This event is not triggered when a new project is created or imported. Currently supported targets/scan types are Open Source and container.
```jsx
POST /webhook-handler/snyk123 HTTP/1.1
Host: my.app.com
X-Snyk-Event: project_snapshot/v0
X-Snyk-Transport-ID: 998fe884-18a0-45db-8ae0-e379eea3bc0a
X-Snyk-Timestamp: 2020-09-25T15:27:53Z
X-Hub-Signature: sha256=7d38cdd689735b008b3c702edd92eea23791c5f6
User-Agent: Snyk-Webhooks/044aadd
Content-Type: application/json
{
"project": { ... }, // project object matching API responses
"org": { ... }, // organization object matching API responses
"group": { ... }, // group object matching API responses
"newIssues": [], // array of issues object matching API responses
"removedIssues": [], // array of issues object matching API responses
}
```
#### Detailed example of a payload
##### project
see: [https://snyk.docs.apiary.io/#reference/projects](https://snyk.docs.apiary.io/#reference/projects)
```tsx
"project": {
"name": "snyk/goof",
"id": "af137b96-6966-46c1-826b-2e79ac49bbd9",
"created": "2018-10-29T09:50:54.014Z",
"origin": "github",
"type": "maven",
"readOnly": false,
"testFrequency": "daily",
"totalDependencies": 42,
"issueCountsBySeverity": {
"low": 13,
"medium": 8,
"high": 4,
"critical": 5
},
"imageId": "sha256:caf27325b298a6730837023a8a342699c8b7b388b8d878966b064a1320043019",
"imageTag": "latest",
"imageBaseImage": "alpine:3",
"imagePlatform": "linux/arm64",
"imageCluster": "Production",
"hostname": null,
"remoteRepoUrl": "https://github.com/snyk/goof.git",
"lastTestedDate": "2019-02-05T08:54:07.704Z",
"browseUrl": "https://app.snyk.io/org/4a18d42f-0706-4ad0-b127-24078731fbed/project/af137b96-6966-46c1-826b-2e79ac49bbd9",
"importingUser": {
"id": "e713cf94-bb02-4ea0-89d9-613cce0caed2",
"name": "example-user@snyk.io",
"username": "exampleUser",
"email": "example-user@snyk.io"
},
"isMonitored": false,
"branch": null,
"targetReference": null,
"tags": [
{
"key": "example-tag-key",
"value": "example-tag-value"
}
],
"attributes": {
"criticality": [
"high"
],
"environment": [
"backend"
],
"lifecycle": [
"development"
]
},
"remediation": {
"upgrade": {},
"patch": {},
"pin": {}
}
}
```
##### org
see: [https://snyk.docs.apiary.io/#reference/organizations](https://snyk.docs.apiary.io/#reference/organizations)
```tsx
"org": {
"name": "My Org",
"id": "a04d9cbd-ae6e-44af-b573-0556b0ad4bd2",
"slug": "my-org",
"url": "https://api.snyk.io/org/my-org",
"created": "2020-11-18T10:39:00.983Z"
}
```
##### group
see: [https://snyk.docs.apiary.io/#reference/groups](https://snyk.docs.apiary.io/#reference/groups)
```tsx
"group": {
"name": "ACME Inc.",
"id": "a060a49f-636e-480f-9e14-38e773b2a97f"
}
```
##### issue
see: https://snyk.docs.apiary.io/#reference/users/user-organization-notification-settings/list-all-aggregated-issues
```tsx
{
"id": "npm:ms:20170412",
"issueType": "vuln",
"pkgName": "ms",
"pkgVersions": [
"1.0.0"
],
"issueData": {
"id": "npm:ms:20170412",
"title": "Regular Expression Denial of Service (ReDoS)",
"severity": "low",
"url": "https://snyk.io/vuln/npm:ms:20170412",
"description": "Lorem ipsum",
"identifiers": {
"CVE": [],
"CWE": [
"CWE-400"
],
"ALTERNATIVE": [
"SNYK-JS-MS-10509"
]
},
"credit": [
"Snyk Security Research Team"
],
"exploitMaturity": "no-known-exploit",
"semver": {
"vulnerable": [
">=0.7.1 <2.0.0"
]
},
"publicationTime": "2017-05-15T06:02:45Z",
"disclosureTime": "2017-04-11T21:00:00Z",
"CVSSv3": "CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L",
"cvssScore": 3.7,
"language": "js",
"patches": [
{
"id": "patch:npm:ms:20170412:2",
"urls": [
"https://snyk-patches.s3.amazonaws.com/npm/ms/20170412/ms_071.patch"
],
"version": "=0.7.1",
"comments": [],
"modificationTime": "2019-12-03T11:40:45.866206Z"
}
],
"nearestFixedInVersion": "2.0.0"
},
"isPatched": false,
"isIgnored": false,
"fixInfo": {
"isUpgradable": false,
"isPinnable": false,
"isPatchable": true,
"nearestFixedInVersion": "2.0.0"
},
"priority": {
"score": 399,
"factors": [
{
"name": "isFixable",
"description": "Has a fix available"
},
{
"name": "cvssScore",
"description": "CVSS 3.7"
}
]
}
}
```