Twitter OAuth Dance использует GET для авторизации, но защита Apex CSRF предоставляется только для POST - PullRequest
2 голосов
/ 01 февраля 2012

Это проблема безопасности, которую я пытаюсь выяснить.Все работает нормально, и я могу получить аутентификацию пользователей в Twitter из моего управляемого пакета, предназначенного для AppExchange.Проблема заключается в том, что процесс Twitter OAuth 1.0 (или «танец») имеет этапы связи, которые происходят с GET, приходящими из Twitter обратно в мое приложение.Хотя это работает, это красный флаг для процесса проверки безопасности в соответствии с проходами теста безопасности онлайн и теперь с CxViewer в Eclipse.

Но мне нужно получить эту информацию из Twitter и сохранить ее как-то для каждого пользователя.Пример точки входа кода с этой проблемой, когда Twitter перезванивает с одного из моих запросов auth_token, будет выглядеть следующим образом:

Страница:

<apex:page controller="AuthController" action="{!completeAuthorization}"/>

Apex:

public PageReference completeAuthorization() 
{
   String token = ApexPages.currentPage().getParameters().get('oauth_token');
   CustomObject__c c = new CustomObject__c(Name = token);
   insert c; // <--- Security flaw here! (except that it's Twitter, not Trojan.com)
}

Я прочитал всю прилагаемую документацию Apex по этому вопросу, прочитал ее снова, просмотрел форумы и, к сожалению, нашел zilch / nada.Любая помощь будет принята с благодарностью!

1 Ответ

0 голосов
/ 08 февраля 2012

Вот что я обнаружил.Проблема связана с тем, что параметр GET диктует что-либо об объекте, выбранном в Salesforce, а затем сохраняет данные в этом объекте.Я не верю, что когда-либо существовала реальная проблема безопасности, и с моим новым кодом тест безопасности прошел без проблем.По сути, это происходит так:

String token = ApexPages.currentPage().getParameters().get('oauth_token');

CustomObject__c pcs = [
SELECT Id, User__c, Token__c 
FROM CustomObject__c 
WHERE Id = :UserInfo.getUserId() 
AND Token__c = :EncodingUtil.urlEncode(token, 'UTF-8'];

Поскольку весь этот обмен начинается с моего контекста, где я на 100% уверен в текущем пользователе (UserInfo.getUserId ()), мне не нужнопроверьте, совпадает ли этот конкретный токен, так как пользователь гарантирован (по крайней мере, в связи со мной, инициирующим этот процесс).Таким образом, следующий выбор отлично работает:

CustomObject__c pcs = [
SELECT Id, User__c, Token__c 
FROM CustomObject__c 
WHERE Id = :UserInfo.getUserId()];

Затем, если я обновлю этот объект:

update pcs;

, он не будет жаловаться, так как переданное значение GET неиметь какую-либо связь с объектом, выбранным для записи.Однако, как вы могли заметить, проблем на самом деле никогда не было - до тех пор, пока я включил

WHERE Id = :UserInfo.getUserId()

в оператор SOQL.Причина в том, что независимо от того, какие фальшивые токены пыталась внедрить атака в мой код, он все равно проверялся против текущего пользователя и в любом случае потерпел бы неудачу, если пользователь не совпадал.Но в Salesforce нет никакого способа, позволяющего одновременно войти в систему двум пользователям, как в большинстве систем, поэтому проверка токенов с самого начала была излишней, поскольку я никогда не делюсь своими идентификаторами пользователей с Twitter.

Токены фактические , которые необходимо сохранить (oauth_token и oauth_secret), могут быть получены как параметры POST и, следовательно, имеют встроенную защиту Salesforce CSRF.Они получены следующим образом:

Http h = new Http();
HttpRequest req = new HttpRequest();
req.setMethod('POST');
req.setEndpoint(accessTokenURL);
req.setBody('');
sign(req);
HttpResponse res = new HttpResponse();
String resParams = res.getBody();
Map<String,String> rp = new Map<String,String>();

if(resParams != null)
{
   for(String s : resParams.split('&')) 
   {
      List<String> kv = s.split('=');
      rp.put(kv[0],kv[1]);
   }
}

tK.Secret__c = rp.get('oauth_token_secret');
tK.Token__c = rp.get('oauth_token');

upsert tK; // No problem, it's from a POST body

И я собирался ПОСТАВИТЬ щедрость;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...