Giter VIP home page Giter VIP logo

php-mintoken's Issues

README clarifications

  • Create clear instructions for MINTOKEN_SQLITE_PATH, including an example.

    Possible example:

    define('MINTOKEN_SQLITE_PATH', '../../tokens.db');
  • Give a non-command line alternative for adding trusted endpoints to the settings table.

  • Make it clear that one instance of Mintoken can function for multiple websites and multiple authorization endpoints.

How should a token endpoint respond to invalid requests?

Mintoken uses error codes taken from RFC 6750: OAuth 2.0 Bearer Token Usage, 3.1. Error Codes.

An HTTP 401 status code with the invalid_token error is used whenever a faulty bearer token is send as part of the IndieAuth Access Token Verification. Example:

php-mintoken/endpoint.php

Lines 196 to 198 in 998e1d3

header('HTTP/1.1 401 Unauthorized');
header('WWW-Authenticate: Bearer, error="invalid_token", error_description="The access token is unknown"');
exit();

But when a faulty POST request is made, I am not sure which standard to follow. RFC 6750 also features invalid_request:

   invalid_request
         The request is missing a required parameter, includes an
         unsupported parameter or parameter value, repeats the same
         parameter, uses more than one method for including an access
         token, or is otherwise malformed.  The resource server SHOULD
         respond with the HTTP 400 (Bad Request) status code.

Does it make sense to send a HTTP 400 status code, and only put the error in the WWW-Authenticate? That doesn’t feel right. Should a token endpoint respond with a JSON body instead, following RFC 6749: OAuth 2.0, 5.2. Error Response? But then only parameter mistakes return JSON.

Absence of GET param seems to break Mintoken

I am opening this on behalf of Richard, who was at IndieWebCamp Düsseldorf this weekend. This is also the context: we didn't get Mintoken to work and we had minus 3 minutes until demo time.

The endpoint seemed to crash on an error: array_merge() doesn't accept null as a second argument. This means that in the code below, filter_input_array(INPUT_GET, ['me' ...]) does return null. (Line 278)

php-mintoken/endpoint.php

Lines 265 to 281 in 5f508fb

$request = array_merge(
filter_input_array(INPUT_POST, [
'grant_type' => [
'filter' => FILTER_VALIDATE_REGEXP,
'options' => ['regexp' => '@^authorization_code$@'],
],
'code' => [
'filter' => FILTER_VALIDATE_REGEXP,
'options' => ['regexp' => '@^[\x20-\x7E]+$@'],
],
'client_id' => FILTER_VALIDATE_URL,
'redirect_uri' => FILTER_VALIDATE_URL,
]),
filter_input_array(INPUT_GET, [
'me' => FILTER_VALIDATE_URL,
])
);

I cannot find a mention in the spec of the me param in either the POST-body nor the query string for the token request. But: Gimme-a-token does add the me, just in the POST-body, not the query string (which I think is the INPUT_GET but I am not sure how that works).

When we added a ?me= to the endpoint URL manually, it didn't seem to work either, but that's about all the debug-time we had left.

Can you shine any light on this? Where did me come from and why does Mintoken think it should come from GET?

Rename endpoint.php to index.php

It would be nice to be able to clone this repo into a new directory and have it accessible as the index of that directory. Then the <head> of the sites with which I use this could simply reference <link rel="token_endpoint" href="https://example.com/token/">, rather than <link rel="token_endpoint" href="https://example.com/token/endpoint.php">.

Solve timing attacks against the tokens

The token should consist of two parts:

  1. unique token identifier,
  2. random blob.

The first part can be used to query the token information from the database. If this part is faulty, nothing can be retrieved, and an error response can be sent. That is exactly as it is now.

That part might be vulnerable to timing attacks against SQLite’s WHERE clause. This means it would take slightly longer to deny a token starting with a known character, versus one without. (See this issue for a similar thing, and the links therein.) Over time the entire valid token can be found.

Mintoken can use the first part of the token to retrieve the second part of the token from the database. Then PHP can do a constant time comparison between the submitted second part and the second part from the database.

This means the second part is protecting us from timing attacks. Even if an attacker has used timing attacks to discover the complete first part of the token, the same attack can not be used against the second part. This protects the entire token against timing attacks.

Explore possibility to be database agnostic

While there are a few reasons for why I used an SQLite database as the storage behind Mintoken, it may be possible to let the user setup any PDO connection they want. That way any storage compatible with PDO will be compatible with Mintoken.

A few things to note:

  1. This means the SQLs need to be as globally supported as possible. Is there some standard SQL dialect that should be aimed for?
  2. Are there possible security mismatches between different databases?

As far as 2 goes, look into what the security experts from Paragon are doing in EasyDB.

Error: Faulty Request There was an error with the request. The "client_id" field is invalid.

This is an issue with selfauth but I'm hoping I can get some guidance here. I've also set up php-mintoken but I don't see how it even connects to selfauth. What am I missing here?

I've regenerated the config file several times and I keep getting the same error. Tried on a subdomain (http://auth.domain.tld and https://auth.domain.tld), on a subfolder (http://domain.tld/auth and https://domain.tld/auth) like in the guide, and even on the root domain (http://domain.tld and https://domain.tld). I even tried with www in the username (http://www.domain.tld and https://www.domain.tld).

<?php
define('APP_URL', 'http://auth.domain.tld/');
define('APP_KEY', ''>
define('USER_HASH', '');
define('USER_URL', 'https://domain.tld');

Store only hashed tokens

Currently all tokens are stored in the database as they are. This is fine as long as the database is securely stored in its entirety. But if the database was ever leaked, there is a window of opportunity for the tokens to get used before the owner revokes all of them.

By storing only hashed tokens an attacker would first need to bruteforce the hashes before being able to use any of the tokens. Which may proof to be impossible, or at least give the legitimate owner a safe window in which to revoke their tokens.

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.