07:00:05 <KateChapman> #startmeeting RFC meeting 07:00:05 <wm-labs-meetbot> Meeting started Thu Dec 6 07:00:05 2018 UTC and is due to finish in 60 minutes. The chair is KateChapman. Information about MeetBot at http://wiki.debian.org/MeetBot. 07:00:05 <wm-labs-meetbot> Useful Commands: #action #agreed #help #info #idea #link #topic #startvote. 07:00:05 <wm-labs-meetbot> The meeting name has been set to 'rfc_meeting' 07:00:16 <KateChapman> #topic Proposal for partial opt-out method for Content security policy https://phabricator.wikimedia.org/T208188 07:00:45 <bawolff> Woo 07:00:45 <KateChapman> who has joined us to discuss this RFC? 07:01:05 <TimStarling> o/ 07:02:22 <KateChapman> as a reminder the #link #action and #info tags are useful to get things into the minutes 07:02:24 <bawolff> Guess its just us two? 07:02:51 <KateChapman> duesen I believe is also joining 07:04:04 <_joe_> \o 07:04:11 <_joe_> I am here, sorry 07:04:35 <KateChapman> bawolff are there are parts of the discussion on the ticket you were hoping to get clarity on today? 07:04:56 <KateChapman> there were also a couple items that came up in the TechCom meeting today that we can bring forward as well 07:05:30 <bawolff> I think the main thing I want to establish is what the minimum viable product requirements would be for an opt out measure, so that we can start enforcing CSP generally 07:05:35 <RoanKattouw> I'm also here, sorry needed to take a break between my 10pm meeting and this 11pm meeting :| 07:06:21 <TimStarling> in the committee meeting we talked a bit about the UX 07:06:33 <RoanKattouw> Having read through the task there was some discussion about blanket allowing and/or disallowing some domains in the MW config, and I think both of those are good ideas 07:06:58 <RoanKattouw> In the committee meeting we talked about a blanket disallow that overrides any user preferences being a good idea for when we discover bad/compromised domains 07:07:24 <bawolff> FWIW, I don't think we should blanket allow external domains (i.e. archive.org) like Cyberpower was suggesting, if that's what you are referring to 07:07:27 <RoanKattouw> But I also think there might be promise in a global allow list that popular WMF-operated domains (e.g. some Toolforge tools) can be on 07:07:57 <RoanKattouw> Hmm no I agree we shouldn't blanket allow archive.org or other 3rd party domains, also for Privacy Policy reasons 07:08:02 <_joe_> RoanKattouw: I don't think toolforge qualifies as a secure hosting of services 07:08:03 * duesen is around, but in need of coffee and breakfast 07:08:09 <RoanKattouw> I'm now less sure about whether blanket allowing a list of tools is a good idea 07:08:29 <_joe_> RoanKattouw: it's incredibly easy to host a malicious application on toolsforg 07:08:32 <bawolff> I'm also not really a fan of blanket allowing toolforge. Its so easy for just anyone to create a tool there, its basically a public host 07:08:40 <_joe_> bawolff: :) 07:08:45 <RoanKattouw> _joe_: You're right, and that's why Brian proposes banning users from allowing *.wmflabs.org or tools.wmflabs.org/* 07:09:13 <_joe_> bawolff: I was suggesting we could use the safe browsing lists out there as blacklists too 07:09:16 <RoanKattouw> And instead proposes forcing people to specify individual labs subdomains and individual tools 07:09:37 <duesen> +1 to that 07:09:42 <bawolff> And from a privacy perspective, in theory toolforge is not covered by the same privacy policy, so from a privacy perspective, I think ideally we'd want an explicit consent by the user 07:09:48 <RoanKattouw> Right, I was about to say that too 07:10:03 <duesen> makes config more complex, but I suppose we can handle ugly regexes 07:10:37 <RoanKattouw> In an ideal world I'd like toolforge and labs domains to be a quick interstitial and have much more friction for "real" 3rd party domains 07:10:48 <RoanKattouw> But you're looking for something that can be implemented more quickly I think 07:11:14 <TimStarling> the proposal in general is a bit uninspiring, this is not the glorious future, this is a thing to make user scripts not suck quite so much, right? 07:11:28 <KateChapman> #info <bawolff> And from a privacy perspective, in theory toolforge is not covered by the same privacy policy, so from a privacy perspective, I think ideally we'd want an explicit consent by the user 07:11:33 <bawolff> From my perspective this is more something necessary to reach my real goal of CSP enforcement 07:11:34 <_joe_> RoanKattouw: not really, in terms of security isolation, we treat labs/tools as "external world" from production, our applications should do the same 07:12:02 <_joe_> TimStarling: that was my understanding too, yeah 07:12:12 <duesen> I have a question about transitioning: if I'm usinx gadget X, which did not used to require access to an external resource, but is changed to now require it, what happens? does it break? is it disabled, and I have to re-enable it? how does this happen? how do I notice? 07:12:41 <bawolff> I think it being disabled and having to be re-enabled would really be the only solution 07:12:48 <bawolff> Just having it break seems terrible UX 07:12:56 <TimStarling> in the glorious future I would like scripts (gadgets?) to go through a review process before they can be shared, and the review would presumably include reviewing the CSP domain list 07:13:09 <bawolff> and silently enabling kind of defeats the point of a privacy consent 07:13:11 <duesen> ideally, the user woould get an echo notification or something. not sure how that is supposed to work. 07:13:53 <bawolff> maybe get something in console.log(). But nobody will check that, but there is precedent for doing that for non-RL gadgets 07:14:00 <RoanKattouw> Auto-disabling such a gadget would require having the CSP list in the Gadget metadata, which I thought was already kind of beyond what's being proposed here 07:14:10 <duesen> but i'm also not sure how the disabling should work. perhaps the array that encodes which gadgets are enabled needs to be checked against the list of permissions that gadget requirees. 07:14:12 <_joe_> bawolff: during the comitee discussion, I stressed how people have been trained by their smartphones and cookie/gdpr popups to auto-allow anything they're asked for 07:14:20 <RoanKattouw> (although I think it's probably a good idea) 07:14:27 <_joe_> we should try to avoid it in our UX 07:14:43 <duesen> RoanKattouw: in the gadget meta data and in the user prefs for each gadget... 07:14:52 <RoanKattouw> So, how workable do we think a purely MW config-side CSP list would be? 07:15:02 <RoanKattouw> All gadgets and popular user scripts would have to request exemptions through the security team 07:15:08 <bawolff> RoanKattouw: I think there's a compelling usecase for gadget metadata. I'm willing to implement that if that's what's needed 07:15:22 <duesen> bawolff: did you have any specific mechanism in mind for mass-disabling gadgets upon such a change? 07:15:25 <TimStarling> there's no mention of gadgets in the task description, only in the comments, which I think makes it not part of the RFC unless it is amended 07:15:46 <bawolff> _joe_: You're definitely right...but I don't think there are a lot of better solutions 07:16:20 <RoanKattouw> Well right now the RFC proposes making a special page where users can add CSP exemptions for themselves, and in that world (without further features) certain gadgets would not work without the right exemptions being set by the uesr 07:16:37 <duesen> TimStarling: good point. gadgets should probably be mentioned explicitly. they are the main use case. if they are not covered by this rfc, they would need to be covered by a follow-up. 07:16:38 <bawolff> RoanKattouw: My personal opinion is pure server side config is not scalable 07:16:38 <RoanKattouw> So it doesn't explicitly mention gadgets but it's definitely a very related topic 07:17:43 <RoanKattouw> Fair enough re scalability 07:17:46 <bawolff> duesen: So sort of a late addition, but what my first thought would be, is all your exemptions are in a table, and at run time if the gadget needed exemptions don't match the user's list of allowed exemptions, then the gadget doesn't run, user is given some notice 07:18:24 <TimStarling> android now has fine-grained permissions, which I think is a nice model, i.e. gracefully degrade a gadget's functionality if it's not allowed to contact a domain 07:18:29 <duesen> bawolff: that would woork, though I'm worried about performance. would need to be cached in the user session, probably. 07:18:31 <RoanKattouw> Hmm OK I see, that wouldn't be hard to do. And the preferences page for Gadgets could show you which ones you're missing too 07:18:59 <TimStarling> it used to be "accept location access or don't install the app" but now apps are expected to degrade without location access instead of being uninstallable 07:19:10 <duesen> anyway, doing this manually via the special page seems to be the baseline. integrating the with gadget meta data wouldd be the next step. we'd still need the special page to allow this to function with user scripts. 07:19:15 <RoanKattouw> Re fine-grained permissions, there were some proposals in the task to add a JS API that lets code find out whether a certain domain is exempt, and/or request an exemption for a domain 07:19:16 <bawolff> That's definitely another option. In theory we could do nothing and hope the extension catches SecurityException or whatever the JS exception is that CSP is supposed to throw 07:19:45 <duesen> as roan pointed out during the techcom meeting, the opt-in is needed for user scripts at least for testing and development of gadgets, if nothing else 07:20:08 <RoanKattouw> Yeah, I kind of wanted to make this a gadget metadata thing and then not allow custom CSP lists for user scripts, but that makes development hard 07:20:17 <bawolff> I think JS is supposed to throw an exception on attempting to access a blocked site. I'm not sure if that's actually true 07:20:26 <TimStarling> #info add a JS API that lets code find out whether a certain domain is exempt 07:20:34 <TimStarling> that is a simple and useful addition 07:20:40 <_joe_> +1 07:20:41 <RoanKattouw> bawolff: If it works anything like CORS, it'll just be a rejected promise 07:21:02 <RoanKattouw> Although I guess the fact that you're trying to access a blocked domain can be determined synchronously, whereas CORS failures are async 07:21:27 <RoanKattouw> so maybe it works differently, idk 07:21:35 <bawolff> The spec seems to suggest a SecurityPolicyViolation event is triggered 07:21:44 <bawolff> In a very quick skim 07:21:57 <TimStarling> a gadget should be able to remove a button from a UI if a domain is not supported, that's not possible if it has to actually send the request before it can find out if it will work 07:21:58 <bawolff> https://www.w3.org/TR/CSP3/#violation-events 07:22:28 <duesen> #info a user's CSP list will probably have to be cached in the user session, to avoid performance issues with checking the CSP needs of all gadgets against the database on every request. 07:22:38 <KateChapman> #link https://www.w3.org/TR/CSP3/#violation-events 07:23:14 <duesen> #info "nice" integration with gadgets would be good, but is out of scope for the initial rfc. 07:23:20 <_joe_> duesen: I don't think doing a select for a whitelist of urls is really an issue in terms of performance 07:23:42 <_joe_> duesen: at worst, it's a couple milliseconds more than deserializing those data from the session storage 07:24:01 <_joe_> btw, we're talking a lot about domain whitelisting, which I find problematic 07:24:12 <_joe_> I would very much prefer to have per-url whitelisting 07:24:20 <duesen> #info blanket excempts are probably a bad idea, blanket bans are needed, so ops can react to compromized sites 07:24:43 * duesen wonders off to get coffee 07:24:55 <bawolff> We could definitely do it more fine-grained 07:25:03 <RoanKattouw> _joe_: You'll likely need to have at least path-based stuff for certain APIs (e.g. RESTbase) 07:25:13 <RoanKattouw> I mean, for APIs that use the same structure as RESTbase 07:25:38 <RoanKattouw> You would also need to allow query strings to vary 07:25:44 <_joe_> RoanKattouw: think of github.com :) 07:26:01 <_joe_> whitelisting all of github.com would make little sense, right? 07:26:16 <RoanKattouw> I agree, but the fine-grainedness has to stop somewhere, and I'm not sure that's a determination that code can make 07:26:43 <RoanKattouw> Because we also can't require the exact URL to be specified for APIs that use the path to express parameters like RESTbase does 07:27:04 <_joe_> RoanKattouw: a regex, yes 07:27:06 <bawolff> The idea would be you can whitelist ajax requests, but not execute foreign scripts (but that's hard to enforce technically given eval()) 07:27:24 <bawolff> We can't really do regexes here 07:27:28 <RoanKattouw> Sure, but you can't write code that disallows regexes that would match github.com/* but allows regexes that are "sufficiently specific" 07:27:34 <bawolff> As the csp rule is interpreted on the client side 07:27:36 <_joe_> bawolff: prefix urls? 07:27:41 <_joe_> bawolff: right 07:27:43 <bawolff> yes, we can do prefixes 07:27:53 <_joe_> ok then, it's basically what you need 07:27:55 <RoanKattouw> OK prefixes are fine 07:28:21 <_joe_> so you can authorize github.com/<someone> if you trust them 07:28:34 <RoanKattouw> My main point is, there's no good way to police people about being sufficiently specific with their prefixes. If someone wants to whitelist github.com they can. They shouldn't, but we can't stop them really 07:28:42 <bawolff> Yes. in csp if the url ends in a / its considered a prefix 07:29:24 <RoanKattouw> (Except for a few cases that we could configure enforcement for, like no whitelisting all of wmflabs.org or all of Toolforge, and maybe Github could be added to that list) 07:29:49 <bawolff> One of the main goals is to isolate silly behaviour. Maybe someone can whitelist all of github.com, but at least not all users would have it whitelisted 07:31:06 <TimStarling> it could be limited like how cookie domains are limited, i.e. you can't have *.com.au but you can have *.tcl.tk 07:32:04 <duesen> RoanKattouw: that could be done with a ban rule. you ban /github\.com\/*$/. 07:32:17 <TimStarling> or do we not want any domain wildcards? you could just have path wildcards 07:32:22 <duesen> with the $ being the important bit 07:32:38 <KateChapman> *** time check about 1/2 way through (30 minutes left) *** 07:32:57 <bawolff> I'm thinking there would just be hook in the special page, where server side config could put any limitations on allowed urls that we see fit 07:33:06 <RoanKattouw> duesen: Yeah we'd need that to enforce the rules around labs/Toolforge anywya 07:35:00 <bawolff> On the subject of a global blacklist so we can revoke compromised domains, I'm not sure I think that's a necessary feature for a first version.I think that would be super rare [main thing is to make wikimedia a less appealing target by making it so you can't run your scripts on all users] In that sort of emergency situation we could probably just manually modify the db 07:35:14 <bawolff> or maybe do some server side config 07:35:32 <bawolff> I definitely don't think we need something like MediaWiki:Spamblacklist but for csp domains 07:35:33 <RoanKattouw> Yeah I was suggesting it as a server-side config that would override per-user lists 07:35:38 <bawolff> ok 07:35:52 <RoanKattouw> Like, a list of domains that do not get CSP no matter what the user's settings say 07:36:19 <TimStarling> so are we approving plan Dismal Present a.k.a. phab task description? Or are we giving up on that and going straight to Glorious Future? figuring out where to take this conversation 07:36:28 <duesen> #info opt-in should be per prefix, but blanket bans should be based on regexes, so they can be used to force prefixes to be sufficiently specific (e.g. ban toolforge and github if no project is specified) 07:36:32 <RoanKattouw> Yeah I was about to ask something similar 07:36:58 <RoanKattouw> It sounds like "plan Dismal Present" is something like "add a special page where users can configure CSP exemptions, require them to manually add them for any gadget/user script they want to use that needs them" ? 07:37:08 <TimStarling> yes 07:37:26 <bawolff> Honestly, I have limited time to devote to this. I would prefer plan dismal, but am willing to do plan glorious future if that's what is needed to get CSP enforcing on our sites 07:37:31 <TimStarling> with a global exemption list for common.js 07:37:57 <duesen> i think this is fine as a baseline. we'll need this anyway, so people can easily get an overview of what they allowed, and to revoke excemptions 07:38:08 <RoanKattouw> And then slightly more glorious futures would involve one or more of: adding CSP domains to gadget metadata, interstitials, clever management inthe Gadget extension 07:38:35 <bawolff> I think the suggestion that scripts have some way of determining what domains they are allowed, may need to be a requirement for plan dismal, so that gadget authors can have sane fallback behaviour 07:38:35 <RoanKattouw> One minor feature that could more easily be added is the JS API we mentioned to check if a domain is allowed or disallowed 07:38:46 <RoanKattouw> Yes I think that would be a very nice to have at the lesat 07:39:03 <duesen> TimStarling: do we actually want to allow exemptions in common.js? Is that even coompliant with the privacy policy? 07:39:13 <duesen> my gut feeling is no. 07:39:18 <TimStarling> in plan dismal what is the migration path? how do you start enforcing this for existing user scripts? 07:39:42 <RoanKattouw> I would strongly discourage code that needs CSP exemptions from being in common.js or default-enabled gadgets 07:39:44 <TimStarling> duesen: maybe just in MW config 07:39:47 <bawolff> Basically I think we give community some notice, and have script authors update their instructions 07:40:16 <RoanKattouw> Would we have a log-only phase as well? 07:40:30 <duesen> TimStarling: we'll want that for 3rd party use. not sure wmf wants to actually put something there. that would be up to legal. 07:40:38 <bawolff> We're basically already in a log only phase, just without the opt-out 07:41:09 <bawolff> I also agree that common.js code should not be calling other domains. pretty sure that's not cool with the privacy policy 07:41:09 <TimStarling> if you add the JS query API (I still think it is a good idea) then popular user scripts can warn the user to add the exemption even before we start enforcing 07:41:25 <bawolff> yes, that sounds good to me 07:42:00 <duesen> #info 3rd parties will want site-wide blanket exceptions. we can have them as config. if and how wmf sites can use that needs to be checked with legal. 07:42:12 <bawolff> Yes 07:42:48 <bawolff> And longer term, I think even something like OutputPage::addCSPDomain() would make sense, to allow extensions to add per page exemptions (I've already had someone ask about integrating the recaptcha extension with this) 07:42:51 <TimStarling> so the RFC should go to last call with the understanding that it will be as documented in the phab task description, plus a JS API? 07:43:08 <bawolff> yes 07:43:11 * bawolff hopes 07:43:39 <duesen> re migration... if this is implemented without "nice gadget integration", we'll break a bunch of gadgets when this goes live. and people have to figure out how to manually exempt the prefixes these gadgets need. 07:44:04 <bawolff> One other thing I wanted to get feedback on - everyone is cool with the idea that the exemptions are only to access data, and not for executing scripts? (I know that's not enforcible technially, given eval(), but it can be enforced socially partially) 07:44:21 <duesen> whether this is acceptable from a ux perspecctive is unclear to me. from a technical standpoint, it's a decent baseline, on which nicer features can be built later 07:45:00 <bawolff> I think some outreach can be done, we already have a list in logstash of commonly accessed domains, so probably I could do some outreach to the most commonly used gadgets that do this, to ensure they are ready 07:45:30 <KateChapman> 15 minutes remaining 07:45:40 <TimStarling> if popular gadgets pester users to add exemptions, it creates a migration problem to Glorious Future in that we won't know what gadget caused a given exemption to be added 07:45:52 <TimStarling> those exemptions will stay in a user's preferences forever 07:46:12 <TimStarling> we can't tell the user that it's not necessary anymore because it's been superseded by gadget metadata, we won't know that 07:46:31 <RoanKattouw> bawolff: Yes I am very OK with that, in fact I'm curious what would need to happen for us to be able to disallow eval and inline scripts 07:46:32 <bawolff> hmm, that is unfortunate 07:46:43 <RoanKattouw> (my understanding is you'd need to disallow both) 07:46:45 <TimStarling> maybe there should be a "reason" or "notes" field in the table, like an edit summary 07:46:47 <bawolff> RoanKattouw: Kill RLStorage is the big one 07:47:01 <RoanKattouw> Right, I know that's an eval() case 07:47:17 <TimStarling> so that users can make a note as to why they added an exemption 07:47:22 <RoanKattouw> For inline scripts we have the nonce stuff, right? 07:47:40 <bawolff> There would be a lot of migration pain in terms of user js. in terms of MW js though not so much. Some uses of javascript: url scheme 07:47:49 <duesen> TimStarling: it's easy enough to check a user's exemptions aggainst the meta-data of all gadgets that the user had enabled. 07:48:10 <duesen> TimStarling: so the special page can, in the glorious future, tell the user which gadgets uses which exemption. 07:48:28 <TimStarling> fine, but my suggestion is still to add a free text reason field to csp_sources 07:48:59 <duesen> (by the way - "excemption" and "opt-out" are very technical and misleadinng here. The user optiosn *into* using an external resource, resp grants permission to use it) 07:49:36 <bawolff> That would still be very hard to parse in an automated way, unless we are hoping that the user will just disable stuff they no longer need in the glorious future 07:49:49 <TimStarling> the idea is that the user will disable it manually 07:50:01 <TimStarling> it just gives diligent users a way to maintain their list 07:50:20 <duesen> TimStarling: a reason field may be ok, but if populated automatically, we may need to normalized it soon (using a comment table, probably) 07:50:26 <duesen> anyway 07:50:51 <duesen> i think kthe proposal needs to mention blanket bans. other than that, it seems ok to me, if a bit basic 07:50:57 <KateChapman> 10 minutes left. Anything else that remains to be discussed? 07:51:21 <KateChapman> bawolff is it clear to you what changes need to happen? 07:51:22 <TimStarling> should it go to last call now or after the recommended changes have been made to the task description? 07:51:39 <bawolff> #info have a reason field added to the CSP list 07:51:58 <_joe_> as far as the UX is concerned, I'd ask people with expertise in that area to help 07:51:59 <TimStarling> I am fine with going to last call now if there are no objections 07:52:12 <_joe_> if we want anything more refined than a special page 07:52:23 <bawolff> KateChapman: Add the JS api to see what the user's csp config is 07:52:28 <duesen> #info <duesen> i think the proposal needs to mention blanket bans, if only to prevent people from exempting all of github, or all of toolforge 07:52:38 <bawolff> KateChapman: Add a reason field, mention strategy for blanket bans 07:52:43 <bawolff> Did i miss anything? 07:53:15 <KateChapman> #action 11:52 PM <bawolff> Add the JS api to see what the user's csp config is 07:53:41 <KateChapman> #action 11:52 PM <bawolff> Add a reason field, mention strategy for blanket bans 07:55:12 <KateChapman> bawolff did you want to add those items prior to going to last call? 07:55:35 <KateChapman> TimStarling: do you want those items to be added first? Or does that not matter for Last Call? 07:55:57 <bawolff> I think I should add them prior to it going to last call 07:56:11 <bawolff> last call is supposed to be the final version of the RFC, right? 07:56:14 <duesen> at least the blanket bans need to be in the proposal, since they are security relevant 07:56:28 <_joe_> +1 07:56:30 <TimStarling> probably best bawolff, last call means advertising it on wikitech-l 07:56:45 <bawolff> ok, I'll try and get that done tomorrow 07:57:10 <KateChapman> bawolff then we'll likely add it to Last Call in the next TechCom meeting next Wednesday 07:57:24 <bawolff> Awesome :) 07:57:27 <KateChapman> anything else? (3 minutes left) 07:57:51 <bawolff> Thanks everyone for participating 07:58:48 * duesen notes that rolling this out WILL break a buncch of gandgets without any good way of telling the user how to fix themö. 07:59:12 <KateChapman> thanks all 07:59:42 <_joe_> have a nice day/evening/sleep :) 07:59:46 * duesen waves 07:59:47 <KateChapman> #endmeeting