加固遗留 Rails 应用程序的第一步是啥?

     2023-04-14     210

关键词:

【中文标题】加固遗留 Rails 应用程序的第一步是啥?【英文标题】:What are the first steps in hardening a legacy Rails application?加固遗留 Rails 应用程序的第一步是什么? 【发布时间】:2015-10-30 05:41:18 【问题描述】:

有一个生产系统已经运行了很多年,最初是作为 PHP 应用程序,然后是与 Rails 的混合体,现在完全在 Rails 中。目前还不清楚它已经存在了多久。最早的 git commit 是 5 年前的。

目标是不惜一切代价保持系统运行。只要没有中断,我们使用什么代码都没有关系。目前是 Rails 版本3.2.33

如果我们不升级任何宝石,我们就有可能变得过时且无法部署。如果我们升级,我们将需要对代码进行更改,从而导致潜在的错误蔓延。我们不仅面临代码腐烂,而且还面临由于 AWS 中断而导致的停机。

确保万无一失的第一步是什么?我花了几个月的时间编写黄瓜(集成)测试,但很难涵盖所有边缘情况。该应用程序已经运行了很长时间,以至于大多数错误都已修复,并且几乎没有新的例外情况。测试从一开始就不是优先事项,因此大部分代码都没有记录。

【问题讨论】:

硬化到底是什么意思?安全吗? 另外,新功能还在增加吗? 我的意思是加强对任何可能的服务中断的影响。这包括安全相关问题、正常运行时间/可用性和一般维护。 多年来没有添加任何新功能。不太可能添加任何主要的新功能。 【参考方案1】:

老实说,我发现 Ruby on Rails 并不适合这种应用程序。 Ruby 和 Rails 都有一个非常激进的发布计划,而且 Rails 尤其不怕放弃向后兼容性。 Rails 非常适合敏捷开发,其中事物总是在变化,但会以长期稳定性为代价。

我假设您的应用程序足够大,以至于您不想切换到其他任何东西。例如,Sinatra 并没有太大变化,而且会是一个更稳定的选择。

如果您坚持使用 Rails,我建议您摆脱尽可能多的 gem 依赖项。它们总是存在不再被开发或者可能引入错误或漏洞的危险。

此外,最好尽可能使用 PORO(普通的旧 Ruby 对象)而不是依赖于 Rails 的代码。这通常需要更多的工作,但您最终会得到更稳定和可重用的代码。

我意识到这可能比你想在这样的应用程序中投入更多的工作,但这是我最好的建议。

【讨论】:

我的经验证实了你所说的。这是一项艰巨的任务,因为开发人员倾向于在开始时使用尽可能多的 gem 来快速完成工作。宝石质量参差不齐,但通常比本土解决方案更好。几乎总是这样,此应用程序将从更高的代码质量标准中受益最多。【参考方案2】:

第一步是为 gem 文件中使用的所有 gem 放置特定的 gem 版本。

例如

 gem 'rspec-rails'

可能变成

 gem 'rspec-rails', '2.14.1'

您可以通过查看您的 Gemfile.lock 来确定当前正在使用哪些版本,例如,Gemfile.lock 中的这一行显示了为 rspec 选择的版本:

rspec (2.14.1)

即使 Gemfile 没有版本,例如

gem chronic

Gemfile 有使用的版本,例如

chronic (0.10.2)

如果我们不升级任何宝石,我们就有可能变得过时且无法部署。如果我们升级,我们将需要对代码进行更改,从而导致潜在的错误蔓延。

是的,这就是你的困境。没有任何魔法,您必须选择要解决的这两个优先事项中的哪一个。正如 aNoble 所指出的,RoR 不是一个可以“原地不动”的框架。组成大多数应用程序的 gem 不断变化意味着 RoR 应用程序不能很好地老化。

您应该向项目所有者解释并重复、重复、重复。通常这是“接受”的那种原则——但不是真的——因为同样的问题继续被问到“尽管如此,我如何升级它,我如何确保没有任何变化或中断等。”

如果应用程序将在几个月后停用,没问题。如果没有真正的计划来终止应用程序并且它将继续成为业务的重要组成部分,那么您只需要使用资源来维护它。在 RoR 土地上没有免费的午餐。

【讨论】:

升级不是项目所有者的优先事项,但如果代码腐烂它会。所以我们需要在及时升级和稳定性之间找到平衡。 安全也是一个问题,所以我们需要查看每个 gem 的更新日志,看看当前版本是否有任何漏洞。【参考方案3】:

编写许多测试是关键的第一步,很高兴看到这一点。检查您的语句覆盖率,看看您是否缺少对重要代码区域的测试,并确保您有涵盖关键序列的集成测试。我们的想法是修改您的测试,以降低更改导致用户可见故障的风险。

现在在某些系统上设置连续测试。

设置您的 Gemfile 和 .ruby-version,以便您可以具体控制加载所有内容的确切版本。这不会自动更新 - 但它确保您可以控制您更新的内容。签入 Gemfile 和 Gemfile.lock。

此时您可以慢慢增加版本号。不要跳过很多版本号 - 通常最好慢慢升级,这样您就可以看到弃用警告。修复这些,冲洗,重复。

将您的(输入)验证器修改为挑剔的白名单(“它必须是这种形式,否则我不会接受它”)。如果您可以防止不良数据进入您的系统,那么它就更有可能正常工作并且通常更难受到攻击。

为了安全,请考虑添加安全标头,并将 CSP 设置为尽可能强。

开始添加一些静态分析器。 Rubocop 和 Brakeman 非常有用。您可能必须将 Rubocop 配置为只抱怨一些事情,然后慢慢增加他们报告的内容。将所有检查添加到默认的“rake”命令中,这样您只需键入“rake”即可运行静态分析器和测试套件。

无论您使用什么框架,都没有魔法。人们会犯错误,假装是没有帮助的。

CII Best Practices badge project 可能是一个有用的例子。它使用 RoR,我领导。特别是,请参阅: * CONTRIBUTING * Security information (assurance case)

来自贡献: “一般来说,我们会尽量主动检测和消除错误和漏洞,并在它们确实发生时减少它们的影响。我们使用防御性设计和编码风格来减少错误的可能性,各种工具可以尝试及早发现错误,并使用具有显着覆盖率的自动测试套件。”

【讨论】:

谢谢。这是一个比我选择的更好的答案,但我已经很久没有问了:)

查找此异常原因的下一步是啥?

...clipse、Java和Android编程相当陌生。我已经接管了一个Android应用程序的开发。几个月前有人进行了更改,导致应用程序在不属于应用程序代码的代码中崩溃(异常)。我不知道项目的哪个 查看详情

将数据放入sharepoint列表的第一步是导出数据对吗

将数据放入sharepoint列表的第一步不是导出数据,第一步是定义列表的列,可以把列表当成是传统数据库的表。将数据表格导出为SharePoint列表的方法如下:1、打开软件点击办公软件菜单栏第九项,设计。2、然后点击办公软件菜... 查看详情

下一步是啥();在这段代码中?

...发布时间】:2013-08-2518:27:03【问题描述】:在这个Express应用程序(用于Nodejs)中有一行代码使用next();,我不明白。不知道你能不能澄清一下。在index.js中,express应用调用了一个函数isLoggedInMiddleware。它不传递任何参数app.use(sess 查看详情

使用 cx_Freeze 的下一步是啥?

...件夹。在这个文件夹中有2个文件。setup.py和holg.py(我的应用程序)这是我的setup.py:impo 查看详情

c# windows form,部署前的下一步是啥?

】c#windowsform,部署前的下一步是啥?【英文标题】:c#windowsform,Whatisnextstepbeforedeployment?c#windowsform,部署前的下一步是什么?【发布时间】:2020-08-1416:21:55【问题描述】:刚刚在sql管理Studio中使用数据库完成了我的诊所Winforms程... 查看详情

使用 libdbus-c++ 获得 DBus::Path - 下一步是啥?

】使用libdbus-c++获得DBus::Path-下一步是啥?【英文标题】:GotaDBus::Pathwithlibdbus-c++-whatnext?使用libdbus-c++获得DBus::Path-下一步是什么?【发布时间】:2013-05-0403:24:21【问题描述】:我有一个简短的测试程序,用于研究如何将D-Bus与libdb... 查看详情

Ruby 中的下一步是啥?

】Ruby中的下一步是啥?【英文标题】:WhatisinvalidnextinRuby?Ruby中的下一步是什么?【发布时间】:2013-11-0212:33:27【问题描述】:以下代码有效:collection.eachdo|i|beginnextifi>10i+=1rescueputs"couldnotprocess#i"endend但是,当我们重构时:colle... 查看详情

RestKit 中 RKManagedObject 的下一步是啥

】RestKit中RKManagedObject的下一步是啥【英文标题】:what\'sthenextofRKManagedObjectinRestKitRestKit中RKManagedObject的下一步是什么【发布时间】:2015-09-1914:41:32【问题描述】:刚看了github上的tutorial,发现了一些关于CoreData的对象方法,比如fe... 查看详情

cell.accessoryType = UITableViewCellAccessoryDe​​tailButton 下一步是啥?

】cell.accessoryType=UITableViewCellAccessoryDe​​tailButton下一步是啥?【英文标题】:cell.accessoryType=UITableViewCellAccessoryDetailButtonWHATISNEXT?cell.accessoryType=UITableViewCellAccessoryDe​​tailButton下一步是什么?【发布时间】:2014-08-0314 查看详情

在 vue app 中运行 npm build 以将其部署到服务器上后,下一步是啥?

...0-09-2804:34:53【问题描述】:我正在尝试在服务器上部署vue应用程序,我已经运行npmrunbuild,执行后 查看详情

Tigase:MUG 没有实现,下一步是啥?

】Tigase:MUG没有实现,下一步是啥?【英文标题】:Tigase:MUGnotimplemented,what\'snext?Tigase:MUG没有实现,下一步是什么?【发布时间】:2010-12-1011:59:02【问题描述】:我开始为iPhone/iPad开发多人游戏,我正在考虑使用Tigase作为游戏服... 查看详情

从 appengine 迁移到完整 django 的下一步是啥?

】从appengine迁移到完整django的下一步是啥?【英文标题】:What\'sthenextstepsformovingfromappenginetofulldjango?从appengine迁移到完整django的下一步是什么?【发布时间】:2011-06-0517:19:46【问题描述】:我是编程新手,我一直在使用appengine来... 查看详情

Rails 3 数据库索引和其他优化

...时间】:2011-08-3013:11:33【问题描述】:我一直在构建Rails应用程序,但不幸的是,我的应用程序都没有大量数据或流量。但现在我有一个正在获得动力。因此,我首先深入研究扩展和优化我的应用程序。似乎第一步也是最简单的... 查看详情

学习了如何使用 HTML 和 CSS 从头开始​​制作响应式 HTML 电子邮件。下一步是啥? [关闭]

...何使用HTML和CSS从头开始​​制作响应式HTML电子邮件。下一步是啥?[关闭]【英文标题】:LearnedhowtomakeresponsiveHTMLEmailsfromscratchusingHTML&CSS.What\'snext?[closed]学习了如何使用HTML和CSS从头开始​​制作响应式HTML电子邮件。下一步是... 查看详情

Spring Batch 在流程中有两个步骤。为啥第二步永远不会运行,第一步是无限循环

...ringBatch在流程中有两个步骤。为啥第二步永远不会运行,第一步是无限循环【英文标题】:SpringBatchwithtwoStepsinflow.WhysecondstepneverrunandfirststepisininfiniteloopSpringBatch在流程中有两个步骤。为什么第二步永远不会运行,第一步是无限循... 查看详情

第一步是 THREE.js:尝试将搅拌机模型添加到场景中的问题

】第一步是THREE.js:尝试将搅拌机模型添加到场景中的问题【英文标题】:Firststep\'swithTHREE.js:issuestryingtoaddablendermodeltoscene【发布时间】:2012-07-1812:40:48【问题描述】:我正在使用THREE.js迈出第一步。现在我只是尝试修改此处找到... 查看详情

Rails 遗留应用程序和 Ruby 2 错误:无法从文件类型 yml 加载翻译未知

】Rails遗留应用程序和Ruby2错误:无法从文件类型yml加载翻译未知【英文标题】:RailslegacyappandRuby2error:cannotloadtranslationsfromthefiletypeymlisnotknown【发布时间】:2014-09-2123:49:47【问题描述】:我有一个旧版Rails应用程序,我想升级到最... 查看详情

初学者的第一步。

---恢复内容开始---                  初学小程序: inti; gotoxy(40,13); printf("lingzhipeng"); gotoxy(40,12); printf("1-212"); gotoxy(40,11); printf("TEL:13217935482"); gotoxy(30,15); printf("************ 查看详情