Skip to content

Commit

Permalink
Merge pull request #85 from stellar/limit-responses-length
Browse files Browse the repository at this point in the history
Limit federation and stellar.toml responses length
  • Loading branch information
bartekn committed Mar 9, 2017
2 parents 6063164 + 5b86fd7 commit ae6d8c1
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 8 deletions.
14 changes: 11 additions & 3 deletions src/federation_server.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import {Config} from "./config";
import {Account, StrKey} from 'stellar-base';
import {StellarTomlResolver} from "./stellar_toml_resolver";

// FEDERATION_RESPONSE_MAX_SIZE is the maximum size of response from a federation server
export const FEDERATION_RESPONSE_MAX_SIZE = 100 * 1024;

export class FederationServer {
/**
* FederationServer handles a network connection to a
Expand Down Expand Up @@ -157,9 +160,14 @@ export class FederationServer {
}

_sendRequest(url) {
return axios.get(url.toString())
.then(response => response.data)
.catch(function (response) {
return axios.get(url.toString(), {maxContentLength: FEDERATION_RESPONSE_MAX_SIZE})
.then(response => {
if (typeof response.data.memo != "undefined" && typeof response.data.memo != 'string') {
throw new Error("memo value should be of type string");
}
return response.data;
})
.catch(response => {
if (response instanceof Error) {
return Promise.reject(response);
} else {
Expand Down
4 changes: 2 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ require('es6-promise').polyfill();
export * from "./errors";
export {Config} from "./config";
export {Server} from "./server";
export {FederationServer} from "./federation_server";
export {StellarTomlResolver} from "./stellar_toml_resolver";
export {FederationServer, FEDERATION_RESPONSE_MAX_SIZE} from "./federation_server";
export {StellarTomlResolver, STELLAR_TOML_MAX_SIZE} from "./stellar_toml_resolver";

// expose classes and functions from stellar-base
export * from "stellar-base";
Expand Down
5 changes: 4 additions & 1 deletion src/stellar_toml_resolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import Promise from 'bluebird';
import toml from 'toml';
import {Config} from "./config";

// STELLAR_TOML_MAX_SIZE is the maximum size of stellar.toml file
export const STELLAR_TOML_MAX_SIZE = 5 * 1024;

/**
* StellarTomlResolver allows resolving `stellar.toml` files.
*/
Expand Down Expand Up @@ -35,7 +38,7 @@ export class StellarTomlResolver {
if (allowHttp) {
protocol = 'http';
}
return axios.get(`${protocol}://${domain}/.well-known/stellar.toml`)
return axios.get(`${protocol}://${domain}/.well-known/stellar.toml`, {maxContentLength: STELLAR_TOML_MAX_SIZE})
.then(response => {
try {
let tomlObject = toml.parse(response.data);
Expand Down
40 changes: 38 additions & 2 deletions test/unit/federation_server_test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import http from "http";

describe("federation-server.js tests", function () {
beforeEach(function () {
this.server = new StellarSdk.FederationServer('https://acme.com:1337/federation', 'stellar.org');
Expand Down Expand Up @@ -174,7 +176,7 @@ FEDERATION_SERVER="https://api.stellar.org/federation"
stellar_address: 'bob*stellar.org',
account_id: 'GB5XVAABEQMY63WTHDQ5RXADGYF345VWMNPTN2GFUDZT57D57ZQTJ7PS',
memo_type: 'id',
memo: 100
memo: '100'
}
}));

Expand All @@ -183,13 +185,47 @@ FEDERATION_SERVER="https://api.stellar.org/federation"
stellar_address: 'bob*stellar.org',
account_id: 'GB5XVAABEQMY63WTHDQ5RXADGYF345VWMNPTN2GFUDZT57D57ZQTJ7PS',
memo_type: 'id',
memo: 100
memo: '100'
})
.notify(done);
});

it("fails for invalid Stellar address", function (done) {
StellarSdk.FederationServer.resolve('bob*stellar.org*test').should.be.rejectedWith(/Invalid Stellar address/).notify(done);
});

it("fails when memo is not string", function (done) {
this.axiosMock.expects('get')
.withArgs(sinon.match('https://acme.com:1337/federation?type=name&q=bob%2Astellar.org'))
.returns(Promise.resolve({
data: {
stellar_address: 'bob*stellar.org',
account_id: 'GB5XVAABEQMY63WTHDQ5RXADGYF345VWMNPTN2GFUDZT57D57ZQTJ7PS',
memo_type: 'id',
memo: 100
}
}));

this.server.resolveAddress('bob*stellar.org')
.should.be.rejectedWith(/memo value should be of type string/).notify(done);
});

it("fails when response exceeds the limit", function (done) {
// Unable to create temp server in a browser
if (typeof window != 'undefined') {
return done();
}
var response = Array(StellarSdk.FEDERATION_RESPONSE_MAX_SIZE+10).join('a');
let tempServer = http.createServer((req, res) => {
res.setHeader('Content-Type', 'application/json; charset=UTF-8');
res.end(response);
}).listen(4444, () => {
new StellarSdk.FederationServer('http://localhost:4444/federation', 'stellar.org', {allowHttp: true})
.resolveAddress('bob*stellar.org')
.should.be.rejectedWith(/maxContentLength size of [0-9]+ exceeded/)
.notify(done)
.then(() => tempServer.close());
});
});
});
});
19 changes: 19 additions & 0 deletions test/unit/stellar_toml_resolver_test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import http from "http";

describe("stellar_toml_resolver.js tests", function () {
beforeEach(function () {
this.axiosMock = sinon.mock(axios);
Expand Down Expand Up @@ -87,5 +89,22 @@ FEDERATION_SERVER="https://api.stellar.org/federation"

StellarSdk.StellarTomlResolver.resolve('acme.com').should.be.rejected.and.notify(done);
});

it("fails when response exceeds the limit", function (done) {
// Unable to create temp server in a browser
if (typeof window != 'undefined') {
return done();
}
var response = Array(StellarSdk.STELLAR_TOML_MAX_SIZE+10).join('a');
let tempServer = http.createServer((req, res) => {
res.setHeader('Content-Type', 'text/x-toml; charset=UTF-8');
res.end(response);
}).listen(4444, () => {
StellarSdk.StellarTomlResolver.resolve("localhost:4444", {allowHttp: true})
.should.be.rejectedWith(/maxContentLength size of [0-9]+ exceeded/)
.notify(done)
.then(() => tempServer.close());
});
});
});
});

0 comments on commit ae6d8c1

Please sign in to comment.