package.json 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. {
  2. "_args": [
  3. [
  4. {
  5. "raw": "hawk@~3.1.3",
  6. "scope": null,
  7. "escapedName": "hawk",
  8. "name": "hawk",
  9. "rawSpec": "~3.1.3",
  10. "spec": ">=3.1.3 <3.2.0",
  11. "type": "range"
  12. },
  13. "/mnt/Data/bach/Documents/ola/OLA#4/OLA#4DOC/sys/node_modules/request"
  14. ]
  15. ],
  16. "_from": "hawk@>=3.1.3 <3.2.0",
  17. "_id": "hawk@3.1.3",
  18. "_inCache": true,
  19. "_location": "/hawk",
  20. "_nodeVersion": "5.4.1",
  21. "_npmUser": {
  22. "name": "hueniverse",
  23. "email": "eran@hammer.io"
  24. },
  25. "_npmVersion": "3.3.12",
  26. "_phantomChildren": {},
  27. "_requested": {
  28. "raw": "hawk@~3.1.3",
  29. "scope": null,
  30. "escapedName": "hawk",
  31. "name": "hawk",
  32. "rawSpec": "~3.1.3",
  33. "spec": ">=3.1.3 <3.2.0",
  34. "type": "range"
  35. },
  36. "_requiredBy": [
  37. "/request"
  38. ],
  39. "_resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
  40. "_shasum": "078444bd7c1640b0fe540d2c9b73d59678e8e1c4",
  41. "_shrinkwrap": null,
  42. "_spec": "hawk@~3.1.3",
  43. "_where": "/mnt/Data/bach/Documents/ola/OLA#4/OLA#4DOC/sys/node_modules/request",
  44. "author": {
  45. "name": "Eran Hammer",
  46. "email": "eran@hammer.io",
  47. "url": "http://hueniverse.com"
  48. },
  49. "browser": "./lib/browser.js",
  50. "bugs": {
  51. "url": "https://github.com/hueniverse/hawk/issues"
  52. },
  53. "contributors": [],
  54. "dependencies": {
  55. "boom": "2.x.x",
  56. "cryptiles": "2.x.x",
  57. "hoek": "2.x.x",
  58. "sntp": "1.x.x"
  59. },
  60. "description": "HTTP Hawk Authentication Scheme",
  61. "devDependencies": {
  62. "code": "1.x.x",
  63. "lab": "5.x.x"
  64. },
  65. "directories": {},
  66. "dist": {
  67. "shasum": "078444bd7c1640b0fe540d2c9b73d59678e8e1c4",
  68. "tarball": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz"
  69. },
  70. "engines": {
  71. "node": ">=0.10.32"
  72. },
  73. "gitHead": "2f0b93b34ed9b0ebc865838ef70c6a4035591430",
  74. "homepage": "https://github.com/hueniverse/hawk#readme",
  75. "keywords": [
  76. "http",
  77. "authentication",
  78. "scheme",
  79. "hawk"
  80. ],
  81. "license": "BSD-3-Clause",
  82. "main": "lib/index.js",
  83. "maintainers": [
  84. {
  85. "name": "hueniverse",
  86. "email": "eran@hueniverse.com"
  87. }
  88. ],
  89. "name": "hawk",
  90. "optionalDependencies": {},
  91. "readme": "![hawk Logo](https://raw.github.com/hueniverse/hawk/master/images/hawk.png)\r\n\r\n<img align=\"right\" src=\"https://raw.github.com/hueniverse/hawk/master/images/logo.png\" /> **Hawk** is an HTTP authentication scheme using a message authentication code (MAC) algorithm to provide partial\r\nHTTP request cryptographic verification. For more complex use cases such as access delegation, see [Oz](https://github.com/hueniverse/oz).\r\n\r\nCurrent version: **3.x**\r\n\r\nNote: 3.x and 2.x are the same exact protocol as 1.1. The version increments reflect changes in the node API.\r\n\r\n[![Build Status](https://secure.travis-ci.org/hueniverse/hawk.png)](http://travis-ci.org/hueniverse/hawk)\r\n\r\n# Table of Content\r\n\r\n- [**Introduction**](#introduction)\r\n - [Replay Protection](#replay-protection)\r\n - [Usage Example](#usage-example)\r\n - [Protocol Example](#protocol-example)\r\n - [Payload Validation](#payload-validation)\r\n - [Response Payload Validation](#response-payload-validation)\r\n - [Browser Support and Considerations](#browser-support-and-considerations)\r\n<p></p>\r\n- [**Single URI Authorization**](#single-uri-authorization)\r\n - [Usage Example](#bewit-usage-example)\r\n<p></p>\r\n- [**Security Considerations**](#security-considerations)\r\n - [MAC Keys Transmission](#mac-keys-transmission)\r\n - [Confidentiality of Requests](#confidentiality-of-requests)\r\n - [Spoofing by Counterfeit Servers](#spoofing-by-counterfeit-servers)\r\n - [Plaintext Storage of Credentials](#plaintext-storage-of-credentials)\r\n - [Entropy of Keys](#entropy-of-keys)\r\n - [Coverage Limitations](#coverage-limitations)\r\n - [Future Time Manipulation](#future-time-manipulation)\r\n - [Client Clock Poisoning](#client-clock-poisoning)\r\n - [Bewit Limitations](#bewit-limitations)\r\n - [Host Header Forgery](#host-header-forgery)\r\n<p></p>\r\n- [**Frequently Asked Questions**](#frequently-asked-questions)\r\n<p></p>\r\n- [**Implementations**](#implementations)\r\n- [**Acknowledgements**](#acknowledgements)\r\n\r\n# Introduction\r\n\r\n**Hawk** is an HTTP authentication scheme providing mechanisms for making authenticated HTTP requests with\r\npartial cryptographic verification of the request and response, covering the HTTP method, request URI, host,\r\nand optionally the request payload.\r\n\r\nSimilar to the HTTP [Digest access authentication schemes](http://www.ietf.org/rfc/rfc2617.txt), **Hawk** uses a set of\r\nclient credentials which include an identifier (e.g. username) and key (e.g. password). Likewise, just as with the Digest scheme,\r\nthe key is never included in authenticated requests. Instead, it is used to calculate a request MAC value which is\r\nincluded in its place.\r\n\r\nHowever, **Hawk** has several differences from Digest. In particular, while both use a nonce to limit the possibility of\r\nreplay attacks, in **Hawk** the client generates the nonce and uses it in combination with a timestamp, leading to less\r\n\"chattiness\" (interaction with the server).\r\n\r\nAlso unlike Digest, this scheme is not intended to protect the key itself (the password in Digest) because\r\nthe client and server must both have access to the key material in the clear.\r\n\r\nThe primary design goals of this scheme are to:\r\n* simplify and improve HTTP authentication for services that are unwilling or unable to deploy TLS for all resources,\r\n* secure credentials against leakage (e.g., when the client uses some form of dynamic configuration to determine where\r\n to send an authenticated request), and\r\n* avoid the exposure of credentials sent to a malicious server over an unauthenticated secure channel due to client\r\n failure to validate the server's identity as part of its TLS handshake.\r\n\r\nIn addition, **Hawk** supports a method for granting third-parties temporary access to individual resources using\r\na query parameter called _bewit_ (in falconry, a leather strap used to attach a tracking device to the leg of a hawk).\r\n\r\nThe **Hawk** scheme requires the establishment of a shared symmetric key between the client and the server,\r\nwhich is beyond the scope of this module. Typically, the shared credentials are established via an initial\r\nTLS-protected phase or derived from some other shared confidential information available to both the client\r\nand the server.\r\n\r\n\r\n## Replay Protection\r\n\r\nWithout replay protection, an attacker can use a compromised (but otherwise valid and authenticated) request more \r\nthan once, gaining access to a protected resource. To mitigate this, clients include both a nonce and a timestamp when \r\nmaking requests. This gives the server enough information to prevent replay attacks.\r\n\r\nThe nonce is generated by the client, and is a string unique across all requests with the same timestamp and\r\nkey identifier combination. \r\n\r\nThe timestamp enables the server to restrict the validity period of the credentials where requests occuring afterwards\r\nare rejected. It also removes the need for the server to retain an unbounded number of nonce values for future checks.\r\nBy default, **Hawk** uses a time window of 1 minute to allow for time skew between the client and server (which in\r\npractice translates to a maximum of 2 minutes as the skew can be positive or negative).\r\n\r\nUsing a timestamp requires the client's clock to be in sync with the server's clock. **Hawk** requires both the client\r\nclock and the server clock to use NTP to ensure synchronization. However, given the limitations of some client types\r\n(e.g. browsers) to deploy NTP, the server provides the client with its current time (in seconds precision) in response\r\nto a bad timestamp.\r\n\r\nThere is no expectation that the client will adjust its system clock to match the server (in fact, this would be a\r\npotential attack vector). Instead, the client only uses the server's time to calculate an offset used only\r\nfor communications with that particular server. The protocol rewards clients with synchronized clocks by reducing\r\nthe number of round trips required to authenticate the first request.\r\n\r\n\r\n## Usage Example\r\n\r\nServer code:\r\n\r\n```javascript\r\nvar Http = require('http');\r\nvar Hawk = require('hawk');\r\n\r\n\r\n// Credentials lookup function\r\n\r\nvar credentialsFunc = function (id, callback) {\r\n\r\n var credentials = {\r\n key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',\r\n algorithm: 'sha256',\r\n user: 'Steve'\r\n };\r\n\r\n return callback(null, credentials);\r\n};\r\n\r\n// Create HTTP server\r\n\r\nvar handler = function (req, res) {\r\n\r\n // Authenticate incoming request\r\n\r\n Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {\r\n\r\n // Prepare response\r\n\r\n var payload = (!err ? 'Hello ' + credentials.user + ' ' + artifacts.ext : 'Shoosh!');\r\n var headers = { 'Content-Type': 'text/plain' };\r\n\r\n // Generate Server-Authorization response header\r\n\r\n var header = Hawk.server.header(credentials, artifacts, { payload: payload, contentType: headers['Content-Type'] });\r\n headers['Server-Authorization'] = header;\r\n\r\n // Send the response back\r\n\r\n res.writeHead(!err ? 200 : 401, headers);\r\n res.end(payload);\r\n });\r\n};\r\n\r\n// Start server\r\n\r\nHttp.createServer(handler).listen(8000, 'example.com');\r\n```\r\n\r\nClient code:\r\n\r\n```javascript\r\nvar Request = require('request');\r\nvar Hawk = require('hawk');\r\n\r\n\r\n// Client credentials\r\n\r\nvar credentials = {\r\n id: 'dh37fgj492je',\r\n key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',\r\n algorithm: 'sha256'\r\n}\r\n\r\n// Request options\r\n\r\nvar requestOptions = {\r\n uri: 'http://example.com:8000/resource/1?b=1&a=2',\r\n method: 'GET',\r\n headers: {}\r\n};\r\n\r\n// Generate Authorization request header\r\n\r\nvar header = Hawk.client.header('http://example.com:8000/resource/1?b=1&a=2', 'GET', { credentials: credentials, ext: 'some-app-data' });\r\nrequestOptions.headers.Authorization = header.field;\r\n\r\n// Send authenticated request\r\n\r\nRequest(requestOptions, function (error, response, body) {\r\n\r\n // Authenticate the server's response\r\n\r\n var isValid = Hawk.client.authenticate(response, credentials, header.artifacts, { payload: body });\r\n\r\n // Output results\r\n\r\n console.log(response.statusCode + ': ' + body + (isValid ? ' (valid)' : ' (invalid)'));\r\n});\r\n```\r\n\r\n**Hawk** utilized the [**SNTP**](https://github.com/hueniverse/sntp) module for time sync management. By default, the local\r\nmachine time is used. To automatically retrieve and synchronice the clock within the application, use the SNTP 'start()' method.\r\n\r\n```javascript\r\nHawk.sntp.start();\r\n```\r\n\r\n\r\n## Protocol Example\r\n\r\nThe client attempts to access a protected resource without authentication, sending the following HTTP request to\r\nthe resource server:\r\n\r\n```\r\nGET /resource/1?b=1&a=2 HTTP/1.1\r\nHost: example.com:8000\r\n```\r\n\r\nThe resource server returns an authentication challenge.\r\n\r\n```\r\nHTTP/1.1 401 Unauthorized\r\nWWW-Authenticate: Hawk\r\n```\r\n\r\nThe client has previously obtained a set of **Hawk** credentials for accessing resources on the \"http://example.com/\"\r\nserver. The **Hawk** credentials issued to the client include the following attributes:\r\n\r\n* Key identifier: dh37fgj492je\r\n* Key: werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn\r\n* Algorithm: sha256\r\n\r\nThe client generates the authentication header by calculating a timestamp (e.g. the number of seconds since January 1,\r\n1970 00:00:00 GMT), generating a nonce, and constructing the normalized request string (each value followed by a newline\r\ncharacter):\r\n\r\n```\r\nhawk.1.header\r\n1353832234\r\nj4h3g2\r\nGET\r\n/resource/1?b=1&a=2\r\nexample.com\r\n8000\r\n\r\nsome-app-ext-data\r\n\r\n```\r\n\r\nThe request MAC is calculated using HMAC with the specified hash algorithm \"sha256\" and the key over the normalized request string.\r\nThe result is base64-encoded to produce the request MAC:\r\n\r\n```\r\n6R4rV5iE+NPoym+WwjeHzjAGXUtLNIxmo1vpMofpLAE=\r\n```\r\n\r\nThe client includes the **Hawk** key identifier, timestamp, nonce, application specific data, and request MAC with the request using\r\nthe HTTP `Authorization` request header field:\r\n\r\n```\r\nGET /resource/1?b=1&a=2 HTTP/1.1\r\nHost: example.com:8000\r\nAuthorization: Hawk id=\"dh37fgj492je\", ts=\"1353832234\", nonce=\"j4h3g2\", ext=\"some-app-ext-data\", mac=\"6R4rV5iE+NPoym+WwjeHzjAGXUtLNIxmo1vpMofpLAE=\"\r\n```\r\n\r\nThe server validates the request by calculating the request MAC again based on the request received and verifies the validity\r\nand scope of the **Hawk** credentials. If valid, the server responds with the requested resource.\r\n\r\n\r\n### Payload Validation\r\n\r\n**Hawk** provides optional payload validation. When generating the authentication header, the client calculates a payload hash\r\nusing the specified hash algorithm. The hash is calculated over the concatenated value of (each followed by a newline character):\r\n* `hawk.1.payload`\r\n* the content-type in lowercase, without any parameters (e.g. `application/json`)\r\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)\r\n\r\nFor example:\r\n\r\n* Payload: `Thank you for flying Hawk`\r\n* Content Type: `text/plain`\r\n* Hash (sha256): `Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=`\r\n\r\nResults in the following input to the payload hash function (newline terminated values):\r\n\r\n```\r\nhawk.1.payload\r\ntext/plain\r\nThank you for flying Hawk\r\n\r\n```\r\n\r\nWhich produces the following hash value:\r\n\r\n```\r\nYi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=\r\n```\r\n\r\nThe client constructs the normalized request string (newline terminated values):\r\n\r\n```\r\nhawk.1.header\r\n1353832234\r\nj4h3g2\r\nPOST\r\n/resource/1?a=1&b=2\r\nexample.com\r\n8000\r\nYi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=\r\nsome-app-ext-data\r\n\r\n```\r\n\r\nThen calculates the request MAC and includes the **Hawk** key identifier, timestamp, nonce, payload hash, application specific data,\r\nand request MAC, with the request using the HTTP `Authorization` request header field:\r\n\r\n```\r\nPOST /resource/1?a=1&b=2 HTTP/1.1\r\nHost: example.com:8000\r\nAuthorization: Hawk id=\"dh37fgj492je\", ts=\"1353832234\", nonce=\"j4h3g2\", hash=\"Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=\", ext=\"some-app-ext-data\", mac=\"aSe1DERmZuRl3pI36/9BdZmnErTw3sNzOOAUlfeKjVw=\"\r\n```\r\n\r\nIt is up to the server if and when it validates the payload for any given request, based solely on it's security policy\r\nand the nature of the data included.\r\n\r\nIf the payload is available at the time of authentication, the server uses the hash value provided by the client to construct\r\nthe normalized string and validates the MAC. If the MAC is valid, the server calculates the payload hash and compares the value\r\nwith the provided payload hash in the header. In many cases, checking the MAC first is faster than calculating the payload hash.\r\n\r\nHowever, if the payload is not available at authentication time (e.g. too large to fit in memory, streamed elsewhere, or processed\r\nat a different stage in the application), the server may choose to defer payload validation for later by retaining the hash value\r\nprovided by the client after validating the MAC.\r\n\r\nIt is important to note that MAC validation does not mean the hash value provided by the client is valid, only that the value\r\nincluded in the header was not modified. Without calculating the payload hash on the server and comparing it to the value provided\r\nby the client, the payload may be modified by an attacker.\r\n\r\n\r\n## Response Payload Validation\r\n\r\n**Hawk** provides partial response payload validation. The server includes the `Server-Authorization` response header which enables the\r\nclient to authenticate the response and ensure it is talking to the right server. **Hawk** defines the HTTP `Server-Authorization` header\r\nas a response header using the exact same syntax as the `Authorization` request header field.\r\n\r\nThe header is contructed using the same process as the client's request header. The server uses the same credentials and other\r\nartifacts provided by the client to constructs the normalized request string. The `ext` and `hash` values are replaced with\r\nnew values based on the server response. The rest as identical to those used by the client.\r\n\r\nThe result MAC digest is included with the optional `hash` and `ext` values:\r\n\r\n```\r\nServer-Authorization: Hawk mac=\"XIJRsMl/4oL+nn+vKoeVZPdCHXB4yJkNnBbTbHFZUYE=\", hash=\"f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=\", ext=\"response-specific\"\r\n```\r\n\r\n\r\n## Browser Support and Considerations\r\n\r\nA browser script is provided for including using a `<script>` tag in [lib/browser.js](/lib/browser.js). It's also a [component](http://component.io/hueniverse/hawk).\r\n\r\n**Hawk** relies on the _Server-Authorization_ and _WWW-Authenticate_ headers in its response to communicate with the client.\r\nTherefore, in case of CORS requests, it is important to consider sending _Access-Control-Expose-Headers_ with the value\r\n_\"WWW-Authenticate, Server-Authorization\"_ on each response from your server. As explained in the\r\n[specifications](http://www.w3.org/TR/cors/#access-control-expose-headers-response-header), it will indicate that these headers\r\ncan safely be accessed by the client (using getResponseHeader() on the XmlHttpRequest object). Otherwise you will be met with a\r\n[\"simple response header\"](http://www.w3.org/TR/cors/#simple-response-header) which excludes these fields and would prevent the\r\nHawk client from authenticating the requests.You can read more about the why and how in this\r\n[article](http://www.html5rocks.com/en/tutorials/cors/#toc-adding-cors-support-to-the-server)\r\n\r\n\r\n# Single URI Authorization\r\n\r\nThere are cases in which limited and short-term access to a protected resource is granted to a third party which does not\r\nhave access to the shared credentials. For example, displaying a protected image on a web page accessed by anyone. **Hawk**\r\nprovides limited support for such URIs in the form of a _bewit_ - a URI query parameter appended to the request URI which contains\r\nthe necessary credentials to authenticate the request.\r\n\r\nBecause of the significant security risks involved in issuing such access, bewit usage is purposely limited only to GET requests\r\nand for a finite period of time. Both the client and server can issue bewit credentials, however, the server should not use the same\r\ncredentials as the client to maintain clear traceability as to who issued which credentials.\r\n\r\nIn order to simplify implementation, bewit credentials do not support single-use policy and can be replayed multiple times within\r\nthe granted access timeframe. \r\n\r\n\r\n## Bewit Usage Example\r\n\r\nServer code:\r\n\r\n```javascript\r\nvar Http = require('http');\r\nvar Hawk = require('hawk');\r\n\r\n\r\n// Credentials lookup function\r\n\r\nvar credentialsFunc = function (id, callback) {\r\n\r\n var credentials = {\r\n key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',\r\n algorithm: 'sha256'\r\n };\r\n\r\n return callback(null, credentials);\r\n};\r\n\r\n// Create HTTP server\r\n\r\nvar handler = function (req, res) {\r\n\r\n Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {\r\n\r\n res.writeHead(!err ? 200 : 401, { 'Content-Type': 'text/plain' });\r\n res.end(!err ? 'Access granted' : 'Shoosh!');\r\n });\r\n};\r\n\r\nHttp.createServer(handler).listen(8000, 'example.com');\r\n```\r\n\r\nBewit code generation:\r\n\r\n```javascript\r\nvar Request = require('request');\r\nvar Hawk = require('hawk');\r\n\r\n\r\n// Client credentials\r\n\r\nvar credentials = {\r\n id: 'dh37fgj492je',\r\n key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',\r\n algorithm: 'sha256'\r\n}\r\n\r\n// Generate bewit\r\n\r\nvar duration = 60 * 5; // 5 Minutes\r\nvar bewit = Hawk.uri.getBewit('http://example.com:8080/resource/1?b=1&a=2', { credentials: credentials, ttlSec: duration, ext: 'some-app-data' });\r\nvar uri = 'http://example.com:8000/resource/1?b=1&a=2' + '&bewit=' + bewit;\r\n```\r\n\r\n\r\n# Security Considerations\r\n\r\nThe greatest sources of security risks are usually found not in **Hawk** but in the policies and procedures surrounding its use.\r\nImplementers are strongly encouraged to assess how this module addresses their security requirements. This section includes\r\nan incomplete list of security considerations that must be reviewed and understood before deploying **Hawk** on the server.\r\nMany of the protections provided in **Hawk** depends on whether and how they are used.\r\n\r\n### MAC Keys Transmission\r\n\r\n**Hawk** does not provide any mechanism for obtaining or transmitting the set of shared credentials required. Any mechanism used\r\nto obtain **Hawk** credentials must ensure that these transmissions are protected using transport-layer mechanisms such as TLS.\r\n\r\n### Confidentiality of Requests\r\n\r\nWhile **Hawk** provides a mechanism for verifying the integrity of HTTP requests, it provides no guarantee of request\r\nconfidentiality. Unless other precautions are taken, eavesdroppers will have full access to the request content. Servers should\r\ncarefully consider the types of data likely to be sent as part of such requests, and employ transport-layer security mechanisms\r\nto protect sensitive resources.\r\n\r\n### Spoofing by Counterfeit Servers\r\n\r\n**Hawk** provides limited verification of the server authenticity. When receiving a response back from the server, the server\r\nmay choose to include a response `Server-Authorization` header which the client can use to verify the response. However, it is up to\r\nthe server to determine when such measure is included, to up to the client to enforce that policy.\r\n\r\nA hostile party could take advantage of this by intercepting the client's requests and returning misleading or otherwise\r\nincorrect responses. Service providers should consider such attacks when developing services using this protocol, and should\r\nrequire transport-layer security for any requests where the authenticity of the resource server or of server responses is an issue.\r\n\r\n### Plaintext Storage of Credentials\r\n\r\nThe **Hawk** key functions the same way passwords do in traditional authentication systems. In order to compute the request MAC,\r\nthe server must have access to the key in plaintext form. This is in contrast, for example, to modern operating systems, which\r\nstore only a one-way hash of user credentials.\r\n\r\nIf an attacker were to gain access to these keys - or worse, to the server's database of all such keys - he or she would be able\r\nto perform any action on behalf of any resource owner. Accordingly, it is critical that servers protect these keys from unauthorized\r\naccess.\r\n\r\n### Entropy of Keys\r\n\r\nUnless a transport-layer security protocol is used, eavesdroppers will have full access to authenticated requests and request\r\nMAC values, and will thus be able to mount offline brute-force attacks to recover the key used. Servers should be careful to\r\nassign keys which are long enough, and random enough, to resist such attacks for at least the length of time that the **Hawk**\r\ncredentials are valid.\r\n\r\nFor example, if the credentials are valid for two weeks, servers should ensure that it is not possible to mount a brute force\r\nattack that recovers the key in less than two weeks. Of course, servers are urged to err on the side of caution, and use the\r\nlongest key reasonable.\r\n\r\nIt is equally important that the pseudo-random number generator (PRNG) used to generate these keys be of sufficiently high\r\nquality. Many PRNG implementations generate number sequences that may appear to be random, but which nevertheless exhibit\r\npatterns or other weaknesses which make cryptanalysis or brute force attacks easier. Implementers should be careful to use\r\ncryptographically secure PRNGs to avoid these problems.\r\n\r\n### Coverage Limitations\r\n\r\nThe request MAC only covers the HTTP `Host` header and optionally the `Content-Type` header. It does not cover any other headers\r\nwhich can often affect how the request body is interpreted by the server. If the server behavior is influenced by the presence\r\nor value of such headers, an attacker can manipulate the request headers without being detected. Implementers should use the\r\n`ext` feature to pass application-specific information via the `Authorization` header which is protected by the request MAC.\r\n\r\nThe response authentication, when performed, only covers the response payload, content-type, and the request information \r\nprovided by the client in it's request (method, resource, timestamp, nonce, etc.). It does not cover the HTTP status code or\r\nany other response header field (e.g. Location) which can affect the client's behaviour.\r\n\r\n### Future Time Manipulation\r\n\r\nThe protocol relies on a clock sync between the client and server. To accomplish this, the server informs the client of its\r\ncurrent time when an invalid timestamp is received.\r\n\r\nIf an attacker is able to manipulate this information and cause the client to use an incorrect time, it would be able to cause\r\nthe client to generate authenticated requests using time in the future. Such requests will fail when sent by the client, and will\r\nnot likely leave a trace on the server (given the common implementation of nonce, if at all enforced). The attacker will then\r\nbe able to replay the request at the correct time without detection.\r\n\r\nThe client must only use the time information provided by the server if:\r\n* it was delivered over a TLS connection and the server identity has been verified, or\r\n* the `tsm` MAC digest calculated using the same client credentials over the timestamp has been verified.\r\n\r\n### Client Clock Poisoning\r\n\r\nWhen receiving a request with a bad timestamp, the server provides the client with its current time. The client must never use\r\nthe time received from the server to adjust its own clock, and must only use it to calculate an offset for communicating with\r\nthat particular server.\r\n\r\n### Bewit Limitations\r\n\r\nSpecial care must be taken when issuing bewit credentials to third parties. Bewit credentials are valid until expiration and cannot\r\nbe revoked or limited without using other means. Whatever resource they grant access to will be completely exposed to anyone with\r\naccess to the bewit credentials which act as bearer credentials for that particular resource. While bewit usage is limited to GET\r\nrequests only and therefore cannot be used to perform transactions or change server state, it can still be used to expose private\r\nand sensitive information.\r\n\r\n### Host Header Forgery\r\n\r\nHawk validates the incoming request MAC against the incoming HTTP Host header. However, unless the optional `host` and `port`\r\noptions are used with `server.authenticate()`, a malicous client can mint new host names pointing to the server's IP address and\r\nuse that to craft an attack by sending a valid request that's meant for another hostname than the one used by the server. Server\r\nimplementors must manually verify that the host header received matches their expectation (or use the options mentioned above).\r\n\r\n# Frequently Asked Questions\r\n\r\n### Where is the protocol specification?\r\n\r\nIf you are looking for some prose explaining how all this works, **this is it**. **Hawk** is being developed as an open source\r\nproject instead of a standard. In other words, the [code](/hueniverse/hawk/tree/master/lib) is the specification. Not sure about\r\nsomething? Open an issue!\r\n\r\n### Is it done?\r\n\r\nAs of version 0.10.0, **Hawk** is feature-complete. However, until this module reaches version 1.0.0 it is considered experimental\r\nand is likely to change. This also means your feedback and contribution are very welcome. Feel free to open issues with questions\r\nand suggestions.\r\n\r\n### Where can I find **Hawk** implementations in other languages?\r\n\r\n**Hawk**'s only reference implementation is provided in JavaScript as a node.js module. However, it has been ported to other languages.\r\nThe full list is maintained [here](https://github.com/hueniverse/hawk/issues?labels=port&state=closed). Please add an issue if you are\r\nworking on another port. A cross-platform test-suite is in the works.\r\n\r\n### Why isn't the algorithm part of the challenge or dynamically negotiated?\r\n\r\nThe algorithm used is closely related to the key issued as different algorithms require different key sizes (and other\r\nrequirements). While some keys can be used for multiple algorithm, the protocol is designed to closely bind the key and algorithm\r\ntogether as part of the issued credentials.\r\n\r\n### Why is Host and Content-Type the only headers covered by the request MAC?\r\n\r\nIt is really hard to include other headers. Headers can be changed by proxies and other intermediaries and there is no\r\nwell-established way to normalize them. Many platforms change the case of header field names and values. The only\r\nstraight-forward solution is to include the headers in some blob (say, base64 encoded JSON) and include that with the request,\r\nan approach taken by JWT and other such formats. However, that design violates the HTTP header boundaries, repeats information,\r\nand introduces other security issues because firewalls will not be aware of these \"hidden\" headers. In addition, any information\r\nrepeated must be compared to the duplicated information in the header and therefore only moves the problem elsewhere.\r\n\r\n### Why not just use HTTP Digest?\r\n\r\nDigest requires pre-negotiation to establish a nonce. This means you can't just make a request - you must first send\r\na protocol handshake to the server. This pattern has become unacceptable for most web services, especially mobile\r\nwhere extra round-trip are costly.\r\n\r\n### Why bother with all this nonce and timestamp business?\r\n\r\n**Hawk** is an attempt to find a reasonable, practical compromise between security and usability. OAuth 1.0 got timestamp\r\nand nonces halfway right but failed when it came to scalability and consistent developer experience. **Hawk** addresses\r\nit by requiring the client to sync its clock, but provides it with tools to accomplish it.\r\n\r\nIn general, replay protection is a matter of application-specific threat model. It is less of an issue on a TLS-protected\r\nsystem where the clients are implemented using best practices and are under the control of the server. Instead of dropping\r\nreplay protection, **Hawk** offers a required time window and an optional nonce verification. Together, it provides developers\r\nwith the ability to decide how to enforce their security policy without impacting the client's implementation.\r\n\r\n### What are `app` and `dlg` in the authorization header and normalized mac string?\r\n\r\nThe original motivation for **Hawk** was to replace the OAuth 1.0 use cases. This included both a simple client-server mode which\r\nthis module is specifically designed for, and a delegated access mode which is being developed separately in\r\n[Oz](https://github.com/hueniverse/oz). In addition to the **Hawk** use cases, Oz requires another attribute: the application id `app`.\r\nThis provides binding between the credentials and the application in a way that prevents an attacker from tricking an application\r\nto use credentials issued to someone else. It also has an optional 'delegated-by' attribute `dlg` which is the application id of the\r\napplication the credentials were directly issued to. The goal of these two additions is to allow Oz to utilize **Hawk** directly,\r\nbut with the additional security of delegated credentials.\r\n\r\n### What is the purpose of the static strings used in each normalized MAC input?\r\n\r\nWhen calculating a hash or MAC, a static prefix (tag) is added. The prefix is used to prevent MAC values from being\r\nused or reused for a purpose other than what they were created for (i.e. prevents switching MAC values between a request,\r\nresponse, and a bewit use cases). It also protects against exploits created after a potential change in how the protocol\r\ncreates the normalized string. For example, if a future version would switch the order of nonce and timestamp, it\r\ncan create an exploit opportunity for cases where the nonce is similar in format to a timestamp.\r\n\r\n### Does **Hawk** have anything to do with OAuth?\r\n\r\nShort answer: no.\r\n\r\n**Hawk** was originally proposed as the OAuth MAC Token specification. However, the OAuth working group in its consistent\r\nincompetence failed to produce a final, usable solution to address one of the most popular use cases of OAuth 1.0 - using it\r\nto authenticate simple client-server transactions (i.e. two-legged). As you can guess, the OAuth working group is still hard\r\nat work to produce more garbage.\r\n\r\n**Hawk** provides a simple HTTP authentication scheme for making client-server requests. It does not address the OAuth use case\r\nof delegating access to a third party. If you are looking for an OAuth alternative, check out [Oz](https://github.com/hueniverse/oz).\r\n\r\n# Implementations\r\n\r\n- [Logibit Hawk in F#/.Net](https://github.com/logibit/logibit.hawk/)\r\n- [Tent Hawk in Ruby](https://github.com/tent/hawk-ruby)\r\n- [Wealdtech in Java](https://github.com/wealdtech/hawk)\r\n- [Kumar's Mohawk in Python](https://github.com/kumar303/mohawk/)\r\n\r\n# Acknowledgements\r\n\r\n**Hawk** is a derivative work of the [HTTP MAC Authentication Scheme](http://tools.ietf.org/html/draft-hammer-oauth-v2-mac-token-05) proposal\r\nco-authored by Ben Adida, Adam Barth, and Eran Hammer, which in turn was based on the OAuth 1.0 community specification.\r\n\r\nSpecial thanks to Ben Laurie for his always insightful feedback and advice.\r\n\r\nThe **Hawk** logo was created by [Chris Carrasco](http://chriscarrasco.com).\r\n",
  92. "readmeFilename": "README.md",
  93. "repository": {
  94. "type": "git",
  95. "url": "git://github.com/hueniverse/hawk.git"
  96. },
  97. "scripts": {
  98. "test": "lab -a code -t 100 -L",
  99. "test-cov-html": "lab -a code -r html -o coverage.html"
  100. },
  101. "version": "3.1.3"
  102. }