HTTP 'Get' 安全性

4

有哪些HTTP“Get”安全最佳实践?

何时应该模糊HTTP Get查询字符串值?

编辑 - 我继承的应用程序对所有查询字符串参数进行了异或“加密”。它还在查询字符串中传递像AccountID这样的东西。所以我想知道这些是否是好的做法,如果它们不是,我该如何纠正这些问题。

编辑 -

我可以使用一种方法来解决这个问题,即创建一个基类(这只是伪代码):


public mustinherit class QSBase

  public shared Unique as long = 0
  private m_ID as string

  public readonly property ID
    get
      return m_ID
    end get
  end property

  public sub new()
   m_ID = Unique 'somehow get a unique value for this querystring
   Unique += 1
  end sub

  public function IDQueryString() as string
    return "ID=" & m_ID
  end function

end class

对于应用程序中的每个页面,我会创建一个派生类,并为每个查询字符串值创建属性。


public class QSPage1
  inherits QSBase

  private m_AccountID as string

  public readonly property AccountID as string
    get
      return m_AccountID
    end get
  end property

  public sub new(byval _AccountID as string)
    m_AccountID = _AccountID
  end sub

end class

然后,当我将查询字符串传递给弹出窗口或其他页面时,我会实例化相关类,将其存储在会话中,并在查询字符串中传递唯一的ID。


Dim qs as new QSPage1("123456")
Session(qs.ID) = qs
Server.Transfer("Page1.aspx?" & qs.IDQueryString())
'or
CreatePopup("Page1.aspx?" & qs.IDQueryString())

在页面中,我通过获取唯一的ID并引用存储的会话值来访问这些值:


AccountID = CType(Session(Request.QueryString("ID")), QSPage1).AccountID()

当然,这可以放入页面中的函数或类中。
这种方法的一些优点是:
- 除了不相关的ID外,查询字符串中没有任何内容可见。 - 在已有的代码中实现相当容易。
其中一些缺点是:
- 长时间会话可能会积累许多这些查询字符串对象。 - 唯一ID需要在该会话中“真正唯一”。
有人能想到其他的好处/缺点或更好的方法吗(除了重写应用程序)?
编辑 -
感谢所有建议使用HTTPS和POST的人。不幸的是,我正在寻找与仅使用“GET”有关的答案。(除非您可以解释如何在不使用QueryString、Session或Javascript的情况下向弹出窗口发布数据?)

好奇问一下,您认为应该隐藏哪种信息? - Colin Burnett
1
这个问题对我来说听起来非常泛泛。你想要保护什么?为什么你特别问HTTP GET? - Alexander Klimetschek
这个问题为什么会被投票否决?我看不出来有什么问题啊! - razenha
+1备份。也许这不是针对该主题最好措辞的问题,但它似乎正在产生良好的评论和答案。 - Demi
你可能想查看https://dev59.com/W3VC5IYBdhLWcg3wvT1a。 - James McMahon
@Nemo - 那个问题根本没有提供任何帮助。 - user79755
8个回答

7
如果您有任何值得隐藏的内容,我建议使用HTTPS并放弃HTTP。
通常情况下,我不会在查询字符串中添加与客户、供应商或订单标识相关的任何内容。但这只是我的看法。

好的,谢谢。您还有其他关于Http 'GET'安全最佳实践的建议吗? - user79755

4

我认为您不应该隐藏GET参数。

如果您需要在导航栏中隐藏查询字符串中的参数,应使用POST。

如果您想防止嗅探器拦截您的GET参数数据,请使用HTTPS。


3
POST 比 GET 更安全的说法是不正确的。 - Colin Burnett
1
这不是关于安全性的问题,而是关于在导航栏中隐藏查询字符串参数的问题。 - razenha
而POST查询无法被书签标记,直接被Google索引等。Google有惊人的能力来发现“隐藏”的页面。 - Eli

3
也许您可以详细说明您想要实现的目标?一般来说,您应该避免将重要的内容(例如登录凭据)放在URL中。URL有泄漏的习惯。
一般建议:设置robots.txt以防止Google索引任何这些页面,并使登录令牌(或其他令牌)仅限单次使用。
编辑:我建议不要使用弱XOR“加密”。如果您担心人们篡改URL参数,则添加安全哈希。如果您确实需要隐藏查询包含的信息,则真正进行加密,不要自己编写弱算法。

2

不要在GET请求中放置安全信息。这些请求直接被Web服务器记录。因此,如果第三方希望查看和破解信息,则可以以纯文本格式获得该信息。

如果需要传递凭据,请使用cookie存储状态信息,并将所有内容分层在SSL上。


除了Web服务器记录Get请求外,它们还将存储在本地浏览器历史记录中。 - James McMahon
非常正确!再加上任何透明代理都可以。 - sybreon

0

我的诚实回答是,除非数据真的非常敏感(例如密码、信用卡号等),否则编写“加密”的人可能只是试图掩盖应用中缺乏适当身份验证/授权的问题。

例如,如果您担心如果不加密URL中的“accountId = 1”部分,那么其他人就能够篡改它为“accountId = 2”并查看其他人的帐户,那么应用程序中的真正缺陷在于它在提供服务之前未检查帐户所有权!

尝试使用加密来修复这种缺乏授权检查的问题最多只是一个应急措施。请注意,应急措施有时是必要的-此时也许别无选择-但我们仍然应该意识到它的本质。


0

有几个需要考虑的问题...

  • 根据请求的内容,可能需要进行身份验证和授权。

  • 值得考虑的是如何使用查询参数数据。如果参数数据用于除了一组选项之外的任何方式,并且可能来自不受信任的来源,则可能需要验证参数值。

  • 注意返回错误代码。攻击者可以利用错误代码来确定可能的攻击向量,从而了解您的站点拓扑结构:如果资源不存在或参数错误等情况下会返回什么信息。


0
你可以在asp.net中使用HttpModule,全局加密HTTP Get值 - HttpModule for query string encryption。此外,使用SessionId作为加密/解密的密钥,使每个会话的查询字符串更安全。但是,它并不是100%安全的,我不建议在高安全性网站上使用。
正如“JD”所建议的那样,最好使用HTTPS来保护服务器和客户端之间的通信。然而,客户端可以轻松地在浏览器上更改参数值,例如/showinvoice.aspx?id=1000变成/showinvoice.aspx?id=1001。
我建议在执行页面之前在服务器端验证每个参数的值。这将停止执行无效请求。

0

如果您需要更高的安全性,请使用POST方法。

不应该在查询字符串中传递帐户信息。


哦,那真是太艰难了,而且完全没有必要。 - James McMahon
1
这是绝对必要的。事实上,应该给它一个踩。这篇帖子是一个没有阅读整个OP或任何其他回复的即兴评论。 - user79755

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接