Socket
Socket
Sign inDemoInstall

hawk

Package Overview
Dependencies
4
Maintainers
1
Versions
85
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.10.0 to 0.10.1

3

example/usage.js

@@ -39,3 +39,3 @@ // Load modules

'Content-Type': 'text/plain',
'Authorization': Hawk.server.header(artifacts, { payload: payload, contentType: 'text/plain' })
'Server-Authorization': Hawk.server.header(artifacts, { payload: payload, contentType: 'text/plain' })
};

@@ -70,3 +70,2 @@

console.log(options.headers.authorization);

@@ -73,0 +72,0 @@ Request(options, function (error, response, body) {

@@ -142,3 +142,3 @@ // Load modules

payload: optional payload received
required: specifies is an Authorization header is required. Defaults to 'false'
required: specifies if a Server-Authorization header is required. Defaults to 'false'
}

@@ -169,5 +169,5 @@ */

// Parse HTTP Authorization header
// Parse HTTP Server-Authorization header
if (!res.headers.authorization &&
if (!res.headers['server-authorization'] &&
!options.required) {

@@ -178,3 +178,3 @@

var attributes = Utils.parseAuthorizationHeader(res.headers.authorization, ['mac', 'ext', 'hash']);
var attributes = Utils.parseAuthorizationHeader(res.headers['server-authorization'], ['mac', 'ext', 'hash']);
if (attributes instanceof Error) {

@@ -181,0 +181,0 @@ return false;

@@ -220,3 +220,3 @@ // Load modules

// Generate an Authorization header for a given response
// Generate a Server-Authorization header for a given response

@@ -255,3 +255,2 @@ /*

if (!credentials ||
!artifacts.id ||
!credentials.key ||

@@ -258,0 +257,0 @@ !credentials.algorithm) {

{
"name": "hawk",
"description": "HTTP Hawk Authentication Scheme",
"version": "0.10.0",
"version": "0.10.1",
"author": "Eran Hammer <eran@hueniverse.com> (http://hueniverse.com)",

@@ -6,0 +6,0 @@ "contributors": [],

@@ -8,4 +8,2 @@ ![hawk Logo](https://raw.github.com/hueniverse/hawk/master/images/hawk.png)

Last protocol change: **0.10.0** (changed payload hash method)
[![Build Status](https://secure.travis-ci.org/hueniverse/hawk.png)](http://travis-ci.org/hueniverse/hawk)

@@ -20,2 +18,3 @@

- [Payload Validation](#payload-validation)
- [Response Payload Validation](#response-payload-validation)
<p></p>

@@ -43,8 +42,8 @@ - [**Single URI Authorization**](#single-uri-authorization)

**Hawk** is an HTTP authentication scheme providing mechanisms for making authenticated HTTP requests with
partial cryptographic verification of the request, covering the HTTP method, request URI, host, and optionally
the request payload.
partial cryptographic verification of the request and response, covering the HTTP method, request URI, host,
and optionally the request payload.
Similar to the HTTP [Digest access authentication schemes](http://www.ietf.org/rfc/rfc2617.txt), **Hawk** uses a set of
client credentials which include a identifier (username) and key (password). Likewise, just as with the Digest scheme,
the key is never included in authenticated requests; instead, it is used to calculate a request MAC value which is
client credentials which include an identifier (e.g. username) and key (e.g. password). Likewise, just as with the Digest scheme,
the key is never included in authenticated requests. Instead, it is used to calculate a request MAC value which is
included in its place.

@@ -54,5 +53,5 @@

replay attacks, in **Hawk** the client generates the nonce and uses it in combination with a timestamp, leading to less
interaction with the server ("chattiness").
"chattiness" (interaction with the server).
Also unlike Digest, this scheme is not intended to protect the key itself (called the password in Digest) because
Also unlike Digest, this scheme is not intended to protect the key itself (the password in Digest) because
the client and server must both have access to the key material in the clear.

@@ -62,7 +61,9 @@

* simplify and improve HTTP authentication for services that are unwilling or unable to deploy TLS for all resources,
* secure credentials against leakage (e.g., when the client uses some form of dynamic configuration to determine where to send an authenticated request), and
* avoid the exposure of credentials sent to a malicious server over an unauthenticated secure channel due to client failure to validate the server's identity as part of its TLS handshake.
* secure credentials against leakage (e.g., when the client uses some form of dynamic configuration to determine where
to send an authenticated request), and
* avoid the exposure of credentials sent to a malicious server over an unauthenticated secure channel due to client
failure to validate the server's identity as part of its TLS handshake.
In addition, **Hawk** supports a method for granting third-parties temporary access to individual resources using
a query parameter called _bewit_ (leather straps used to attach a tracking device to the leg of a hawk).
a query parameter called _bewit_ (in falconry, a leather strap used to attach a tracking device to the leg of a hawk).

@@ -79,3 +80,3 @@ The **Hawk** scheme requires the establishment of a shared symmetric key between the client and the server,

than once, gaining access to a protected resource. To mitigate this, clients include both a nonce and a timestamp when
making requests; this gives the server enough information to prevent replay attacks.
making requests. This gives the server enough information to prevent replay attacks.

@@ -85,11 +86,10 @@ The nonce is generated by the client, and is a string unique across all requests with the same timestamp and

The timestamp enables the server to restrict the validity period of the credentials; requests occuring afterwards
The timestamp enables the server to restrict the validity period of the credentials where requests occuring afterwards
are rejected. It also removes the need for the server to retain an unbounded number of nonce values for future checks.
By default, **Hawk** uses a time window of 1 minute to allow for time skew between the client and server (which in
translates to a maximum of 2 minutes as the skew can be positive or negative).
practice translates to a maximum of 2 minutes as the skew can be positive or negative).
Using a timestamp requires the client's clock to be in sync with the server's clock. **Hawk** requires both the client
clock and the server clock to use NTP to ensure synchronization. However, given the limitations of some client types
(e.g. browsers) to deploy NTP, the server provides the client with its current time in response to a bad timestamp or
as part of an authentication challenge.
(e.g. browsers) to deploy NTP, the server provides the client with its current time in response to a bad timestamp.

@@ -99,3 +99,3 @@ There is no expectation that the client will adjust its system clock to match the server (in fact, this would be a

for communications with that particular server. The protocol rewards clients with synchronized clocks by reducing
the number of round trips required to authentication to a single request.
the number of round trips required to authenticate the first request.

@@ -138,6 +138,6 @@

// Generate Authorization response header
// Generate Server-Authorization response header
var header = Hawk.server.header(artifacts, { payload: payload, contentType: headers['Content-Type'] });
headers.Authorization = header;
headers['Server-Authorization'] = header;

@@ -216,8 +216,7 @@ // Send the response back

The resource server returns an authentication challenge. The challenge provides the client with the server's current
time and NTP server used for clock sync, which enable the client to offset its clock when making requests.
The resource server returns an authentication challenge.
```
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Hawk ts="1353832200"
WWW-Authenticate: Hawk
```

@@ -233,3 +232,4 @@

The client generates the authentication header by calculating a timestamp (e.g. the number of seconds since January 1,
1970 00:00:00 GMT), generating a nonce, and constructing the normalized request string (newline separated values):
1970 00:00:00 GMT), generating a nonce, and constructing the normalized request string (each value followed by a newline
character):

@@ -249,7 +249,2 @@ ```

The 'hawk.1.header' normalized string header is used to prevent MAC values from being reused after a potential change in how the
protocol creates the normalized string. For example, if a future version would switch the order of nonce and timestamp, it
can create an exploit opportunity for cases where the nonce is similar in format to a timestamp. In addition, the header
prevents switching MAC values between a header request and a bewit request.
The request MAC is calculated using HMAC with the specified hash algorithm "sha256" and the key over the normalized request string.

@@ -263,3 +258,3 @@ The result is base64-encoded to produce the request MAC:

The client includes the **Hawk** key identifier, timestamp, nonce, application specific data, and request MAC with the request using
the HTTP "Authorization" request header field:
the HTTP `Authorization` request header field:

@@ -279,3 +274,3 @@ ```

**Hawk** provides optional payload validation. When generating the authentication header, the client calculates a payload hash
using the specified hash algorithm. The hash is calculated over the concatenated value of:
using the specified hash algorithm. The hash is calculated over the concatenated value of (each followed by a newline character):
* `hawk.1.payload`

@@ -291,3 +286,3 @@ * the content-type in lowercase, without any parameters (e.g. `application/json`)

Results in the following input to the payload hash function (newline separated values):
Results in the following input to the payload hash function (newline terminated values):

@@ -307,3 +302,3 @@ ```

The client constructs the normalized request string (newline separated values):
The client constructs the normalized request string (newline terminated values):

@@ -324,3 +319,3 @@ ```

Then calculates the request MAC and includes the **Hawk** key identifier, timestamp, nonce, payload hash, application specific data,
and request MAC with the request using the HTTP "Authorization" request header field:
and request MAC, with the request using the HTTP `Authorization` request header field:

@@ -345,8 +340,26 @@ ```

It is important to note that MAC validation does not mean the hash value provided by the client is valid, only that the value
included in the header was nor modified. Without calculating the payload hash on the server and comparing it to the value provided
included in the header was not modified. Without calculating the payload hash on the server and comparing it to the value provided
by the client, the payload may be modified by an attacker.
## Response Payload Validation
**Hawk** provides partial response payload validation. The server includes the `Server-Authorization` response header which enables the
client to authenticate the response and ensure it is talking to the right server. **Hawk** defines the HTTP `Server-Authorization` header
as a response header using the exact same syntax as the `Authorization` request header field.
The header is contructed using the same process as the client's request header. The server uses the same credentials and other
artifacts provided by the client to constructs the normalized request string. The `ext` and `hash` values are replaced with
new values based on the server response. The rest as identical to those used by the client.
The result MAC digest is included with the optional `hash` and `ext` values:
```
Server-Authorization: Hawk mac="XIJRsMl/4oL+nn+vKoeVZPdCHXB4yJkNnBbTbHFZUYE=", hash="f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=", ext="response-specific"
```
# Single URI Authorization
There are often cases in which limited and short-term access is granted to protected resource to a third party which does not
There are cases in which limited and short-term access to a protected resource is granted to a third party which does not
have access to the shared credentials. For example, displaying a protected image on a web page accessed by anyone. **Hawk**

@@ -356,3 +369,3 @@ provides limited support for such URIs in the form of a _bewit_ - a URI query parameter appended to the request URI which contains

Because of the significant security risks involved in issuing such access, bewit usage is purposely limited to only GET requests
Because of the significant security risks involved in issuing such access, bewit usage is purposely limited only to GET requests
and for a finite period of time. Both the client and server can issue bewit credentials, however, the server should not use the same

@@ -428,2 +441,3 @@ credentials as the client to maintain clear traceability as to who issued which credentials.

an incomplete list of security considerations that must be reviewed and understood before deploying **Hawk** on the server.
Many of the protections provided in **Hawk** depends on whether and how they are used.

@@ -444,7 +458,10 @@ ### MAC Keys Transmission

**Hawk** makes no attempt to verify the authenticity of the server. A hostile party could take advantage of this by intercepting
the client's requests and returning misleading or otherwise incorrect responses. Service providers should consider such attacks
when developing services using this protocol, and should require transport-layer security for any requests where the authenticity
of the resource server or of server responses is an issue.
**Hawk** provides limited verification of the server authenticity. When receiving a response back from the server, the server
may choose to include a response `Server-Authorization` header which the client can use to verify the response. However, it is up to
the server to determine when such measure is included, to up to the client to enforce that policy.
A hostile party could take advantage of this by intercepting the client's requests and returning misleading or otherwise
incorrect responses. Service providers should consider such attacks when developing services using this protocol, and should
require transport-layer security for any requests where the authenticity of the resource server or of server responses is an issue.
### Plaintext Storage of Credentials

@@ -478,12 +495,15 @@

The request MAC only covers the HTTP `Host` header and does not cover any other headers which can often affect how the request
body is interpreted by the server (i.e. Content-Type). If the server behavior is influenced by the presence or value of such headers,
an attacker can manipulate the request header without being detected. Implementers should use the `ext` feature to pass
application-specific information via the Authorization header which is protected by the request MAC.
The request MAC only covers the HTTP `Host` header and optionally the `Content-Type` header. It does not cover any other headers
which can often affect how the request body is interpreted by the server. If the server behavior is influenced by the presence
or value of such headers, an attacker can manipulate the request headers without being detected. Implementers should use the
`ext` feature to pass application-specific information via the `Authorization` header which is protected by the request MAC.
The response authentication, when performed, only covers the response payload, content-type, and the request information
provided by the client in it's request (method, resource, timestamp, nonce, etc.). It does not cover the HTTP status code or
any other response header field (e.g. Location) which can affect the client's behaviour.
### Future Time Manipulation
The protocol relies on a clock sync between the client and server. To accomplish this, the server informs the client of its
current time as well as identifies the NTP server used (the client can opt to use either one to calculate the offset used for
further interactions with the server).
current time when an invalid timestamp is received.

@@ -495,4 +515,5 @@ If an attacker is able to manipulate this information and cause the client to use an incorrect time, it would be able to cause

The client must only use the time information provided by the server if it is sent over a TLS connection and the server identity
has been verified.
The client must only use the time information provided by the server if:
* it was delivered over a TLS connection and the server identity has been verified, or
* the `tsm` MAC digest calculated using the same client credentials over the timestamp has been verified.

@@ -518,3 +539,3 @@ ### Client Clock Poisoning

If you are looking for some prose explaining how all this works, there isn't any. **Hawk** is being developed as an open source
If you are looking for some prose explaining how all this works, **this is it**. **Hawk** is being developed as an open source
project instead of a standard. In other words, the [code](/hueniverse/hawk/tree/master/lib) is the specification. Not sure about

@@ -525,19 +546,9 @@ something? Open an issue!

No but it's getting close. Until this module reaches version 1.0.0 it is considered experimental and is likely to change. This also
means your feedback and contribution are very welcome. Feel free to open issues with questions and suggestions.
At if version 0.10.0, **Hawk** is feature-complete. However, until this module reaches version 1.0.0 it is considered experimental
and is likely to change. This also means your feedback and contribution are very welcome. Feel free to open issues with questions
and suggestions.
### Does **Hawk** have anything to do with OAuth?
Short answer: no.
**Hawk** was originally proposed as the OAuth MAC Token specification. However, the OAuth working group in its consistent
incompetence failed to produce a final, usable solution to address one of the most popular use cases of OAuth 1.0 - using it
to authenticate simple client-server transactions (i.e. two-legged).
**Hawk** provides a simple HTTP authentication scheme for making client-server requests. It does not address the OAuth use case
of delegating access to a third party. If you are looking for an OAuth alternative, check out [Oz](/hueniverse/oz).
### Where can I find **Hawk** implementations in other languages?
**Hawk** is only officially implemented in JavaScript as a node.js module. However, others are actively porting it to other
**Hawk**'s only reference implementation is provided in JavaScript as a node.js module. However, others are actively porting it to other
platforms. There is already a [PHP](https://github.com/alexbilbie/PHP-Hawk),

@@ -552,12 +563,12 @@ [.NET](https://github.com/pcibraro/hawknet), and [JAVA](https://github.com/wealdtech/hawk) libraries available. The full list

requirements). While some keys can be used for multiple algorithm, the protocol is designed to closely bind the key and algorithm
together as part of the issued credentials.
together as part of the issued credentials.
### Why is Host the only header covered by the request MAC?
### Why is Host and Content-Type the only headers covered by the request MAC?
It is really hard to include other headers. Headers can be changed by proxies and other intermediaries and there is no
well-established way to normalize them. The only straight-forward solution is to include the headers in some blob (say,
bas64 encoded JSON) and include that with the request, an approach taken by JWT and other such formats. However, that
design violates the HTTP header boundaries, repeats information, and introduces other security issues because firewalls
will not be aware of these "hidden" headers. In addition, any information repeated must be compared to the duplicated
information in the header and therefore only moves the problem elsewhere.
well-established way to normalize them. Many platforms change the case of header field names and values. The only
straight-forward solution is to include the headers in some blob (say, base64 encoded JSON) and include that with the request,
an approach taken by JWT and other such formats. However, that design violates the HTTP header boundaries, repeats information,
and introduces other security issues because firewalls will not be aware of these "hidden" headers. In addition, any information
repeated must be compared to the duplicated information in the header and therefore only moves the problem elsewhere.

@@ -568,4 +579,3 @@ ### Why not just use HTTP Digest?

a protocol handshake to the server. This pattern has become unacceptable for most web services, especially mobile
where extra round-trip are costly. While Hawk includes support for sending a challenge when a request lacks
authentication, it does not require it.
where extra round-trip are costly.

@@ -575,3 +585,3 @@ ### Why bother with all this nonce and timestamp business?

**Hawk** is an attempt to find a reasonable, practical compromise between security and usability. OAuth 1.0 got timestamp
and nonces half the way right but failed when it came to scalability and consistent developer experience. **Hawk** addresses
and nonces halfway right but failed when it came to scalability and consistent developer experience. **Hawk** addresses
it by requiring the client to sync its clock, but provides it with tools to accomplish it.

@@ -591,7 +601,26 @@

to use credentials issued to someone else. It also has an optional 'delegated-by' attribute `dlg` which is the application id of the
application the credentials were directly issued to.
application the credentials were directly issued to. The goal of these two additions is to allow Oz to utilize **Hawk** directly,
but with the additional security of delegated credentials.
The goal of these two additions is to allow Oz to utilize **Hawk** directly, but with the additional security of delegated credentials.
The additional support has been added without breaking or affecting **Hawk**-only use cases.
### What is the purpose of the static strings used in each normalized MAC input?
When calculating a hash or MAC, a static prefix (tag) is added. The prefix is used to prevent MAC values from being
used or reused for a purpose other than what they were created for (i.e. prevents switching MAC values between a request,
response, and a bewit use cases). It also protects against expliots created after a potential change in how the protocol
creates the normalized string. For example, if a future version would switch the order of nonce and timestamp, it
can create an exploit opportunity for cases where the nonce is similar in format to a timestamp.
### Does **Hawk** have anything to do with OAuth?
Short answer: no.
**Hawk** was originally proposed as the OAuth MAC Token specification. However, the OAuth working group in its consistent
incompetence failed to produce a final, usable solution to address one of the most popular use cases of OAuth 1.0 - using it
to authenticate simple client-server transactions (i.e. two-legged). As you can guess, the OAuth working group is still hard
at work to produce more garbage.
**Hawk** provides a simple HTTP authentication scheme for making client-server requests. It does not address the OAuth use case
of delegating access to a third party. If you are looking for an OAuth alternative, check out [Oz](/hueniverse/oz).
# Acknowledgements

@@ -598,0 +627,0 @@

@@ -89,3 +89,3 @@ // Load modules

headers: {
'authorization': 'Hawk mac="abc", bad="xyz"'
'server-authorization': 'Hawk mac="abc", bad="xyz"'
}

@@ -103,3 +103,3 @@ };

'content-type': 'text/plain',
'authorization': 'Hawk mac="_IJRsMl/4oL+nn+vKoeVZPdCHXB4yJkNnBbTbHFZUYE=", hash="f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=", ext="response-specific"'
'server-authorization': 'Hawk mac="_IJRsMl/4oL+nn+vKoeVZPdCHXB4yJkNnBbTbHFZUYE=", hash="f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=", ext="response-specific"'
}

@@ -139,3 +139,3 @@ };

'content-type': 'text/plain',
'authorization': 'Hawk mac="XIJRsMl/4oL+nn+vKoeVZPdCHXB4yJkNnBbTbHFZUYE=", hash="f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=", ext="response-specific"'
'server-authorization': 'Hawk mac="XIJRsMl/4oL+nn+vKoeVZPdCHXB4yJkNnBbTbHFZUYE=", hash="f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=", ext="response-specific"'
}

@@ -142,0 +142,0 @@ };

@@ -87,4 +87,4 @@ // Load modules

res.headers.authorization = Hawk.server.header(artifacts, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' });
expect(res.headers.authorization).to.exist;
res.headers['server-authorization'] = Hawk.server.header(artifacts, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' });
expect(res.headers['server-authorization']).to.exist;

@@ -91,0 +91,0 @@ expect(Hawk.client.authenticate(res, artifacts, { payload: 'some reply' })).to.equal(true);

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc