{"action":"created","issue":{"url":"https://api.github.com/repos/dropbox/dropbox-sdk-ruby/issues/29","labels_url":"https://api.github.com/repos/dropbox/dropbox-sdk-ruby/issues/29/labels{/name}","comments_url":"https://api.github.com/repos/dropbox/dropbox-sdk-ruby/issues/29/comments","events_url":"https://api.github.com/repos/dropbox/dropbox-sdk-ruby/issues/29/events","html_url":"https://github.com/dropbox/dropbox-sdk-ruby/pull/29","id":107584745,"number":29,"title":"Protecting against timing attacks","user":{"login":"JackDanger","id":2071,"avatar_url":"https://avatars.githubusercontent.com/u/2071?v=3","gravatar_id":"","url":"https://api.github.com/users/JackDanger","html_url":"https://github.com/JackDanger","followers_url":"https://api.github.com/users/JackDanger/followers","following_url":"https://api.github.com/users/JackDanger/following{/other_user}","gists_url":"https://api.github.com/users/JackDanger/gists{/gist_id}","starred_url":"https://api.github.com/users/JackDanger/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JackDanger/subscriptions","organizations_url":"https://api.github.com/users/JackDanger/orgs","repos_url":"https://api.github.com/users/JackDanger/repos","events_url":"https://api.github.com/users/JackDanger/events{/privacy}","received_events_url":"https://api.github.com/users/JackDanger/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2015-09-21T19:45:56Z","updated_at":"2015-09-29T03:27:27Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/dropbox/dropbox-sdk-ruby/pulls/29","html_url":"https://github.com/dropbox/dropbox-sdk-ruby/pull/29","diff_url":"https://github.com/dropbox/dropbox-sdk-ruby/pull/29.diff","patch_url":"https://github.com/dropbox/dropbox-sdk-ruby/pull/29.patch"},"body":"The previous string comparison method didn't operate in constant time.\r\nIf the string under test wasn't the same length as the secret the method\r\ninstantly returned.\r\n\r\nThis implementation is constant time with respect to the untrusted\r\nstring and executes very quickly (that's why the style is not quite as compact\r\nas one might expect)."},"comment":{"url":"https://api.github.com/repos/dropbox/dropbox-sdk-ruby/issues/comments/143933051","html_url":"https://github.com/dropbox/dropbox-sdk-ruby/pull/29#issuecomment-143933051","issue_url":"https://api.github.com/repos/dropbox/dropbox-sdk-ruby/issues/29","id":143933051,"user":{"login":"cakoose","id":239989,"avatar_url":"https://avatars.githubusercontent.com/u/239989?v=3","gravatar_id":"","url":"https://api.github.com/users/cakoose","html_url":"https://github.com/cakoose","followers_url":"https://api.github.com/users/cakoose/followers","following_url":"https://api.github.com/users/cakoose/following{/other_user}","gists_url":"https://api.github.com/users/cakoose/gists{/gist_id}","starred_url":"https://api.github.com/users/cakoose/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cakoose/subscriptions","organizations_url":"https://api.github.com/users/cakoose/orgs","repos_url":"https://api.github.com/users/cakoose/repos","events_url":"https://api.github.com/users/cakoose/events{/privacy}","received_events_url":"https://api.github.com/users/cakoose/received_events","type":"User","site_admin":false},"created_at":"2015-09-29T03:27:27Z","updated_at":"2015-09-29T03:27:27Z","body":"The SDK uses it for CSRF checking.\r\n\r\nI'm not sure if it's possible to write something that's constant-time for all lengths of inputs.  For example, in your code, `trusted_chars[idx]` will trigger different code paths depending on whether the index is in bounds or not.  It will be \"more\" constant time than the current early exit code, but I wonder if it's better to draw a hard line and say \"we don't leak contents; we do leak the length; use appropriately\" instead of \"we don't leak contents; we sorta leak the length\"."}}