我正在尝试找出一种方法来防止某人更改部分网址。我已经设置了我的网站,以便没有人可以注册或创建帐户,以便任何访问的人都是客人。
例如,我已经在网站的此部分中设置了网址,以从1a
中查找/pathfinder/a/quest1/1a/q1sub1/
的值,以便显示{{1 }}。
如果有人要将q1sub1
的值更改为1a
,我想测试网址是否已更改并给出某种错误消息。
不确定在这种情况下要共享的代码摘录,如果您需要更多信息,请告诉我。
我愿意接受任何想法,并感谢任何意见。谢谢!
答案 0 :(得分:0)
URL是设计使然,无法由您的应用程序控制。但是,如果您想跟踪用户以前的位置,则在所有控制器中您都可以访问request.referrer
,它应该告诉您请求来自何处。如果您想限制request.referrer
,则可以在控制器中添加一些条件逻辑并重定向用户。因此,在您的控制器操作中,如下所示:
def show # for example
if request.referrer != "http://example.com/myformpage"
redirect_to root_path, notice: "Invalid access"
else
# do stuff
end
end
但是,这仍然是不安全的,因为可以伪造标题(感谢@Holgar Just)。如果您确实需要应用程序中的安全性,则应该阅读documentation,并且如果需要对用户权限进行更精细的控制,可以结帐CanCanCan gem
答案 1 :(得分:0)
一种描述您的方法的方法是,使用包含机密pepper的哈希函数,在将URL发送给客户端之前先对URL进行指纹识别。这个想法是,如果客户端篡改了URL,则指纹将不再匹配,并且由于指纹是通过服务器端机密生成的,因此客户端将无法生成与新URL匹配的新指纹。
这里是一个例子。
用户将访问/foo
并传递自定义data
参数。应用程序将使用此参数来构建格式为/my/secret/:one/path/:two
的自定义URL,并将客户端重定向到该URL。这只是为了简化操作,如果将生成的URL用作页面中的<a href="...">
,则可以应用相同的方法。
生成的URL包含一个指纹,并且如果客户端篡改了URL或指纹,或者如果缺少指纹,则应用程序将以403响应。
让我们看一下代码。路线:
Rails.application.routes.draw do
get :foo, to: 'example#foo'
get '/my/secret/:one/path/:two', to: 'example#bar', as: 'bar'
end
和控制器:
class ExampleController < ApplicationController
# GET /foo?data=xx foo_path
#
def foo
user_data = request[:data]
go_to_path = bar_path(one: user_data, two: "foobar")
go_to_path += "?check=#{url_fingerprint(go_to_path)}"
redirect_to go_to_path
end
# GET /my/secret/:one/path/:two bar_path
#
def bar
unless valid_request?
render plain: "invalid request!", status: 403
return
end
render plain: "this is a good request", status: 200
end
private
SECRET = ENV.fetch("URL_FINGERPRINT_SECRET", "default secret")
# Calculate the fingerprint of a URL path to detect
# manual tampering.
#
# If you want to restrict this to a single client, add
# some unique identifier stored in a cookie.
#
def url_fingerprint(path)
Digest::SHA2.hexdigest(path + SECRET)
end
def valid_request?
return false unless params[:check].present?
params[:check] == url_fingerprint(request.path)
end
end
以此,客户端将以:
$ curl -i -s http://localhost:3000/foo?data=hello | grep Location
Location: http://localhost:3000/my/secret/hello/path/foobar?check=da343dd84accb4c0f5f7ff1d6e68152ac124ca1a39ce4746623bcb7b9043cab3
然后:
curl -i http://localhost:3000/my/secret/hello/path/foobar?check=da343dd84accb4c0f5f7ff1d6e68152ac124ca1a39ce4746623bcb7b9043cab3
HTTP/1.1 200 OK
this is a good request
但是,如果URL被修改:
curl -i http://localhost:3000/my/secret/IWASCHANGED/path/foobar?check=da343dd84accb4c0f5f7ff1d6e68152ac124ca1a39ce4746623bcb7b9043cab3
HTTP/1.1 403 Forbidden
invalid request!
如果指纹本身被修改或丢失,也会发生同样的情况。