Skip to content

Instantly share code, notes, and snippets.

@gdb

gdb/index.html Secret

Last active August 29, 2015 14:04
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save gdb/cd4504c852102d4fd92c to your computer and use it in GitHub Desktop.
Save gdb/cd4504c852102d4fd92c to your computer and use it in GitHub Desktop.
User authentication using Stellar: proof-of-concept
<!DOCTYPE html>
<html>
<head>
<title>Authentication through Stellar proof-of-concept</title>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
<style>
body {
padding-top: 50px;
}
.starter-template {
padding: 40px 15px;
text-align: center;
}
</style>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
live = true;
if (live) {
var username = 'gdb-auth-notifier';
var account_id = 'g3S2S81x97WN4ZDdmYsWFt5pLzfwG3xqv7';
var url = 'ws://live.stellar.org:9001'
} else {
// Generate a test account using the tutorial at https://www.stellar.org/blog/introducing-stellar/
var username = '(no usernames in testmode)';
var account_id = 'gNL4zATHB95QPzM914hsnbXhXJxKc9hECR';
var url = 'ws://test.stellar.org:9001'
}
// Small random number. Normally this would be generated by the server
// to match with your session.
var microstellar_amount = Math.round(Math.random() * 1000);
function lookupUsername(account, onComplete) {
$.get('https://api.stellar.org/reverseFederation', {
destination_address: account,
domain: 'stellar.org',
type: 'reverse_federation'
}, function(data) {
console.log("Federation server responded with", data);
// Lifted from https://www.stellar.org/wp-content/themes/stellar/angular/explorer/scripts/services/reverseFederation.js?ver=0.0
if ("object" === typeof data &&
"object" === typeof data.federation_json &&
data.federation_json.type === "federation_record" &&
data.federation_json.destination_address === account &&
data.federation_json.domain === 'stellar.org') {
var username = data.federation_json.destination;
onComplete(username);
} else {
onComplete(null);
}
});
}
function promptLogin(destination) {
lookupUsername(destination, function(username) {
if (username) {
var text = "Authentication request received. Log in as " + username + " (" + destination + ")?";
} else {
var text = "Authentication request received. Log in as " + destination + "?";
}
var proceed = confirm(text);
if (proceed) {
$('#auth').text('You have successfully authenticated as ' + username + '.')
}
})
}
var ws = new WebSocket(url);
ws.onopen = function() {
console.log("Connected to stellard at " + url);
var msg = JSON.stringify({
command: 'subscribe',
accounts: [account_id]
});
ws.send(msg);
};
ws.onerror = function(err) {
console.error(err);
}
ws.onmessage = function(result) {
var msg = JSON.parse(result.data);
console.log(msg);
if(
msg.engine_result_code === 0 &&
msg.type === 'transaction' &&
msg.transaction.Destination === account_id
) {
if (msg.transaction.Amount == microstellar_amount) {
promptLogin(msg.transaction.Account);
} else {
console.log("Saw someone else's payment for", msg.transaction.Amount, "microstellars");
}
}
}
</script>
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<span class="navbar-brand">
User authentication via Stellar (<a href="https://gist.github.com/gdb/cd4504c852102d4fd92c">Github</a>)
</span>
</div>
</div>
</div>
<div class="container">
<div class="starter-template">
<h1>User authentication using Stellar</h1>
<p class="lead"> This is a proof-of-concept of using a Stellar
account for user authentication. </p>
<h2> How it works </h2>
<p> The service asks the user to send it a transaction for a
unique amount. Once the transaction has been received, the service
knows the user's address. In order to prevent an attacker from
just guessing the unique amount and submitting their own
transaction, the service prompts the user to confirm their
address. </p>
<h2> Known issues </h2>
<p> This implementation is vulnerable to a session fixation
attack, similar to the one that
affected <a href="http://hueniverse.com/2009/04/23/explaining-the-oauth-session-fixation-attack/">OAuth
v1</a>. The most plausible workaround I've thought of is that
payments need to somehow embed the metadata {gregbrockman.com,
session ID} (either natively by extending the Stellar protocol, or
as a layer on top of it) -- that way the user <i>can</i> always
verify which site they're authenticating to. I feel like there's
probably a better solution though, and would be curious to
<a href="https://twitter.com/thegdb">hear</a> if you have any
ideas. </p>
<hr />
<h2> Authenticate </h2>
<div id="auth">
<p> Leaving this window open, send <b id="amount">...</b> STR to <a id="destination" href="#">...</a> (<span id="account_id">...</span>) to authenticate. </p>
</div>
<script>
$('#amount').text(microstellar_amount/1000000);
var destination = $('#destination');
destination.text(username);
destination.attr('href', 'https://www.stellar.org/viewer/#/' + username);
$('#account_id').text(account_id);
</script>
</div>
</div><!-- /.container -->
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment