这是我想弄清楚的安全问题。 的所有内容都很好,我可以从我的托管软件包内部向AppExchange发送用户身份验证的用户。问题是Twitter OAuth 1.0进程(或“舞蹈”)有通信步骤,GET从Twitter返回到我的应用程序。虽然这有效,但根据安全测试通过online以及现在使用Eclipse中的CxViewer,安全审查过程是一个危险信号。
但我需要从Twitter获取此信息并以某种方式为每个用户存储 。这个问题的示例代码入口点,其中Twitter从我的一个auth_token请求回调,将是:
页:
<apex:page controller="AuthController" action="{!completeAuthorization}"/>
顶点:
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。非常感谢任何帮助!
答案 0 :(得分:0)
这是我发现的。该问题涉及让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中,没有办法让两个同时用户同时登录,就像大多数系统一样,所以令牌检查从一开始就太过分了,因为我从不共享我的用户ID鸣叫声。
需要存储的 实际 令牌(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
我准备发布奖金;)