Realms #3854
Realms #3854
Changes from 2 commits
f6e2b48
2dda3ca
7d81daa
8c7b0d9
a76701f
a38a69f
527c4f5
28152c7
bc5c8a9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,11 +20,12 @@ var addy = config.has('bind_to.host') ? config.get('bind_to.host') : "127.0.0.1" | |
forward.setTimeout(config.get('declaration_of_support_timeout_ms')); | ||
|
||
const allowed = /^https:\/\/[a-zA-Z0-9\.\-_]+\/\.well-known\/browserid(\?.*)?$/; | ||
const allowed_realm = /^https?:\/\/[a-zA-Z0-9\.\-_:]+\/\.well-known\/browserid-realm(\?.*)?$/; | ||
const allowed_kpi = /^https:\/\/[a-zA-Z0-9\.\-_]+\/wsapi\/interaction_data(\?.*)?$/; | ||
|
||
var server = http.createServer(function (req, res) { | ||
var url = req.url; | ||
if (!allowed.test(url) && !allowed_kpi.test(url) ) { | ||
if (!allowed.test(url) && !allowed_realm.test(url) && !allowed_kpi.test(url) ) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. will this also require changes to our production proxy? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Possibly, @gene1wood or @jrgm? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @shane-tomlinson Will this change result in persona initiating outbound connections out to the internet to new destinations (destinations other than sites' well-known/.browserid files and identity bridge endpoints [yahoo, gmail, etc])? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @gene1wood - indeed, the new outbound request will search for realm files at <rp_location>/.well-known/browserid-realm There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Proxy server support added here mozilla/identity-ops@e6e2931 When QA wants to see this code in stage they'll need to request that new proxy server AMIs be built with this new code in the process. (cc @jrgm) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Excellent, thanks @gene1wood |
||
res.writeHead(400); | ||
res.end('You can\'t get there from here'); | ||
return; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"realm": ["http://localhost:10001", "http://127.0.0.1:10001"] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -179,6 +179,7 @@ <h2>readiness</h2> | |
|
||
navigator.id.watch({ | ||
loggedInUser: (storage.loggedInUser === 'null') ? null : storage.loggedInUser, | ||
realm: 'http://localhost:10001', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. must a site specify a realm? If not, can we make this optional or create a new example page for it? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A site doesn't have to. I was trying to figure out how to make this optional. Perhaps if the page is loaded with |
||
onready: function () { | ||
loggit("onready"); | ||
var txt = serial++ + ' navigator.id ready at ' + (new Date).toString(); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||
|
||
const request = require('./request'); | ||
const logger = require('./logging').logger; | ||
const util = require('util'); | ||
const validate = require('./validate'); | ||
|
||
const WELL_KNOWN_PATH = '/.well-known/browserid-realm'; | ||
|
||
function isJsonType(res) { | ||
var contentType = res.headers['content-type']; | ||
return contentType && contentType.indexOf('application/json') === 0; | ||
} | ||
|
||
exports.checkSupport = function realmSupport(realm, callback) { | ||
request(realm + WELL_KNOWN_PATH, { json: true }, function onRequest(err, res, body) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Must realms be defined at an https endpoint like /.well-known/browserid? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nope, http and https are both valid. The protocol is required in the listed realm argument (wsapi/realm_info validates its a proper There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So, I could have missed something, but here's my reasoning as to why we should allow http as well. First, we allow RPs to use Persona for login even over http. Their sites don't need to be secured with HTTPS. Of course, there's risk for the sites, that an attacker could adjust DNS to make the user log into the wrong site, or an attack could capture the assertion as the site POSTs it to their own server for verification, and login as the user. Still, we let the sites accept those risks, instead of demanding everyone who wants to use Persona needs to setup HTTPS. Likewise, the realm is simply a group of sites that a user is logging in to. An attacker could hijack DNS to an http site, and declare a different realm than normal. Or they could serve up their own browserid-realm file, which could include a different list of sites. The user isn't automatically logged into any of those sites at that time. The user then needs to visit one of those sites, and that site (whether normally or by the attacker) would need to declare being part of the hijacked realm. In the end, the worst that could happen is a user is logged into a realm or site that isn't really part of the realm. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @seanmonstar If we want https and http for the /.well-known/browserid-realm URL I'll need to tweak my proxy config change (I'd assumed this was https only like /.well-known/browserid |
||
if (err) { | ||
logger.debug(err); | ||
} else if (!isJsonType(res)) { | ||
// strict here so that file isn't added to site by mistake. admin | ||
// must want this file to exist by explicitly setting headers | ||
err = new Error("content-type was not application/json"); | ||
body = null; | ||
} else if (!(body && body.realm)) { | ||
err = new Error('missing realm json'); | ||
} else if (!util.isArray(body.realm)) { | ||
err = new Error('realm property is not an array'); | ||
} else { | ||
body.realm = body.realm.filter(function(value) { | ||
try { | ||
validate.is.origin(value); | ||
return true; | ||
} catch(err) { | ||
return false; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should there be some sort of error surfaced here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a filter on the array provided by a support document. If a value in the array isn't a proper origin, it gets dumped. So, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok, that makes sense. |
||
} | ||
}); | ||
} | ||
callback(err, body); | ||
}); | ||
}; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
const request = require('request'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i dearly wanted to fix up There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add an issue for it! |
||
const config = require('./configuration'); | ||
|
||
const REQUEST_TIMEOUT = config.get('declaration_of_support_timeout_ms'); | ||
const HTTP_PROXY = config.has('http_proxy') ? config.get('http_proxy') : null; | ||
|
||
module.exports = function browserid_request(url, options, callback) { | ||
if (typeof options === 'function') { | ||
callback = options; | ||
options = {}; | ||
} | ||
|
||
if (HTTP_PROXY) { | ||
options.proxy = { | ||
protocol: 'http:', | ||
host: HTTP_PROXY.host, | ||
port: HTTP_PROXY.port | ||
}; | ||
} | ||
|
||
if (!('timeout' in options)) { | ||
options.timeout = REQUEST_TIMEOUT; | ||
} | ||
|
||
options.strictSSL = true; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah yes, it looks like declaration of support must be SSL. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, it doesn't have to be. This option is only used for HTTPS requests. But considering we pretty much always use an outgoing proxy, it's likely never actually needed. Still, doesn't hurt, and is safer. |
||
|
||
request(url, options, callback); | ||
}; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -143,3 +143,5 @@ module.exports = function (params) { | |
next(); | ||
}; | ||
}; | ||
|
||
module.exports.is = types; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||
const realm = require('../realm'); | ||
const logger = require('../logging').logger; | ||
|
||
exports.method = 'get'; | ||
exports.writes_db = false; | ||
exports.authed = false; | ||
exports.args = { | ||
realm: 'origin' | ||
}; | ||
exports.i18n = false; | ||
|
||
exports.process = function realm_info(req, res) { | ||
var domain = req.params.realm.toLowerCase(); | ||
realm.checkSupport(domain, function onRealm(err, body) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure whether this comment is better here or in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ideally, we could let squid handle caching this file, just as we do when requesting the IdP support document. possible @gene1wood ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @seanmonstar The squid proxy server will respect whatever caching directives it receives from the target site in the HTTP headers that come with the /.well-known/browserid-realm document. If the target asserts long cache times, the squid proxy will respect that and not make an outbound request. |
||
var json = {}; | ||
if (err) { | ||
logger.info('"' + domain + '" realm support is misconfigured: ' + err); | ||
json.realm = []; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IIUC, the intent here is to not block users from signing in to a site if the support document is misconfigured? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. correct. i'll add a comment say as much |
||
} else { | ||
json.realm = body.realm; | ||
} | ||
|
||
res.json(json); | ||
}); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,13 +14,22 @@ | |
"ansi": { | ||
"0.1.2": "2627e29498f06e2a1c2ece9c21e28fd494430827" | ||
}, | ||
"asn1": { | ||
"0.1.11": "559be18376d08a4ec4dbe80877d27818639b2df7" | ||
}, | ||
"assert-plus": { | ||
"0.1.2": "d93ffdbb67ac5507779be316a7d65146417beef8" | ||
}, | ||
"async": { | ||
"0.1.22": "0fc1aaa088a0e3ef0ebe2d8831bab0dcf8845061", | ||
"0.2.9": "df63060fbf3d33286a76aaf6d55a2986d9ff8619" | ||
}, | ||
"aws-lib": { | ||
"0.0.5": "971b8995078d83c80f2372f134c496e71b293a46" | ||
}, | ||
"aws-sign": { | ||
"0.3.0": "3d81ca69b474b1e16518728b51c24ff0bbedc6e9" | ||
}, | ||
"awsbox": { | ||
"0.4.5": "027a9998955f09f3d6b0a10d38ea37ae381b6358" | ||
}, | ||
|
@@ -33,6 +42,9 @@ | |
"bindings": { | ||
"1.0.0": "c3ccde60e9de6807c6f1aa4ef4843af29191c828" | ||
}, | ||
"boom": { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like boom, can we get rid of our homegrown error code library and use it instead? |
||
"0.4.2": "7a636e9ded4efcefb19cef4947a3c67dfaee911b" | ||
}, | ||
"browserify": { | ||
"1.13.5": "b5f0a160733779d27547885dfb598a65ef6fdaad" | ||
}, | ||
|
@@ -63,6 +75,9 @@ | |
"0.5.1": "7d0023eaeb154e8ee9fce75dcb923d0ed1667774", | ||
"0.6.0-1": "6dbb68ceb8bc60f2b313dcc5ce1599f06d19e67a" | ||
}, | ||
"combined-stream": { | ||
"0.0.4": "2d1a43347dbe9515a4a2796732e5b88473840b22" | ||
}, | ||
"commander": { | ||
"1.1.1": "50d1651868ae60eccff0a2d9f34595376bc6b041" | ||
}, | ||
|
@@ -96,13 +111,19 @@ | |
"convict": { | ||
"0.0.6": "960495df513baf3e5c20b970268fd86ff1ac79b2" | ||
}, | ||
"cookie-jar": { | ||
"0.3.0": "bc9a27d4e2b97e186cd57c9e2063cb99fa68cccc" | ||
}, | ||
"cookies": { | ||
"0.2.1": "fee635ef023704893ac30387899f3dc448a52840", | ||
"0.3.6": "1b5e4bd66fc732ea2e8b5087a8fb3718b4ec8597" | ||
}, | ||
"cover": { | ||
"0.2.8": "91946a9806e992f98d374cecd642fce9b96f5237" | ||
}, | ||
"cryptiles": { | ||
"0.2.2": "ed91ff1f17ad13d3748288594f8a48a0d26f325c" | ||
}, | ||
"crypto-browserify": { | ||
"0.2.3": "c98141505d90e31a1e456cb97343dc3b0f4a1a2a" | ||
}, | ||
|
@@ -115,6 +136,9 @@ | |
"css-stringify": { | ||
"1.0.5": "b0d042946db2953bb9d292900a6cb5f6d0122031" | ||
}, | ||
"ctype": { | ||
"0.5.2": "fe8091d468a373a0b0c9ff8bbfb3425c00973a1d" | ||
}, | ||
"cycle": { | ||
"1.0.2": "269aca6f1b8d2baeefc8ccbc888b459f322c4e60" | ||
}, | ||
|
@@ -124,6 +148,9 @@ | |
"debug": { | ||
"0.7.2": "056692c86670977f115de82917918b8e8b9a10f0" | ||
}, | ||
"delayed-stream": { | ||
"0.0.5": "d4b1f43a93e8296dfe02694f4680bc37a313c73f" | ||
}, | ||
"deputy": { | ||
"0.0.4": "edc00a9ef5c53527c405328534c99795ada41cbf" | ||
}, | ||
|
@@ -158,6 +185,12 @@ | |
"eyes": { | ||
"0.1.8": "62cf120234c683785d902348a800ef3e0cc20bc0" | ||
}, | ||
"forever-agent": { | ||
"0.5.0": "0c1647a74f3af12d76a07a99490ade7c7249c8f0" | ||
}, | ||
"form-data": { | ||
"0.1.1": "0d5f2805647b45533ba10bc8a59cf17d1efa5f12" | ||
}, | ||
"fresh": { | ||
"0.1.0": "03e4b0178424e4c2d5d19a54d8814cdc97934850" | ||
}, | ||
|
@@ -173,27 +206,34 @@ | |
}, | ||
"graceful-fs": { | ||
"1.1.14": "07078db5f6377f6321fceaaedf497de124dc9465", | ||
"1.2.1": "b35cc6e623576fc2a278cba12c00dda6a1758d2d", | ||
"1.2.3": "15a4806a57547cb2d2dbf27f42e89a8c3451b364", | ||
"2.0.0": "c9a206f6f5f4b94e1046dfaaccfe9e12d0ab8cef" | ||
}, | ||
"hashish": { | ||
"0.0.4": "6d60bc6ffaf711b6afd60e426d077988014e6554" | ||
}, | ||
"hawk": { | ||
"1.0.0": "b90bb169807285411da7ffcb8dd2598502d3b52d" | ||
}, | ||
"hoek": { | ||
"0.9.1": "3d322462badf07716ea7eb85baf88079cddce505" | ||
}, | ||
"htmlparser": { | ||
"1.7.6": "6a263c7ee5930f3e5c56fa564011f99e49f80d34" | ||
}, | ||
"http-browserify": { | ||
"0.1.1": "d9d82735a5f85f950761ac3909ba9485ec0af4f1" | ||
}, | ||
"http-signature": { | ||
"0.10.0": "1494e4f5000a83c0f11bcc12d6007c530cb99582" | ||
}, | ||
"i18n-abide": { | ||
"0.0.8": "a7610465be083a21e1c2f52e2fd78503ee90dd29" | ||
}, | ||
"iconv-lite": { | ||
"0.2.7": "45be2390d27af4b7613aac4ee4d957e3f4cbdb54" | ||
}, | ||
"inherits": { | ||
"1.0.0": "38e1975285bf1f7ba9c84da102bb12771322ac48", | ||
"2.0.0": "76c81b3b1c10ddee3a60bf2c247162bc369f8ba8" | ||
}, | ||
"irc": { | ||
|
@@ -208,8 +248,10 @@ | |
"jshint": { | ||
"0.9.1": "ff32ec7f09f84001f7498eeafd63c9e4fbb2dc0e" | ||
}, | ||
"json-stringify-safe": { | ||
"5.0.0": "4c1f228b5050837eba9d21f50c2e6e320624566e" | ||
}, | ||
"jsxgettext": { | ||
"0.0.4": "7dc442c1102ba73edfaa7fd60703ab1d03234194", | ||
"0.1.3": "db9dd0bedd531606cdd5fd978dd75d383fd99327" | ||
}, | ||
"jwcrypto": { | ||
|
@@ -229,10 +271,8 @@ | |
"mailcomposer": { | ||
"0.1.33": "69f6e924c55804f17c1bfea6c3f2f51049650820" | ||
}, | ||
"mersenne": { | ||
"0.0.3": "c39a3d45fee6091189ccd329107312ea8fe14d8a" | ||
}, | ||
"mime": { | ||
"1.2.11": "58203eed86e3a5ef17aed2b7d9ebd47f0a60dd10", | ||
"1.2.6": "b1f86c768c025fa87b48075f1709f28aeaf20365", | ||
"1.2.9": "009cd40867bd35de521b3b966f04e2f8d4d13d09" | ||
}, | ||
|
@@ -249,7 +289,6 @@ | |
"0.3.5": "de3e5f8961c88c787ee1368df849ac4413eca8d7" | ||
}, | ||
"monocle": { | ||
"0.1.46": "32ff9137fd3ee31d2d69a29db2f8a69389cd9860", | ||
"0.1.50": "9a7cbd0ccc10de95fd78a04b9beb2482ae4940b7" | ||
}, | ||
"mysql": { | ||
|
@@ -264,6 +303,9 @@ | |
"node-statsd": { | ||
"0.0.2": "ba96c26d4ec22b4f9501bb332fdf740db5a40ee7" | ||
}, | ||
"node-uuid": { | ||
"1.4.1": "39aef510e5889a3dca9c895b506c73aae1bac048" | ||
}, | ||
"nodemailer": { | ||
"0.3.21": "d9637a1d585f36fd30362c3036ce0692656fe771" | ||
}, | ||
|
@@ -280,6 +322,9 @@ | |
"nub": { | ||
"0.0.0": "b369bd32bdde66af59605c3b0520bc219dccc04f" | ||
}, | ||
"oauth-sign": { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. eh? |
||
"0.3.0": "cb540f93bb2b22a7d5941691a288d60e8ea9386e" | ||
}, | ||
"optimist": { | ||
"0.2.6": "c15b750c98274ea175d241b745edf4ddc88f177b", | ||
"0.2.8": "e981ab7e268b457948593b55674c099a815cac31", | ||
|
@@ -324,6 +369,7 @@ | |
"1.1.1": "75c97c5446fa1146c1d250c47ca3629fb9a2e764" | ||
}, | ||
"request": { | ||
"2.27.0": "dfb1a224dd3a5a9bade4337012503d710e538668", | ||
"2.9.203": "6c1711a5407fb94a114219563e44145bcbf4723a" | ||
}, | ||
"resolve": { | ||
|
@@ -352,8 +398,10 @@ | |
"slide": { | ||
"1.1.4": "2b23f1949b369ed61d22bd6570ff0320302fc8df" | ||
}, | ||
"sntp": { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. eheh? |
||
"0.2.4": "fb885f18b0f3aad189f824862536bceeec750900" | ||
}, | ||
"source-map": { | ||
"0.1.22": "425906162f81bf110552ccc9931dba079e9f1341", | ||
"0.1.25": "5851545c1f4a40243829065c20e6f40b023fba1a" | ||
}, | ||
"stack-trace": { | ||
|
@@ -371,6 +419,9 @@ | |
"traverse": { | ||
"0.6.3": "a053ffa1b6179b9240ea16d74bfd604bd6b6e41b" | ||
}, | ||
"tunnel-agent": { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and finally, eheheh? Are these all required by There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yea they are... i can switch away from |
||
"0.3.0": "ad681b68f5321ad2827c4cfb1b7d5df2cfe942ee" | ||
}, | ||
"ua-parser": { | ||
"0.2.4": "c25ef577be95350d0fe1d3361597282da4e9ba71" | ||
}, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -525,6 +525,25 @@ BrowserID.Network = (function() { | |
}); | ||
}, | ||
|
||
/** | ||
* Get infornation about a browserid-realm. | ||
* @method realmInfo | ||
* @param {string} realm - Hostname of realm to check. | ||
* @param {function} onComplete - Called with an object on success, | ||
* contained these properties: | ||
* realm: array of hostnames | ||
* @param {function} onFailure - Called on XHR failure. | ||
*/ | ||
realmInfo: function realmInfo(realm, onComplete, onFailure) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this tested via the tests for getSilentAssertion? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yea, getSilentAssertion calls User.isRealmValid, which calls network.realmInfo(realm). |
||
get({ | ||
url: "/wsapi/realm_info?realm=" + encodeURIComponent(realm), | ||
success: function realmInfo_sucess(data, textStatus, xhr) { | ||
complete(onComplete, data); | ||
}, | ||
error: onFailure | ||
}); | ||
}, | ||
|
||
/** | ||
* Remove an email address from the current user. | ||
* @method removeEmail | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need to allow the extra .* on the end? Does it give us anything?