On 03/02/2012 03:25 PM, Paul Wallingford wrote:
On 3/1/2012 12:15 PM, RS Tech wrote:
A client just sent me a web security report for a Mason-based site I
built for him a while ago (Mason 1.38). The report, which was generated
by HP WebInspect, complains that form scripts on the site are not
distinguishing between POST and GET parameters. A summary of the problem
is provided, explaining that 'collapsing' POST and GET params into a
single collection exposes the site to XSS and other attacks.

I'd like to get list users' thoughts on the degree of vulnerability
represented. Is there a best practice way of dealing with this issue?

Thanks,
MM
Hello,

I did some research into this.  It is a bit obscure and information is
not easy to find.  I believe the scan is referencing HTTP Parameter
Pollution (HPP).

See: http://www.iseclab.org/people/embyte/slides/BHEU2011/hpp-bhEU2011.pdf

Essentially, it comes down to how the application or framework handles
multiple sources of the same parameter.  There are several ways an
attacker can pollute the parameters.



Example 1:

original: http://domain.com/page.html?parameter=a
attacker: http://domain.com/page.html?parameter=a&parameter=b

- How is this handled?

- Do you keep "a", "b", somehow combine them both, or can the one that
gets kept be somehow pseudorandom?  (Pseudorandom behavior can result if
a hash is used during processing since the order of keys is based on a
complex hashing algorithm which is specifically designed to scramble key
order, in order to facilitate even distribution).

- Do you even have control over this, or are you "handed" a value by
your framework so you are oblivious that an attempted attack even occurred?

- How are your parameters parsed?

- Are you looking specifically for "?" and "&" since these can be obscured?

- Will you miss the above attack if the URL looks like:
    http://domain.com/page.html?parameter=a%26parameter%3Db
    You might be handed, and take action based on, the value "b" which
could be anything the attacker chooses, when your app was expecting "a".



Example 2:

The same is true if your normally expect to get parameters from a POST,
but your framework combines GET and POST parameters before handing them
to your app.

A misconception among many developers is that POST requests are more
secure and thus more trusted.  This is because POST parameters do not go
into the server logs and do not show up in the URL line.  However, in
many circumstances, it is just as easy for an attacker to generate a
POST as to add parameters to a GET.  So many of the same questions apply:

- If a POST has parameter=a (the real one) and the GET has
...?parameter=b (from the attacker), how does your app or framework
handle it?

- Does the GET take precedence, or the POST, are they somehow combined,
or is the one that is kept, pseudorandom?

The reverse is true.  If you normally have parameters on the command
line (GET), the attacker can use Javascript and optionally one of the
frameworks like jQuery if it is running on the page, to generate AJAX
requests.  From a browser standpoint, AJAX is partial page updates, but
from the server standpoint, an AJAX call is nothing more than a GET or
POST.  Basically, it is possible to inject POST parameters, when you
were expecting only GET parameters.



Example 3:

Another vector of this attack is if you store parameters in a cookie.  I
do not believe this is the default behavior of Mason and is generally a
bad idea.  However, if you store a session key in a cookie such as
sess=12345678 and in your app add that to the same hash that stores your
GET and POST parameters you will be vulnerable.  The attacker can add
sess=ABCDEFGH to the GET request and hijack another session.




It has always bothered me that Mason and many other systems combine GET
and POST parameters, but I was able to ignore that since it did not
adversely affect my apps.  However, based on these newly discovered
vulnerabilities, the defense is the following:

1) Always know where your parameters come from and make sure they come
from an expected source.

2) Do not blindly discard data.  If three copies of "parameter" come
from a GET, keep all three and decide how to handle it. If you only
expect one copy, it is probably best to reject the entire query as a
possible hacking attempt.  If you get one from GET and one from POST,
same logic: keep both tagged where they came from, then in your form
analysis logic, reject the entire query as a possible hack attempt.



As Dave Rolsky said, a lot of frameworks treat parameters rather
sloppily.  However, until fairly recently, doing so was not known to be
a security problem and it made things simpler for the web developer.
These frameworks will need to be changed to accommodate these new
defenses and the changes cannot be backward compatible with the old
behavior, since the old behavior is vulnerable to attack.

In the meantime, a quick patch, if your app only expects to get
parameters via POST, is to disallow GET parameters altogether.  If you
have the option of specifying this in your framework, then use it.

If you are using CGI to initiate Mason, then you can delete the
QUERY_STRING environment variable in your Mason handler, so CGI.pm and
Mason never see it.

Or, if you need GET parameters for certain operations, then within the
mason handler, read QUERY_STRING and make sure it only contains
parameters that you are expecting, erasing the rest, then store the
sanitized results back in QUERY_STRING (although this is not as good as
disallowing it altogether).

If you use mod_perl, then you will need to do handle more of this in
your app.

HOWEVER, in all the above cases of disallowing GET parameters, you will
still need to test if multiple copies of a parameter came in via the
POST mechanism.  All parameters that you expect only one copy, you
should specify as scalars.  Then check if they are a reference to an
array, since Mason 1 does this for you when it sees multiple copies of a
parameter that is specified as a scalar (see Mason book page 35).

Many thanks for this very thorough investigation of potential issues with POST/GET mixing. I've just posted a response to Dave, and included the HP WebInspect app's generic description of the issue. Apparently, HPWI is most concerned about the degree to which mixing POST and GET args opens up a site to so-called 'Cross-Site request forgery' attacks. cgisecurity.com describes this type of attack as follows:

"Cross Site Request Forgery (also known as XSRF, CSRF, and Cross Site Reference Forgery) works by exploiting the trust that a site has for the user. Site tasks are usually linked to specific urls (Example: http://site/stocks?buy=100&stock=ebay) allowing specific actions to be performed when requested. If a user is logged into the site and an attacker tricks their browser into making a request to one of these task urls, then the task is performed and logged as the logged in user. Typically an attacker will embed malicious HTML or JavaScript code into an email or website to request a specific 'task url' which executes without the users knowledge, either directly or by utilizing a Cross-site Scripting Flaw. Injection via light markup languages such as BBCode is also entirely possible<http://www.webappsec.org/lists/websecurity/archive/2007-01/msg00158.html>. These sorts of attacks are fairly difficult to detect potentially leaving a user debating with the website/company as to whether or not the stocks bought the day before was initiated by the user after the price plummeted."

cgisecurity.com's CSRF FAQ:
http://www.cgisecurity.com/csrf-faq.html

Clearly POST/GET arg mixing is but a piece of a potential vulnerability. Still, it's a more important consideration than I'd realized.

Dave Rolsky's suggestion is a good start, but it is still vulnerable to
the following (action was modified by the attacker to add x=evil_value):

<form method="post" action="/formhandler.mhtml?x=evil_value">
    <input type="hidden" name="x" value="real_value">
    <input type="submit" value="Submit">
</form>

$r->method reports this as POST, but it is still vulnerable and you may
not know that you received two versions of the same parameter and which
one you were handed by the framework.

A lot of the vulnerability comes down to your app's handling of the
situation, but the framework can make it easier or more difficult.  I
recommend you get the specifics from the scan, try to duplicate it
yourself and plan how to fix it, if it indeed is a vulnerability.

Cheers.

Paul Wallingford

------------------------------------------------------------------------------
Virtualization&  Cloud Management Using Capacity Planning
Cloud computing makes use of virtualization - but cloud computing
also focuses on allowing computing to be delivered as a service.
http://www.accelacomm.com/jaw/sfnl/114/51521223/
_______________________________________________
Mason-users mailing list
Mason-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mason-users

As I mentioned in the response to Dave, I put a routine in place to check method type and bail if not POST -- but I haven't tested against the style of argument passing you describe above. I'll test that this weekend -- and will test for other vulnerabilities using your contributions as a guide.

Again, many thanks for your thoughts on this. I'll report back with any discoveries.

MM
------------------------------------------------------------------------------
Virtualization & Cloud Management Using Capacity Planning
Cloud computing makes use of virtualization - but cloud computing 
also focuses on allowing computing to be delivered as a service.
http://www.accelacomm.com/jaw/sfnl/114/51521223/
_______________________________________________
Mason-users mailing list
Mason-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mason-users

Reply via email to