Code Monkey home page Code Monkey logo

hawk's Introduction

hawk

HTTP Holder-Of-Key Authentication Scheme.

Documentation of the protocol, and the JS API, is in https://github.com/mozilla/hawk/blob/main/API.md.

Ownership Changes

This was once hueniverse/hawk and relased as hawk. Then, after the 7.0.10 release, it was moved to the hapijs/hawk repository and released as @hapi/hawk. Hapi later de-supported the library, after releasing version 8.0.0. It has since been moved to mozilla/hawk and is again released as hawk. All of the intermediate versions are also relased as hawk.

Changes are represented in GitHub releases on this repository.

Mozilla maintains several Hawk implementations in different langauages, so it is likely to stay at Mozilla for some time.

This library is in "maintenance mode" -- no features will be added, and only security-related bugfixes will be applied.

hawk's People

Contributors

chrisdlangton avatar djmitche avatar dreyer avatar geek avatar grncdr avatar hendrikcech avatar hueniverse avatar jarrodyellets avatar joaojeronimo avatar johanneszorn avatar jsteunou avatar leviticusmb avatar lki avatar lotas avatar marsup avatar mathieuloutre avatar matt-boris avatar mcandre avatar mikeal avatar mnot avatar nwhitmont avatar paullang avatar pdehaan avatar salarelv avatar secretfader avatar severeoverfl0w avatar thusoy avatar titanous avatar tomyam1-personal avatar yury avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hawk's Issues

Is the id included in the normalized string

There appears to be a mismatch between the code and the docs regarding the inclusion of the credential's id in the normalized string:

  • the docs include the id in the normalized string
  • the code doesn't (hawk.js:154)

Storing the NTP offset in LocalStorage for the browser

In the browser plugin, the NTP offset is calculated and stored in memory. On page reload, this information would be lost. If this information is stored in LocalStorage for instance and retrieved on first execution of the script and used again.

For testing purposes, a library like node-localstorage could be used.

I could have a go and submit a pull request if it's interesting.

why is the id required for authentication?

in the example you send the authorization data like this

{"authorization":"Hawk id=\"dh37fgj492je\", ts=\"1360868338\", nonce=\"MTU2LD\", ext=\"and welcome!\", mac=\"+GU8is0px4MPjKbPxuJrlYjA5/ZwX/dD3o6vClALpYA=\"",...}

But isn't the 'id' really an internal user-id in a database.
Why not provide the username instead and then lookup the user-id serverside?

Sending Hawk MAC through querystring

We are thinking of using Hawk and use the authoirzation via the querystring instead of the header (we want to embed ready-to-use "next" links for paging as part of our API responses). Our HTTP endpoints are all TLS protected.

This would require to change a bit the library to try with the header first and if not, try with a querystring.

Do you think that makes sense?

Nice and simple implementation btw!

Why not Digest

Hi!

I hope this is an appropriate channel to ask this question. I'm trying to figure out what the benefits are of Hawk over HTTP digest.

The only I really see, is the usage of sha-256 over md5.

Is that correct, or is there more to it?

Python Implementation of Hawk

I'm working on a PyHawk, a library compatible with Hawk 0.13.

It seems to working for client, server, and bewit urls.

API isn't finalized, but otherwise I'd love some feedback and/or testers over in that repo.

Aside - A Hawk validation service would be awesome to test compliance. I'm using your usage.js in this fashion, but it doesn't cover a wide range of inputs and outputs.

Thanks for an awesome project!

Guidance on time window

Some spec text about the size of the window would be nice, even if it's just a mention that the default is 60 seconds in your implemenation.

Also, guidance that under certain limits, they're going to start seeing issues even with good clock sync; e.g., a one-second window will cause problems with mobile, Australia, etc. Might be good to recommend a minimum (5 or 10 seconds?).

Problems with sha1 test case

While writing compatibility tests for my Java port, I have problems with the payload hashing in test case

'should return a valid authorization header (sha1)'

AFAIU the payload normalized string will be

"hawk.1.payload\ntext/plain\nsomething to write about"

and the test expects the sha1 hash to be

bsvY3IfUllw6V5rvk4tStEvpBhE=

However, my Java test ends up with the hash

9LxQVpfaAgyiyNeOgD8TEKP6RnM=

I expected the error to be on my side (though the sha256 tests work fine) but verifying with an online hash tool confirmed my value (being a hex of "f4bc505697da020ca2c8d78e803f1310a3fa4673".

Any idea what might cause the difference or what I am doing wrong?

My test is here https://github.com/algermissen/hawkj/blob/master/src/test/java/net/jalg/hawkj/HawkCompatibilityTest.java#L42

Jan

how to handle salted keys?

I'd like to store salted credential keys in my users database is this possible or does Hawk require unsalted keys only ?

Response status in response MAC

Does it make sense to include the HTTP status code of the response in the response MAC? It seems like it's the main component of the response that can be tampered with on an untrusted connection.

intro text

The intro dances around the question of whether this is intended for browser, non-browser or both uses.

When comparing to Basic, would be good to (even parenthetically) use the terms "username" and "password", as that's what most of the planet understands. F'ing crypto geeks.

The big win of Hawk over Digest is that the client is responsible for nonce generation, so it's less chatty and stateful. I think you should play that up more.

Payload Hash in Authentication Header - Required?

Looking at 0.5 and the payload hash, is there a reason to have it in the authentication header? Seems like the server-side process for authentication should be:

  • Calculate the payload hash from the payload
  • Calculate the server-side MAC (including the payload hash)
  • Check it matches the client-side MAC

And this process doesn't need the client-side payload hash.

Of course, there does need to be some way for the server to know if the request's MAC was calculated with a payload hash so that the server knows what to do, but sending the payload hash in the authentication header seems like overkill to me. Thoughts?

Hawk should "tag" calls to HMAC to avoid any chance of confusion

It's generally a good practice to "tag" messages with a constant that identifies which message in the protocol the sender thinks it's sending. In hawk, that would mean adding a constant string to the beginning of the stuff you're HMACing. For example, you could add the string:

Hawk authentication

or whatever you like to "name" that message. The idea is that this helps prevent the message from being re-used in another, surprising context. Similarly, you might want to use a different tag for the bewit HMACs. Perhaps something like "Hawk bewit".

Of course, the receiver needs to verify that the message it receives contains the proper tag.

This issue is just about good cryptographic hygiene and unlikely to represent an actual weakness in the protocol.

nonce reuse

You don't say anything about whether it's OK to reuse a nonce, or whether the server should check them.

My .02 - require clients to use a new nonce for each request, within a given time period, and let servers decide if they want to enforce it.

NTP parameter

Do you really think this is necessary? I.e., are we living in a world where different well-run NTP servers can be even a few seconds out of sync? How will this actually be useful?

Payload hash in Authentication Header (again)

I've been looking at your answer to issue 24, and not sure what you're saying in your second paragraph. Are you suggesting that if the payload is not available then Hawk should trust the hash passed in for initial authentication and then hope that somewhere down the line the hash is validated?

I don't see any good coming from sending the hash; at best the server will ignore it as it calculates its own; at worst it will use it without confirming it (either throw laziness/misunderstanding or because the payload is unavailable). Seems to me that it is just inviting implementations to authenticate successfully when they shouldn't.

can't run tests on node 0.8.23

oss/hawk - [master] » make test

domain.js:66
    throw er;
          ^
ReferenceError: setImmediate is not defined
    at Object.internals.protect (/Users/jfroma/Projects/oss/hawk/node_modules/lab/lib/execute.js:235:5)
    at internals.executeTests (/Users/jfroma/Projects/oss/hawk/node_modules/lab/lib/execute.js:178:19)
    at async.eachSeries.iterate (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:128:13)
    at Object.async.eachSeries (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:144:9)
    at Object.internals.executeTests (/Users/jfroma/Projects/oss/hawk/node_modules/lab/lib/execute.js:173:11)
    at exports.execute (/Users/jfroma/Projects/oss/hawk/node_modules/lab/lib/execute.js:137:27)
    at async.series.results (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:545:21)
    at _asyncMap (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:221:13)
    at async.eachSeries.iterate (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:128:13)
    at async.eachSeries.iterate (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:139:25)
    at _asyncMap (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:223:17)
    at async.series.results (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:550:34)
    at internals.executeDeps (/Users/jfroma/Projects/oss/hawk/node_modules/lab/lib/execute.js:164:9)
    at Object.async.eachSeries (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:124:20)
    at Object.internals.executeDeps (/Users/jfroma/Projects/oss/hawk/node_modules/lab/lib/execute.js:159:11)
    at exports.execute (/Users/jfroma/Projects/oss/hawk/node_modules/lab/lib/execute.js:133:27)
    at async.series.results (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:545:21)
    at _asyncMap (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:221:13)
    at async.eachSeries.iterate (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:128:13)
    at async.eachSeries (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:144:9)
    at _asyncMap (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:220:9)
    at Object.doSeries [as mapSeries] (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:210:23)
    at Object.async.series (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:543:19)
    at exports.execute (/Users/jfroma/Projects/oss/hawk/node_modules/lab/lib/execute.js:130:15)
    at async.eachSeries.iterate (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:128:13)
    at async.eachSeries.iterate (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:139:25)
    at exports.execute (/Users/jfroma/Projects/oss/hawk/node_modules/lab/lib/execute.js:146:13)
    at _asyncMap (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:226:13)
    at async.eachSeries.iterate (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:136:25)
    at _asyncMap (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:223:17)
    at async.series.results (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:550:34)
    at internals.executeDeps (/Users/jfroma/Projects/oss/hawk/node_modules/lab/lib/execute.js:164:9)
    at Object.async.eachSeries (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:124:20)
    at Object.internals.executeDeps (/Users/jfroma/Projects/oss/hawk/node_modules/lab/lib/execute.js:159:11)
    at /Users/jfroma/Projects/oss/hawk/node_modules/lab/lib/execute.js:141:27
    at async.series.results (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:545:21)
    at _asyncMap (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:221:13)
    at async.eachSeries.iterate (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:128:13)
    at async.eachSeries.iterate (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:139:25)
    at _asyncMap (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:223:17)
    at async.series.results (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:550:34)
    at internals.executeTests (/Users/jfroma/Projects/oss/hawk/node_modules/lab/lib/execute.js:198:9)
    at Object.async.eachSeries (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:124:20)
    at Object.internals.executeTests (/Users/jfroma/Projects/oss/hawk/node_modules/lab/lib/execute.js:173:11)
    at exports.execute (/Users/jfroma/Projects/oss/hawk/node_modules/lab/lib/execute.js:137:27)
    at async.series.results (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:545:21)
    at _asyncMap (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:221:13)
    at async.eachSeries.iterate (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:128:13)
    at async.eachSeries.iterate (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:139:25)
    at _asyncMap (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:223:17)
    at async.series.results (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:550:34)
    at internals.executeDeps (/Users/jfroma/Projects/oss/hawk/node_modules/lab/lib/execute.js:164:9)
    at Object.async.eachSeries (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:124:20)
    at Object.internals.executeDeps (/Users/jfroma/Projects/oss/hawk/node_modules/lab/lib/execute.js:159:11)
    at exports.execute (/Users/jfroma/Projects/oss/hawk/node_modules/lab/lib/execute.js:133:27)
    at async.series.results (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:545:21)
    at _asyncMap (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:221:13)
    at async.eachSeries.iterate (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:128:13)
    at async.eachSeries (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:144:9)
    at _asyncMap (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:220:9)
    at Object.doSeries [as mapSeries] (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:210:23)
    at Object.async.series (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:543:19)
    at exports.execute (/Users/jfroma/Projects/oss/hawk/node_modules/lab/lib/execute.js:130:15)
    at async.eachSeries.iterate (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:128:13)
    at Object.async.eachSeries (/Users/jfroma/Projects/oss/hawk/node_modules/lab/node_modules/async/lib/async.js:144:9)
    at Object.exports.execute (/Users/jfroma/Projects/oss/hawk/node_modules/lab/lib/execute.js:128:11)
    at Object.<anonymous> (/Users/jfroma/Projects/oss/hawk/node_modules/lab/bin/lab:5:9)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.runMain (module.js:492:10)
    at process.startup.processNextTick.process._tickCallback (node.js:245:9)
make: *** [test] Error 1
oss/hawk - [master] » node --version
v0.8.23

I guess this version of node doesn't have setImmediate

Browser code

kinda need browser code in order to sign from most clients :)

Hawk Browser Client

Hi there!

We started using Hapi for our REST server and thought we might give Hawk a go for our authentification. I spent a little bit of time battling with a browser implementation of the Hawk scheme and I got this working: https://github.com/MathieuLoutre/hawk-browser-client

It's only a draft, but all the current client unit tests of Hawk are passing. It's definitely not maintainable in its current state and makes use of rewritten/extracted bits of code from the different libraries Hawk makes use of. It's basically a port of the current client code, but with libraries that can be used in the browser (minus the NTP stuff).

I figured it might help newcomers.

Unit tests fail with coverage error (Windows)

When I run npm test, the unit tests all pass, but then it fails with a coverage message.

$ npm test

> [email protected] test c:\Documents and Settings\apenneba\Desktop\src\hawk
> make test-cov

node node_modules/lab/bin/lab -r threshold -t 100


  ..................................................
  ..................................................
  ................

 116 tests complete (306 ms)

Coverage: 0.00%

Code coverage below threshold: 0.00 < 100
make: *** [test-cov] Error 1
npm ERR! Test failed.  See above for more details.
npm ERR! not ok code 0

Abstract request object

All the examples shows how to use hawk as a handler for http.createServer(), then the authentication function uses the request object to validate header or bewit but we don't know what hawks expect from the request object.

I have seen that express.js for instance change the url property while keeping the original url in originalUrl thus breaking the authentication.

It will be nice to have at least a section in the readme that mentions what things hawk expect from the request object, what properties and in what format.

Few I can think of:

  • req.method {string}
  • req.url {string} with querystring and all that..
  • req.headers.host {string}
  • req.headers.authorization

skip trailing '?' from uri in generateNormalizedString ?

I'm having issues with passing complete urls from the framework I'm trying to integrate Hawk into. To make Hawk authentication work in this scenario I have to skip the trailing '?'.
There was a note about that in the source. What are the implications of skipping the url options part?

Add Protocol Version To Header/Bewit

At current there is an assumption that the client and server both agree on the version of Hawk the are communicating with. For the future it would help if the protocol version was sent as part of the authentication header and bewit so that the server can handle multiple versions of the protocol.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.