Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

installs_allowed_from for better receipt checking

  • Loading branch information...
commit 05934f59b8de6a916fcb3e6df49e70beb5d7aa01 1 parent a77f155
@kumar303 authored
Showing with 28 additions and 11 deletions.
  1. +5 −6 README.md
  2. +23 −5 server.js
View
11 README.md
@@ -35,12 +35,11 @@ an attacker can run your app in an apps-enabled browser
(such as the nightly build of Firefox) and fiddle with the JavaScript
using the console to gain access to the app. This would be harder to do
on Android, a B2G phone, or similar open web device.
-However, an attacker could still fiddle with the JavaScript in this repo
-and probably make the app work even when it uses server side receipt checking
-as implemented for this demo.
-If you introduce a strong server component to your app
-(e.g. check the server periodically and possibly issue tokens)
-you can mitigate this.
+For full protection, you'd want to define `installs_allowed_from`
+in `server.js` which will limit which stores can claim to issue a receipt for your
+app.
+There is an open bug ([770666](https://bugzilla.mozilla.org/show_bug.cgi?id=770666))
+that will make the server whitelist more effective when fixed.
# Dev
View
28 server.js
@@ -3,6 +3,22 @@ var Verifier = require('receiptverifier').receipts.Verifier;
var app = express();
var media = __dirname + '/www';
+/*
+ * Array of absolute URLs to stores that can issue receipts for your app.
+ *
+ * Example:
+ * installs_allowed_from = ['https://marketplace.firefox.com',
+ * 'https://marketplace-dev.allizom.org']
+ *
+ * If you don't specify this then the value of the app manifest
+ * will be fetched from the client running your app.
+ * If you rely on the client
+ * then an attacker could hack the client code and issue a fake
+ * receipt at a fake domain with a verifier URL that does nothing.
+ *
+ * */
+var installs_allowed_from;
+
app.configure(function() {
app.use(express.logger({format: 'dev'}));
app.use(express.bodyParser());
@@ -21,17 +37,19 @@ app.get('/yacht/', function (req, res) {
});
app.post('/yacht/verify', function (req, res) {
- var store = new Verifier({ onlog: console.log });
+ var store = new Verifier({
+ onlog: console.log,
+ installs_allowed_from: (installs_allowed_from ||
+ // ... or use the client-fetched manifest value.
+ req.param('installs_allowed_from').split(','))
+ });
var receipts = req.param('receipts');
console.log(receipts);
if (!receipts) {
res.send('NO_RECEIPT', 400);
} else {
var app = {
- receipts: receipts.split(','),
- manifest: {
- installs_allowed_from: req.param('installs_allowed_from').split(',')
- }
+ receipts: receipts.split(',')
};
store.verifyReceipts(app, function (verifier) {
if (verifier.state.toString() === '[OK]') {
Please sign in to comment.
Something went wrong with that request. Please try again.