Freecodecamp: 密码锁定/解锁按钮对于初学者来说是一个令人困惑的用户体验

创建于 2018-01-24  ·  40评论  ·  资料来源: freeCodeCamp/freeCodeCamp



问题说明

Beta版上的“代码锁定”按钮显示了第一个挑战:“向HTML元素问好”。 我认为这与最近的安全性改进有关,可以防止通过URI注入JavaScript? 无论如何,我的URI中没有代码。 URI是https://beta.freecodecamp.org/en/challenges/basic-html-and-html5/say-hello-to-html-elements。 我猜可能是因为在本地存储中找到了保存的代码? 检查本地存储中要执行的代码肯定超出了刚开始该课程的人员的能力范围吗?

既然这是第一个挑战,那无疑是令人困惑的,并且超出了初学者的专业知识来决定代码是否安全。 我们要求他们做出未经培训的决定。 作为一名经验丰富的开发人员,我什至感到困惑。 我应该寻找什么来了解代码是否受信任? 当然不是我的<h1>元素或文本编辑器中的其他内容吗?

另外,它与谈论clicking the "Run tests" button"的指令不匹配。

我们如何在保持安全的同时改善用户体验?

浏览器信息

  • 浏览器名称,版本:Chrome,63
  • 操作系统:Ubuntu
  • 移动设备,台式机或平板电脑:台式机

屏幕截图

image

UI critical path

所有40条评论

@tchaffee感谢您的报告,在此以https://github.com/freeCodeCamp/freeCodeCamp/issues/16250结尾

@raisedadead问题#16250描述了另一个问题。 我关心的是:初学者如何知道代码是否可以安全执行? 用户体验不好,因为初学者无法获得决策所需的信息。

好吧...这意味着我们在登机时需要一步一步的挑战。

@QuincyLarson您有什么想法吗?

还是重新审视我们最初提供此要求的方式? 从本地存储运行代码是否存在任何风险? 即使URI中没有代码,我也会收到警告,这似乎是不必要的警告,因为那只是我保存的工作。

我不知道此用例的背景,但我认为URI中的代码可用于共享吗? 我猜这是真正的安全风险?

也许我们可以考虑使用另一种共享代码的解决方案,而不是要求初学者确定代码是否可以安全执行。 我认为首先了解现有解决方案提供的内容以及导致我们当前解决方案的要求是值得的。 或者可能是通过URI共享代码在所有地方都是一个坏主意。

还是重新审视我们最初提供此要求的方式? 从本地存储运行代码是否存在任何风险? 即使URI中没有代码,我也会收到警告,这似乎是不必要的警告,因为那只是我保存的工作。

该要求已得到充分确立。 我们不得不在生产中解决几个XSS问题。 最近的一个需要完全阻止共享。 关于如何执行不安全代码的方法有很多。

例如,用户甚至可以从任何地方复制粘贴代码,这实际上可能导致此类问题。 当前的修补程序不会阻止这种引导,但是从技术上讲,使用警告会限制任何执行。 当然,围绕它的UX是一个问题,因此需要学习途径。

也许我们可以考虑使用另一种共享代码的解决方案,而不是要求初学者确定代码是否可以安全执行。

当然可以,为什么不呢。 请随意查看,我们很乐意提供一个解决方案,该解决方案可以扩展到当前的修复程序,该解决方案基本上是执行过程中的一个下层模块。 当然,如果您有兴趣,我们可以在PR中使用帮助。

或者可能是通过URI共享代码在所有地方都是一个坏主意。

我们已经在计划中的垃圾箱,但是随着我们准备好基础设施,垃圾箱不会很快发生。 参见https://github.com/freeCodeCamp/freeCodeCamp/issues/11263

就像这样,当用户是唯一的模型时,我们必须保持数据库的轻量级,我们计划使其逐步分离。

该要求已得到充分确立。

哪一个? 据我所知,从本地存储抓取代码为的要求之一。 这对我来说很有意义-营员不应该丢失他们已经开始工作的代码。

还有其他要求从URI运行代码吗? 我对此不太了解,这只是几周前我看到的安全问题的钟声。

它们似乎是两个不同的需求,两个不同的目标,以及不同的安全风险?

请随意查看,我们很乐意提供一个解决方案,该解决方案可以扩展到当前的修复程序,该解决方案基本上是执行过程中的一个下层模块。

我不是安全专家,但是如果我可以更好地理解要求,我很乐意尝试提出一些建议。 有人可以从Camper的角度详细描述所有要求,以及最新更改试图解决的安全漏洞吗? 另外,什么是“红外线块”?

我们有计划中的垃圾箱。

问题没有足够详细地描述该解决方案,我无法理解它是什么。 您能给我更多有关什么是“垃圾箱”以及设想的解决方案的详细信息吗?

无论如何,我不想把它变成比实际更大的东西。 也许,现在的入职挑战正确的解决方法。 但是我真的很好奇这种入职的样子。 是否可以在一开始就教Campers哪些代码应该被信任,哪些不应该被信任? 如果您有什么想法,我想看看,因为它可能比我想象的要简单。

感谢您对项目架构的好奇心。 我当然想回答您的所有查询,但是恐怕,解释该线程上的所有内容都是不够的或合理的。

我了解您可能已经开始使用它,因此,我会尽量保持清楚,但是如果有不清楚的地方,请不要提出疑问。

我将使用此查询并尝试为您提供上下文:

有人可以从Camper的角度详细描述所有要求,以及最新更改试图解决的安全漏洞吗? 另外,什么是“红外线块”?

  • 首先,在客户端的生产(freeCodeCamp.org)和登台(beta.freeCodeCamp.org)中如何评估和执行代码有很大的不同。 讨论有点超出范围,所以我建议您看一下代码。 但是,只是为了让您对过程有一个大致的了解,它以不同的方式将代码带入编辑器并在浏览器的上下文中执行(使用代码)。

  • 现在,进入露营者的视野。 想像一下您将成为一名露营者的所有场景:

    • 您可以开始在编辑器中编辑代码。
    • 您可以将代码粘贴到编辑器中
    • 您可以进行部分编辑,移至另一个挑战然后再回来。
    • 您可以访问某人的个人资料,单击查看解决方案链接,或单击论坛中的链接,等等。否则称为URI。
    • 你可以 ...
      或以上的任何组合也是可能的。
  • 在所有情况下,它都到达将分析和评估代码的同一编辑器。
  • 可以从键入的代码,本地存储或URI中进行解析。
  • 在所有情况下,都将进行一些安全检查,例如无限循环保护,在编码解决方案之前剥离和/或替换标签,然后再将解决方案发送到DB等。

  • 与否。 组合非常复杂,无法处理多种攻击媒介。

  • 那只是安全性。

  • 然后是工作流程:

    • 本地存储需要某种方式来“自动保存”工作,而不会影响数据库。
    • 之所以这样,是因为只有提交和通过的解决方案才应该进入数据库。
    • 部分解决方案(已编辑或复制粘贴),即(已提交+未通过或正在工作)必须位于本地存储中。
    • 另外,出于我前面提到的原因,数据库和本地存储之间的事务(共享/查看URI)需要进行编码/解码。

在这里,通过事务,我的意思是进入一种状态,即编辑器有代码,这是因为用户单击了个人资料或其他地方的共享链接。

加载评估解决方案的优先级是Editor > Local Storage > URI/DB

如果将方案与工作流进行比较,您可能会更了解逻辑变得多么复杂,同时避免攻击向量。

因此,如果没有明确的同意,通过代码解锁方法,全面检查将不会对所有挑战在编辑器中进行任何操作。 这是我正在考虑的基础设施。 除非有一种安全的方法可以在浏览器的隔离环境中执行所有代码,否则这无济于事。

我同意这可能对UX不利。 因此,入职可能是一种显示为什么需要这样做的方式,而不会陷入太多的复杂性并吓scar新用户。

最后,垃圾桶类似于短链接,您会看到其他位置。 例如:codepen,jsbin等。注意:这里我简化了这个想法。

这些可以帮助我们,安全地存储/查看代码,而无需当前的优先级开销。

所以,

真正的UX修复程序只是在接受挑战时解释警告。

请注意,我这里可能已经简化了一些事情。 如果您有兴趣,我建议您检出代码。 如果遇到困难,我们愿意解决在这方面的任何理解。 因此,请在此处填写任何查询。

再次重申一下:

  1. 是的,有多个要求,但是所有要求都具有相同的执行/评估和查看入口点。 因此,需要锁定/解锁。 它们都导致相同的安全风险。
  2. 到目前为止,这是对代码进入评估机制的所有传入路径的全面检查。
  3. 我们绝对需要将UX作为某种学习形式来解决:

是否可以在一开始就教Campers哪些代码应该被信任,哪些不应该被信任? 如果您有什么想法,我想看看,因为它可能比我想象的要简单。

  1. 营员为解决挑战而创建的代码(通过手动键入或从其他任何编辑器复制/粘贴)均受信任。

  2. 由其他人创建的代码(包括其个人资料中的链接)不受信任,应检查一次。 他们可以简单地检查编辑器中的解决方案是否对他们有意义。 因为,如果他们在解锁任何随机代码的同时不了解其含义,则可能会冒一些可能的安全保护措施的风险。

我们只需要准备围绕以上两点的词汇,并提出入职挑战。

希望这能给您一些背景吗? 如果没有,请随时添加更多查询。 快乐贡献!

@raisedadead您的详细解释会

它在编辑器中获取代码并在浏览器的上下文中执行代码(使用eval

那是造成安全问题的弱点。 我并不是说这是可以避免的,而只是指出,如果有人提出了提供相同功能的更安全方法,这是需要集思广益的事情。 可能不是因为一天结束时您必须执行代码。 但是,让我们对此保持开放的态度。 我会问周围。

让我们进一步了解功能和需求:

部分解决方案(已编辑或复制粘贴),即(已提交+未通过或正在工作)必须位于本地存储中。

营员为解决挑战而创建的代码(通过手动键入或从任何其他编辑器复制/粘贴)均受信任。

从上面看来,在我看来,本地存储中的代码应该受到信任,但不受信任。 有没有办法区分来​​自URI(绝对不受信任)的代码和我先前键入的来自本地存储的代码? 仅此一个很小的变化就可以使UX变得更好。 尤其是因为我们可以使消息更加具体:“您使用了带有代码的URI,您信任代码吗?”

如果可以检测到而不是信任来自URI的代码,那么我认为它很适合现有的工作流程和功能。 如果代码确实来自URI,则在用户按下“代码已锁定/解锁?”之前,我们不会将任何代码保存到本地存储中。 按钮。 在此之后,用户表明他们信任该代码,因此可以安全地将其放入本地存储中,然后在将来返回时无需警告就可以执行。

从长远来看,我绝对在质疑在URI中发送代码是否整体上不是一个好主意,以及我们是否可以找到共享解决方案和代码的更好方法。 但是,我重申这是一个长期问题,因为它需要对当前的工作方式进行一些大的更改。

他们可以简单地检查编辑器中的解决方案是否对他们有意义。

这使我确信,入职可能足够简单而有效。 “如果您在编辑器中无法识别或理解代码,请不要信任它。”

但是,如果可以区分来自URI的代码和本地存储中的代码,那么我什至在质疑是否有必要进行入门,因为在这种情况下发出警告对我而言似乎并不好。 “您刚刚使用了URI中的代码,请先解锁编辑器中的代码,然后再解锁。”

@raisedadead我不知道您之前是否见过@tchaffee ,但他是freeCodeCamp的多产贡献者。 他是一位经验丰富的开发人员,也是我们新的可测试项目背后的主要人员

好吧...这意味着我们在登机时需要一步一步的挑战。

我们不想添加更多的步骤挑战。 如果有的话,我们想摆脱现有的挑战。

这是因为人们不会阅读

我们尝试使挑战性课文尽可能简洁的原因之一是,因为课文越多,用户耐心阅读的可能性就越小。

@tchaffee是正确的-我们需要改善它的用户体验。

我建议我们仅在代码通过单击包含他人代码的URL迎接挑战时锁定代码。 否则,我们不应该警告他们有关运行代码的信息。

JSBin,CodePen,我认为这些网站都不会警告人们关于运行这样的其他人的代码。 我认为我们可以警告他们,但只有在它们可能正在运行非他们自己的代码的情况下,才可以发出警告。 否则,单击该按钮确实很烦人,并且会增加损耗。

您可以开始在编辑器中编辑代码。

无需锁。

您可以将代码粘贴到编辑器中

无需锁定(我们应该假定您已经阅读了要粘贴的代码)

您可以进行部分编辑,移至另一个挑战然后再回来。

无需锁

您可以访问某人的个人资料,单击查看解决方案链接,或单击论坛中的链接等。

这是需要锁的唯一情况。

另外,我们需要将其重新措词到不需要悬停消息的位置。 我们不在代码库中的任何其他地方使用悬停消息,也不应使用悬停消息,因为它们不适用于移动设备。 我们要使用的所有文本都应该写在按钮本身上。

basic_javascript__increment_a_number_with_javascript___freecodecamp_

我们要使用的所有文本都应该写在按钮本身上。

我认为,如果您还在按钮下方显示“为什么我的代码被锁定?”这一行的链接,则现有的按钮文本可能会起作用。 只是一个建议。

此外,如果没有其他人有时间解决这个问题,我可以尝试解决这个问题。 如果有人将我指向所有相关代码,我将需要一些帮助。 但是,如果有人更有资格和意愿,那么可以肯定的让他们来解决这个问题。

@tchaffee那太好了!

无需链接,我们只需要找出一种简洁的方法就可以用尽可能少的单词来解释它,即使按钮只有两行。 “我信任此代码。将其解锁。”

同样,我们只希望在代码不是露营者的代码时显示此按钮。

@QuincyLarson是的,尽管我也想避免加入流程,仅更新标签。

仍然留下这样一个事实,即按照当前的客户端逻辑,必须实现仅阻止非用户代码的实现。

我的意思是按钮"I trust this code. Unlock it."仅在代码来自URI等时才能够显示的逻辑,仍然需要实现。

我将添加PR来更新标签并关闭其他问题https://github.com/freeCodeCamp/freeCodeCamp/issues/16250

仍然留下这样一个事实,即按照当前的客户端逻辑,必须实现仅阻止非用户代码的实现。

不知道这在哪里留下了实施新行为的要约。 我可以尝试实现仅阻止非用户代码的功能,但是现在似乎不是正确的时机? 有人可以澄清一下吗?

我将需要仔细检查,这是如何工作的,以便为您提供具体的操作准则,同时,我会将@BerkeleyTrue标记为他的输入。

我的意思是按钮“我信任此代码。将其解锁”的逻辑。 以便仅当代码来自URI等时才可以显示。

@raisedadead是的-我同意你的看法。 这样做很重要,它将挽救成千上万的露营者的理智。

我已将其移至Beta版看板中的“关键路径”: https : =true

如果有人可以指出相关代码的各个部分,我仍然很乐意尝试一下。 我敢肯定自己会找到它,但是如果有人已经熟悉了该代码,它将节省一些时间。 有人可以让我知道这是什么状态吗?

@tchaffee感谢您的耐心配合。

@Bouncey您知道此逻辑在代码库中的位置吗? 您能将@tchaffee指向正确的方向吗?

@tchaffee

您可以使用pathnameSelector检查URI。

您可以通过将其传递到SidePanel组件mapStatetoProps方法中来使用它,然后可以从此处与ToolPanel组件进行交互

希望这可以帮助👍

我开始看这个,我有一个问题。 有人可以举例说明如何执行以下操作:

您可以访问某人的个人资料,单击查看解决方案链接,或单击论坛中的链接,等等。否则称为URI。

在测试版网站上,我只看到解决方案的弹出窗口,而没有URI加载代码。 所以貌似Beta发生了变化? 还有其他可以从URI加载代码的地方吗? 有人可以指出我的示例URI吗?

谢谢!

@tchaffee是正确的,此用例不再有效:

您可以访问某人的个人资料,单击查看解决方案链接,或单击论坛中的链接,等等。否则称为URI。

现在确实已将其替换为模式,从而使其比必须在编辑器中解析URI更为安全。 因此,我认为从URI加载不再是图片。

现在,这使我们进入代码锁定/解锁。 那就是应该显示按钮的时间。

我可以想到以下几种情况:

  1. 营员可以从地图上重新访问挑战。
  2. 在这种情况下,代码将从本地存储(如果有)中加载到编辑器中。
  3. 或者,它将从后端获取,添加到本地存储,然后放置在编辑器中。

现在,在理想情况下,这种情况将归露营者所有。

但是,无论有什么可能性,都是将代码加载到编辑器上并执行。 这给我们留下了可以执行不安全代码的地方? 至少这是我可以看到的向量。

因此,我们必须确保Camper知道要执行的操作并在获得明确同意的情况下完成。

因此,我想仍然阻止从本地存储或后端(非用户代码)阻止代码的部分。 但是,有了它,我想了一些不必要的按钮。

如果非用户代码不是原始种子代码或露营者输入的东西(用户代码),则应该可以锁定非用户代码,即不执行它。

@Bouncey @BerkeleyTrue我在这种观点上正确吗?

哦,是的,唯一需要注意的是URI解析仍然可用,并且无处可去,因为质询编辑器不知道我们拥有带有解决方案模式的反应配置文件视图这一事实。

如果有时间,我将尝试分享一个示例URI。

但是,无论有什么可能性,都是将代码加载到编辑器上并执行。 这给我们留下了可以执行不安全代码的地方?

我会说不是。 如果露营者从其他地方复制/粘贴代码,则必须由他们来确保他们理解该代码,并且该代码是安全的。 这种方法还可以奖励诚实并惩罚作弊行为-如果您不了解复制的代码是什么,则永远不要粘贴它。 如果您不理解它,显然您自己不会写它,因此造成的任何损害都是真正作弊的结果。

第一次将代码带入编辑器只有两种“诚实”的方式?

  1. 复制/粘贴您了解并可能已经写过的东西。
  2. 自己输入代码。

何时将其保存到本地存储或后端?

任何来自本地存储或后端并置于编辑器中的代码都必须首先来自上述方法之一。 因此,始终可以将本地存储或后端中的代码视为安全代码。

如果非用户代码不是原始种子代码或露营者输入的东西(用户代码),则应该可以锁定非用户代码,即不执行它。

根据以上情况,IMO无需这样做。

URI解析仍然可用,并且无处可去,因为质询编辑器不知道我们拥有带有模式化解决方案的React Profile视图的事实。

这是我能想到的唯一不安全的媒介。 如果可以举个例子,我将尝试检测到此情况,仅在这种情况下显示“解锁”按钮。

当然,如果我错过了一些事情,请纠正我。

是的,您声明的前两点是锁定代码的最小情况,我同意。 虽然理想情况下我们应该阻止它。 这是一件昂贵的事情。

何时将其保存到本地存储或后端?

只要编辑器中提供了任何代码,便会保存它。 因此,复制粘贴和键入已算在内。

这是我能想到的唯一不安全的媒介。 如果可以举个例子,我将尝试检测到此情况,仅在这种情况下显示“解锁”按钮。

这是唯一需要处理的情况。 再次,这不是现在的优先事项。 当我们的解决方案是通过URI从第三方集成到我们的Web应用程序时,就可以说是这种情况。

因此,进行检查就足够了,正如您正确地指出的那样,我们应该仅对此进行智能阻止。

我将尽快分享一个示例URI。 (如果有能力,请Stuart,但请随时击败我)

@raisedadead感谢您的澄清。 我同意我们只应在用户首次加载挑战并且URL中包含代码参数时锁定按钮。 在所有其他情况下,我们不应该锁定代码,而应该在用户单击按钮或第一次单击ctrl + enter时运行它。

只要有人可以在URL中给我提供示例代码,我就可以开始进行处理。

@tchaffee我们在这里测试URI中的代码。

您可以像这样分派一个动作来将代码锁定在if块中

return Observable.of(
  makeToast({
    message: 'I found code in the URI. Loading now.'
  }),
  storedCodeFound(challenge, finalFiles),
  // lockTheCodeAction()
);

在我们可以获取代码URI之前,它应该使您保持工作效率

@tchaffee这是一个示例URL: http:// localhost :3000 / challenges / Check%20for%20Palindromes?solution = function%20palindrome(str)%20%7B%0A%20%20str%20%3D%20str.toLowerCase ().replace(%2F%5B%5CW_%5D%2Fg%2C%20%27%27)%3B%0A%20%20for(var%20i%20%3D%200%2C%20len%20%3D %20str.length%20-%201%3B%20i%20%3C%20len%2F2%3B%20i%2B%2B)%20%7B%0A%20%20%20%20if20(str%5Bi%5D %20!%3D%3D%20str%5Blen-i%5D)%20%7B%0A%20%20%20%20%20%20return%20false%3B%0A%20%20%20%20%20%7D %0A%20%20%7D%0A%20%20return%20true%3B%0A%7D

这将导致http:// localhost :3000 / challenges / check-for-palindromes URL并填充以下代码:

function palindrome(str) {
  str = str.toLowerCase().replace(/[\W_]/g, '');
  for(var i = 0, len = str.length - 1; i < len/2; i++) {
    if(str[i] !== str[len-i]) {
      return false;
    }
  }
  return true;
}

@QuincyLarson谢谢。 我很犹豫,无法测试我的工作就开始工作。 我可以留出一些时间来看看这个。

@tchaffee太棒了! 很高兴我能帮助你。 请让我知道我是否可以采取其他措施来保持您的畅通:)

我需要使用的实际URL是http:// localhost :3000 / zh-CN / challenges / javascript-algorithms-and-data-structures-projects / palindrome-checker?solution = function%20palindrome(str)%20%7B%0A %20%20str%20%3D%20str.toLowerCase()。replace(%2F%5B%5CW_%5D%2Fg%2C%20%27%27)%3B%0A%20%20for(var%20i%20 %3D%200%2C%20len%20%3D%20str.length%20-%201%3B%20i%20%3C%20len%2F2%3B%20i%2B%2B)%20%7B%0A%20 %20%20%20if(str%5Bi%5D%20!%3D%3D%20str%5Blen-i%5D)%20%7B%0A%20%20%20%20%20%20%20return%20false%3B %0A%20%20%20%20%7D%0A%20%20%7D%0A%20%20return%20true%3B%0A%7D

只是将其放在此处作为文档。 无需评论。

@Bouncey您能指出一些执行动作的现有代码吗? 谢谢。

当然

从组件内部

史诗般的单一动作

一部史诗的多项动作

希望这会有所帮助:+1:

编码愉快!

我认为,就代码沙盒而言,所有这些锁定/解锁都不是最好的主意。 相反,我认为您应该在其他来源的iframe中评估代码,以确保无法与Camper的会话进行交互。

(除了但略微相关):向freeCodeCamp报告潜在安全问题的首选方法是什么?

@ joker314请随时给我发送电子邮件[email protected]

请注意,此问题已被问题#16904阻止

由于这个问题最近一直没有解决,因此我将其过时的关闭。 如果您认为这仍然与新更新的平台有关,请说明原因,然后重新打开它。

此页面是否有帮助?
0 / 5 - 0 等级