在我的 ruby 脚本中,我需要传递用户名和
密码作为表单中的纯文本以便登录。用户名和密码当前都存储在我的脚本中。
我无法控制从脚本登录的服务器。该脚本在本地运行良好,将来我想转移到我的
虚拟主机提供商并从那里运行它(我有 ssh 访问权限)
使用 cron。有什么办法/方法如何
保护密码以防万一有人访问此脚本?
在我的 ruby 脚本中,我需要传递用户名和
密码作为表单中的纯文本以便登录。用户名和密码当前都存储在我的脚本中。
我无法控制从脚本登录的服务器。该脚本在本地运行良好,将来我想转移到我的
虚拟主机提供商并从那里运行它(我有 ssh 访问权限)
使用 cron。有什么办法/方法如何
保护密码以防万一有人访问此脚本?
我对此考虑得越多,我认为您必须越信任您的托管服务。我会确保托管服务具有“游戏中的皮肤”:也就是说,他们托管足够多的“高知名度”帐户,被发现不可信对他们来说将是非常昂贵的(丢失帐户和销售)。
而且无论您是否认为托管服务值得信赖,您都应该有一个计划,以防目标帐户被盗用。您将通知谁,您将如何停用该帐户等。
我能想到的唯一技术解决方案——您手动登录,捕获 cookie,并将该 cookie 提供给脚本——保护密码,但可能敌对主机可以使用该 cookie 对目标造成他想要的任何损害系统使用附加到该 cookie 的任何特权,包括更改您的密码。所以根本没有解决办法。
哦,说到特权:您需要自动化的任务是否可以使用具有较低特权的目标帐户来完成,例如只读帐户,或者不能对其配置文件进行任何更改的目标帐户?在托管服务上只有您的低权限凭证会降低您的风险(或“暴露”,正如多音节人群喜欢说的那样)。
先前的答案,发现是行不通的,低于该行。
您可以使用另一个密码来加密用户 ID 和密码。为了运行,脚本必须提供它的密码。它使用该密码来解密 Web 服务的用户名和密码。确保脚本的密码不会存储在任何地方,而只会保存在内存中,并且仅保存足够长的时间以解密最终的用户 ID 和密码。
如果真的很重要,请确保运行脚本的连接是加密的(ssh、ssl 等),并确保脚本仅使用 https 登录。
这不会让你对盒子上具有 root 权限的人无懈可击(在某些时候,明文用户 ID 和密码将在内存中,因此容易受到攻击),但它确实使他们需要更多的工作才能能够获取用户 ID/密码。
更新:自动化的要求使上述解决方案不好。
如果自动化脚本需要使用密码运行某些东西,那么您要么必须让脚本读取它(这打开了其他人阅读它的可能性),要么不以自动化方式提供它。
诀窍是通过一次性启动绕过“自动化”部分:将脚本作为一个小的连续进程运行,该进程将定期唤醒并运行。让进程在启动时或通过某种其他类型的 API 请求(而不是在命令行上!)询问密码。
如果服务器重新启动,密码将丢失,直到您登录并再次输入密码。这样,密码只在内存中,不在文件系统中。
您可能需要一个 cron 作业来检查该进程并在它未运行时提醒您。
如果您需要将密码继续传递给您可能无法更改以使用更安全方案的表单,那么除了混淆密码以使其不会立即显而易见之外,您几乎无能为力。但是,任何有权访问脚本本身的人都可以简单地找到它传递给表单的位置并插入一个命令以在此处打印密码——不管怎样,它都需要在此时“解密”才能传递给你.
为了保护它免受非程序员的影响,你可以用一些东西对它进行异或或旋转一些字母,但我不会在这上面花太多时间,因为它对几乎任何对编程有基本了解的人都是徒劳的。相反,保护脚本本身不受其他用户的影响(正确设置文件访问权限,不要将其放在网络可见的目录中,等等)。如果您不信任服务器的管理,请不要将其上传到那里!
您应该在数据库中存储密码的散列版本。哈希是一种单向加密,因此不可能使用逻辑从哈希密码中猜测密码。
创建一个散列密码的方法,并执行以下操作:
require "digest/sha1"
class User
attr_accessor :password
def initialize(password)
@password = hash_password(password)
end
def hash_password(password)
Digest::SHA1.hexdigest(password)
end
def valid_password?(password)
@password == hash_password(password)
end
end
u = User.new("12345")
p u.password # => "8cb2237d0679ca88db6464eac60da96345513964"
p u.valid_password?("not valid") # => false
p u.valid_password?("12345") # => true
当您从表单中获取纯文本密码时,您将其传递给您的valid_password?
方法。这将执行与存储密码时相同的单向加密。因此,比较加密密码的一种方式。这意味着您永远不会在任何地方存储对实际密码的引用,这是一个巨大的胜利。