{
"_args": [
[
{
"raw": "hawk@~6.0.2",
"scope": null,
"escapedName": "hawk",
"name": "hawk",
"rawSpec": "~6.0.2",
"spec": ">=6.0.2 <6.1.0",
"type": "range"
},
"/Volumes/2009-SSD/GT2/GT2-iOS/node_modules/request"
]
],
"_from": "hawk@>=6.0.2 <6.1.0",
"_id": "hawk@6.0.2",
"_inCache": true,
"_location": "/hawk",
"_nodeVersion": "8.1.4",
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/hawk-6.0.2.tgz_1500338423954_0.2481594004202634"
},
"_npmUser": {
"name": "hueniverse",
"email": "eran@hammer.io"
},
"_npmVersion": "5.3.0",
"_phantomChildren": {},
"_requested": {
"raw": "hawk@~6.0.2",
"scope": null,
"escapedName": "hawk",
"name": "hawk",
"rawSpec": "~6.0.2",
"spec": ">=6.0.2 <6.1.0",
"type": "range"
},
"_requiredBy": [
"/request"
],
"_resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz",
"_shasum": "af4d914eb065f9b5ce4d9d11c1cb2126eecc3038",
"_shrinkwrap": null,
"_spec": "hawk@~6.0.2",
"_where": "/Volumes/2009-SSD/GT2/GT2-iOS/node_modules/request",
"author": {
"name": "Eran Hammer",
"email": "eran@hammer.io",
"url": "http://hueniverse.com"
},
"babel": {
"presets": [
"es2015"
]
},
"browser": "dist/browser.js",
"bugs": {
"url": "https://github.com/hueniverse/hawk/issues"
},
"dependencies": {
"boom": "4.x.x",
"cryptiles": "3.x.x",
"hoek": "4.x.x",
"sntp": "2.x.x"
},
"description": "HTTP Hawk Authentication Scheme",
"devDependencies": {
"babel-cli": "^6.1.2",
"babel-preset-es2015": "^6.1.2",
"code": "4.x.x",
"lab": "14.x.x"
},
"directories": {},
"dist": {
"integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==",
"shasum": "af4d914eb065f9b5ce4d9d11c1cb2126eecc3038",
"tarball": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz"
},
"engines": {
"node": ">=4.5.0"
},
"gitHead": "d251edf711826e961ee6267d29a7fa50ff8cf9d0",
"homepage": "https://github.com/hueniverse/hawk#readme",
"keywords": [
"http",
"authentication",
"scheme",
"hawk"
],
"license": "BSD-3-Clause",
"main": "lib/index.js",
"maintainers": [
{
"name": "hueniverse",
"email": "eran@hueniverse.com"
}
],
"name": "hawk",
"optionalDependencies": {},
"readme": "![hawk Logo](https://raw.github.com/hueniverse/hawk/master/images/hawk.png)\n\n **Hawk** is an HTTP authentication scheme using a message authentication code (MAC) algorithm to provide partial\nHTTP request cryptographic verification. For more complex use cases such as access delegation, see [Oz](https://github.com/hueniverse/oz).\n\nCurrent version: **6.x**\n\nNote: 6.x, 5.x, 4.x, 3.x, and 2.x are the same exact protocol as 1.1. The version increments reflect changes in the node API.\n\n[![Build Status](https://travis-ci.org/hueniverse/hawk.svg?branch=master)](https://travis-ci.org/hueniverse/hawk)\n\n# Table of Content\n\n- [**Introduction**](#introduction)\n - [Replay Protection](#replay-protection)\n - [Usage Example](#usage-example)\n - [Protocol Example](#protocol-example)\n - [Payload Validation](#payload-validation)\n - [Response Payload Validation](#response-payload-validation)\n - [Browser Support and Considerations](#browser-support-and-considerations)\n- [**Single URI Authorization**](#single-uri-authorization)\n - [Usage Example](#bewit-usage-example)\n- [**Security Considerations**](#security-considerations)\n - [MAC Keys Transmission](#mac-keys-transmission)\n - [Confidentiality of Requests](#confidentiality-of-requests)\n - [Spoofing by Counterfeit Servers](#spoofing-by-counterfeit-servers)\n - [Plaintext Storage of Credentials](#plaintext-storage-of-credentials)\n - [Entropy of Keys](#entropy-of-keys)\n - [Coverage Limitations](#coverage-limitations)\n - [Future Time Manipulation](#future-time-manipulation)\n - [Client Clock Poisoning](#client-clock-poisoning)\n - [Bewit Limitations](#bewit-limitations)\n - [Host Header Forgery](#host-header-forgery)\n- [**Frequently Asked Questions**](#frequently-asked-questions)\n- [**Implementations**](#implementations)\n- [**Acknowledgements**](#acknowledgements)\n\n# Introduction\n\n**Hawk** is an HTTP authentication scheme providing mechanisms for making authenticated HTTP requests with\npartial cryptographic verification of the request and response, covering the HTTP method, request URI, host,\nand optionally the request payload.\n\nSimilar to the HTTP [Digest access authentication schemes](http://www.ietf.org/rfc/rfc2617.txt), **Hawk** uses a set of\nclient credentials which include an identifier (e.g. username) and key (e.g. password). Likewise, just as with the Digest scheme,\nthe key is never included in authenticated requests. Instead, it is used to calculate a request MAC value which is\nincluded in its place.\n\nHowever, **Hawk** has several differences from Digest. In particular, while both use a nonce to limit the possibility of\nreplay attacks, in **Hawk** the client generates the nonce and uses it in combination with a timestamp, leading to less\n\"chattiness\" (interaction with the server).\n\nAlso unlike Digest, this scheme is not intended to protect the key itself (the password in Digest) because\nthe client and server must both have access to the key material in the clear.\n\nThe primary design goals of this scheme are to:\n* simplify and improve HTTP authentication for services that are unwilling or unable to deploy TLS for all resources,\n* secure credentials against leakage (e.g., when the client uses some form of dynamic configuration to determine where\n to send an authenticated request), and\n* avoid the exposure of credentials sent to a malicious server over an unauthenticated secure channel due to client\n failure to validate the server's identity as part of its TLS handshake.\n\nIn addition, **Hawk** supports a method for granting third-parties temporary access to individual resources using\na query parameter called _bewit_ (in falconry, a leather strap used to attach a tracking device to the leg of a hawk).\n\nThe **Hawk** scheme requires the establishment of a shared symmetric key between the client and the server,\nwhich is beyond the scope of this module. Typically, the shared credentials are established via an initial\nTLS-protected phase or derived from some other shared confidential information available to both the client\nand the server.\n\n\n## Replay Protection\n\nWithout replay protection, an attacker can use a compromised (but otherwise valid and authenticated) request more\nthan once, gaining access to a protected resource. To mitigate this, clients include both a nonce and a timestamp when\nmaking requests. This gives the server enough information to prevent replay attacks.\n\nThe nonce is generated by the client, and is a string unique across all requests with the same timestamp and\nkey identifier combination.\n\nThe timestamp enables the server to restrict the validity period of the credentials where requests occurring afterwards\nare rejected. It also removes the need for the server to retain an unbounded number of nonce values for future checks.\nBy default, **Hawk** uses a time window of 1 minute to allow for time skew between the client and server (which in\npractice translates to a maximum of 2 minutes as the skew can be positive or negative).\n\nUsing a timestamp requires the client's clock to be in sync with the server's clock. **Hawk** requires both the client\nclock and the server clock to use NTP to ensure synchronization. However, given the limitations of some client types\n(e.g. browsers) to deploy NTP, the server provides the client with its current time (in seconds precision) in response\nto a bad timestamp.\n\nThere is no expectation that the client will adjust its system clock to match the server (in fact, this would be a\npotential attack vector). Instead, the client only uses the server's time to calculate an offset used only\nfor communications with that particular server. The protocol rewards clients with synchronized clocks by reducing\nthe number of round trips required to authenticate the first request.\n\n\n## Usage Example\n\nServer code:\n\n```javascript\nconst Http = require('http');\nconst Hawk = require('hawk');\n\n\n// Credentials lookup function\n\nconst credentialsFunc = function (id, callback) {\n\n const credentials = {\n key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',\n algorithm: 'sha256',\n user: 'Steve'\n };\n\n return callback(null, credentials);\n};\n\n// Create HTTP server\n\nconst handler = function (req, res) {\n\n // Authenticate incoming request\n\n Hawk.server.authenticate(req, credentialsFunc, {}, (err, credentials, artifacts) => {\n\n // Prepare response\n\n const payload = (!err ? `Hello ${credentials.user} ${artifacts.ext}` : 'Shoosh!');\n const headers = { 'Content-Type': 'text/plain' };\n\n // Generate Server-Authorization response header\n\n const header = Hawk.server.header(credentials, artifacts, { payload, contentType: headers['Content-Type'] });\n headers['Server-Authorization'] = header;\n\n // Send the response back\n\n res.writeHead(!err ? 200 : 401, headers);\n res.end(payload);\n });\n};\n\n// Start server\n\nHttp.createServer(handler).listen(8000, 'example.com');\n```\n\nClient code:\n\n```javascript\nconst Request = require('request');\nconst Hawk = require('hawk');\n\n\n// Client credentials\n\nconst credentials = {\n id: 'dh37fgj492je',\n key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',\n algorithm: 'sha256'\n}\n\n// Request options\n\nconst requestOptions = {\n uri: 'http://example.com:8000/resource/1?b=1&a=2',\n method: 'GET',\n headers: {}\n};\n\n// Generate Authorization request header\n\nconst header = Hawk.client.header('http://example.com:8000/resource/1?b=1&a=2', 'GET', { credentials: credentials, ext: 'some-app-data' });\nrequestOptions.headers.Authorization = header.field;\n\n// Send authenticated request\n\nRequest(requestOptions, function (error, response, body) {\n\n // Authenticate the server's response\n\n const isValid = Hawk.client.authenticate(response, credentials, header.artifacts, { payload: body });\n\n // Output results\n\n console.log(`${response.statusCode}: ${body}` + (isValid ? ' (valid)' : ' (invalid)'));\n});\n```\n\n**Hawk** utilized the [**SNTP**](https://github.com/hueniverse/sntp) module for time sync management. By default, the local\nmachine time is used. To automatically retrieve and synchronize the clock within the application, use the SNTP 'start()' method.\n\n```javascript\nHawk.sntp.start();\n```\n\n\n## Protocol Example\n\nThe client attempts to access a protected resource without authentication, sending the following HTTP request to\nthe resource server:\n\n```\nGET /resource/1?b=1&a=2 HTTP/1.1\nHost: example.com:8000\n```\n\nThe resource server returns an authentication challenge.\n\n```\nHTTP/1.1 401 Unauthorized\nWWW-Authenticate: Hawk\n```\n\nThe client has previously obtained a set of **Hawk** credentials for accessing resources on the \"`http://example.com/`\"\nserver. The **Hawk** credentials issued to the client include the following attributes:\n\n* Key identifier: `dh37fgj492je`\n* Key: `werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn`\n* Algorithm: `hmac sha256`\n* Hash: `6R4rV5iE+NPoym+WwjeHzjAGXUtLNIxmo1vpMofpLAE=`\n\nThe client generates the authentication header by calculating a timestamp (e.g. the number of seconds since January 1,\n1970 00:00:00 GMT), generating a nonce, and constructing the normalized request string (each value followed by a newline\ncharacter):\n\n```\nhawk.1.header\n1353832234\nj4h3g2\nGET\n/resource/1?b=1&a=2\nexample.com\n8000\n\nsome-app-ext-data\n\n```\n\nThe request MAC is calculated using HMAC with the specified hash algorithm \"`sha256`\" and the key over the normalized request string.\nThe result is base64-encoded to produce the request MAC:\n\n```\n6R4rV5iE+NPoym+WwjeHzjAGXUtLNIxmo1vpMofpLAE=\n```\n\nThe client includes the **Hawk** key identifier, timestamp, nonce, application specific data, and request MAC with the request using\nthe HTTP `Authorization` request header field:\n\n```\nGET /resource/1?b=1&a=2 HTTP/1.1\nHost: example.com:8000\nAuthorization: Hawk id=\"dh37fgj492je\", ts=\"1353832234\", nonce=\"j4h3g2\", ext=\"some-app-ext-data\", mac=\"6R4rV5iE+NPoym+WwjeHzjAGXUtLNIxmo1vpMofpLAE=\"\n```\n\nThe server validates the request by calculating the request MAC again based on the request received and verifies the validity\nand scope of the **Hawk** credentials. If valid, the server responds with the requested resource.\n\n\n### Payload Validation\n\n**Hawk** provides optional payload validation. When generating the authentication header, the client calculates a payload hash\nusing the specified hash algorithm. The hash is calculated over the concatenated value of (each followed by a newline character):\n* `hawk.1.payload`\n* the content-type in lowercase, without any parameters (e.g. `application/json`)\n* the request payload prior to any content encoding (the exact representation requirements should be specified by the server for payloads other than simple single-part ascii to ensure interoperability)\n\nFor example:\n\n* Payload: `Thank you for flying Hawk`\n* Content Type: `text/plain`\n* Algorithm: `sha256`\n* Hash: `Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=`\n\nResults in the following input to the payload hash function (newline terminated values):\n\n```\nhawk.1.payload\ntext/plain\nThank you for flying Hawk\n\n```\n\nWhich produces the following hash value:\n\n```\nYi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=\n```\n\nThe client constructs the normalized request string (newline terminated values):\n\n```\nhawk.1.header\n1353832234\nj4h3g2\nPOST\n/resource/1?a=1&b=2\nexample.com\n8000\nYi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=\nsome-app-ext-data\n\n```\n\nThen calculates the request MAC and includes the **Hawk** key identifier, timestamp, nonce, payload hash, application specific data,\nand request MAC, with the request using the HTTP `Authorization` request header field:\n\n```\nPOST /resource/1?a=1&b=2 HTTP/1.1\nHost: example.com:8000\nAuthorization: Hawk id=\"dh37fgj492je\", ts=\"1353832234\", nonce=\"j4h3g2\", hash=\"Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=\", ext=\"some-app-ext-data\", mac=\"aSe1DERmZuRl3pI36/9BdZmnErTw3sNzOOAUlfeKjVw=\"\n```\n\nIt is up to the server if and when it validates the payload for any given request, based solely on its security policy\nand the nature of the data included.\n\nIf the payload is available at the time of authentication, the server uses the hash value provided by the client to construct\nthe normalized string and validates the MAC. If the MAC is valid, the server calculates the payload hash and compares the value\nwith the provided payload hash in the header. In many cases, checking the MAC first is faster than calculating the payload hash.\n\nHowever, if the payload is not available at authentication time (e.g. too large to fit in memory, streamed elsewhere, or processed\nat a different stage in the application), the server may choose to defer payload validation for later by retaining the hash value\nprovided by the client after validating the MAC.\n\nIt is important to note that MAC validation does not mean the hash value provided by the client is valid, only that the value\nincluded in the header was not modified. Without calculating the payload hash on the server and comparing it to the value provided\nby the client, the payload may be modified by an attacker.\n\n\n## Response Payload Validation\n\n**Hawk** provides partial response payload validation. The server includes the `Server-Authorization` response header which enables the\nclient to authenticate the response and ensure it is talking to the right server. **Hawk** defines the HTTP `Server-Authorization` header\nas a response header using the exact same syntax as the `Authorization` request header field.\n\nThe header is constructed using the same process as the client's request header. The server uses the same credentials and other\nartifacts provided by the client to constructs the normalized request string. The `ext` and `hash` values are replaced with\nnew values based on the server response. The rest as identical to those used by the client.\n\nThe result MAC digest is included with the optional `hash` and `ext` values:\n\n```\nServer-Authorization: Hawk mac=\"XIJRsMl/4oL+nn+vKoeVZPdCHXB4yJkNnBbTbHFZUYE=\", hash=\"f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=\", ext=\"response-specific\"\n```\n\n\n## Browser Support and Considerations\n\nA browser script is provided for including using a `