[ 
https://issues.apache.org/jira/browse/SHINDIG-447?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Karsten Beyer updated SHINDIG-447:
----------------------------------

    Attachment: fix-issue-447.patch

As promised, attached a patch to fix the situation. However the issue seemed to 
be a lot worse than first expected. So i will first describe my analysis of the 
problems with the current code.

There is a method to sanitize the fields (GET+POST) which go into the 
base_string used for the signature. It is located in SigningFetcher and relies 
on this method:

protected static $ALLOWED_PARAM_NAME = "[-:\\w]+";

...
        
private function allowParam($paramName)
        {
                $canonParamName = strtolower($paramName);
                return (! (substr($canonParamName, 0, 5) == "oauth" || 
substr($canonParamName, 0, 6) == "xoauth" || substr($canonParamName, 0, 9) == 
"opensocial")) && ereg(SigningFetcher::$ALLOWED_PARAM_NAME, $canonParamName);
        }


Now this filters all parameters which either start with one of the strings in 
the first half of the expression or which do not contain a 'w'(!). For this 
reason, stuff like "numentries" or "myvalueformyscript" is being thrown away, 
while "signOwner" and "signViewer" are kept. This is in my opinion a completely 
wrong behavior. I will present a solution to it later on.

Next problem is that the values are only appended to the query string, if they 
were not posted to the proxy (which is ok, if we are supposed to do a POST). 
This affects both the signViewer and signOwner fields as everything is posted 
to the proxy. Bad thing is that the POST data and headers are not set, so we 
effectively do a GET instead of the requested POST. 

The OAuthRequest object now builds its base_string using all "sanitized" values 
in the GET+POST array. This contains at this point in time:

1) signViewer & signOwner
2) all Fields of the user not containing a 'w'

They are not used in the final request string however, as they are POST data. 
Therefore the signature validation cannot work.

Now to my solution (This patch is rather complex, so it would be a good idea to 
review it carefully before applying it):


1) I "fixed" the regular expression to accept alphanum, 0-9, -, _. However this 
is a very bad idea. As i understand, special chars are allowed for form field 
names, they just need to be encoded in a POST. Maybe someone has a good idea 
here. '\w' is as far as i know not available with the POSIX regular expressions.

2) As i understood the OAuth specification, the posted form data needs to be 
included in the base_string used for the signature. This is transfered to the 
proxy in the postData field of the $_POST. I implemented a parsing function 
which put the (sanitized) single entries into the postParams arrays, so they 
are used for the generation of the signature and also for the building of the 
query string / or postdata string (see below).

3) The sanitize function obviously did not work at all. If you fix it however, 
all the parameters which are supposed to be for the proxy, are now in the 
base_string as well as the query string. So i extended the allowParam method to 
exclude all these parameters (e.g. url, gadget, bypassspeccache etc.). This 
includes the postData param, as we put these values individually into the 
postParam array.

4) If we have a POST request, i build a post_data string according to RFC3986 
using the oauth library which is later used to actually post the data. If we 
have a GET request however, i leave the post data string == false in order to 
make a GET request to the partners page and keep the forPost array empty so 
that these are appended to the query string instead. Take a look at this 
example to understand why:

testdataplain = new Object();
testdataplain['hello'] = 'world';
params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.TEXT;
params[gadgets.io.RequestParameters.AUTHORIZATION] = 
gadgets.io.AuthorizationType.SIGNED
params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.GET;
params[gadgets.io.RequestParameters.POST_DATA] = 
gadgets.io.encodeValues(testdataplain);
        
gadgets.io.makeRequest('http://opensocialapps.kbsilver/log.php?hope=itworks', 
gotLog, params);

Obviously i would expect to get the values hello=world&hope=itworks in a signed 
request. 

5) Last of all, if we do a POST, i add the constructed post_data array (see 4) 
and the $_POST['headers'] field to the contructor of RemoteContentRequest in 
order to actually make a POST.

6) I removed the quick hack from the OAuth.php file.

 


        

> makeRequest - Signed request cannot be verified because of base_string 
> inconsitency
> -----------------------------------------------------------------------------------
>
>                 Key: SHINDIG-447
>                 URL: https://issues.apache.org/jira/browse/SHINDIG-447
>             Project: Shindig
>          Issue Type: Bug
>          Components: Common Components (PHP)
>            Reporter: Karsten Beyer
>         Attachments: fix-issue-447.patch
>
>
> When doing a signed request with makeRequest, the generated signature cannot 
> be verified, because different base_strings are used. 
> I used the method described for Orkut 
> (http://code.google.com/p/opensocial-resources/wiki/OrkutValidatingSignedRequests)
>  to verify the signature on the requested page. When logging the base_string 
> on both sides, i detected, that the signOwner and signViewer parameters are 
> used for the base_string, but are not part of the request that the proxy does 
> to the target page: 
> base_string build by shindig:
> GET&http%3A%2F%2Fopensocialapps.kbsilver%2Flog.php&container%3Dazubister%26oauth_consumer_key%3Dnot%2520implemented%26oauth_nonce%3D68d2fedb1b405f426e0b5d6aa90893bb%26oauth_signature_method%3DRSA-SHA1%26oauth_timestamp%3D1215874245%26oauth_token%3D%26opensocial_app_id%3D25%26opensocial_owner_id%3DQ3czQ1B2SytHbVU0ZXJEOXRwOTJHdz09%26opensocial_viewer_id%3DQ3czQ1B2SytHbVU0ZXJEOXRwOTJHdz09%26signOwner%3Dtrue%26signViewer%3Dtrue%26synd%3Dazubister%26xoauth_signature_publickey%3Dhttp%253A%252F%252Fshindig.kbsilver%252Fpublic.crt
> base_string build at the requested page:
> GET&http%3A%2F%2Fopensocialapps.kbsilver%2Flog.php&container%3Dazubister%26oauth_consumer_key%3Dnot%2520implemented%26oauth_nonce%3D68d2fedb1b405f426e0b5d6aa90893bb%26oauth_signature_method%3DRSA-SHA1%26oauth_timestamp%3D1215874245%26oauth_token%3D%26opensocial_app_id%3D25%26opensocial_owner_id%3DQ3czQ1B2SytHbVU0ZXJEOXRwOTJHdz09%26opensocial_viewer_id%3DQ3czQ1B2SytHbVU0ZXJEOXRwOTJHdz09%26synd%3Dazubister%26xoauth_signature_publickey%3Dhttp%253A%252F%252Fshindig.kbsilver%252Fpublic.crt
> Analyzing the $_GET parameters i get at the target leads to the same result. 
> I do not know enough about the OAUTH logic in shindig, but i think either the 
> signOwner and signViewer parameters need to be ignored when building the 
> base_string for the signature or they need to be part of the request to the 
> target page.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to