{"record":{"id":"f3a3b753531cb818","repo":"arsduo/koala","slug":"unsupported-algorithm-envelope-algorithm","errorCode":null,"errorMessage":"Unsupported algorithm #{envelope['algorithm']}","messagePattern":"Unsupported algorithm #(.+?)","errorType":"validation","errorClass":"Koala::Facebook::OAuthSignatureError","httpStatus":null,"severity":"error","filePath":"lib/koala/oauth.rb","lineNumber":245,"sourceCode":"          info[\"access_token\"]\n        end\n      end\n\n      # Parses a signed request string provided by Facebook to canvas apps or in a secure cookie.\n      #\n      # @param input the signed request from Facebook\n      #\n      # @raise OAuthSignatureError if the signature is incomplete, invalid, or using an unsupported algorithm\n      #\n      # @return a hash of the validated request information\n      def parse_signed_request(input)\n        encoded_sig, encoded_envelope = input.split('.', 2)\n        raise OAuthSignatureError, 'Invalid (incomplete) signature data' unless encoded_sig && encoded_envelope\n\n        signature = base64_url_decode(encoded_sig).unpack(\"H*\").first\n        envelope = JSON.parse(base64_url_decode(encoded_envelope))\n\n        raise OAuthSignatureError, \"Unsupported algorithm #{envelope['algorithm']}\" if envelope['algorithm'] != 'HMAC-SHA256'\n\n        # now see if the signature is valid (digest, key, data)\n        hmac = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new, @app_secret, encoded_envelope)\n        raise OAuthSignatureError, 'Invalid signature' if (signature != hmac)\n\n        envelope\n      end\n\n      protected\n\n      def get_token_from_server(args, post = false, options = {})\n        # fetch the result from Facebook's servers\n        response = fetch_token_string(args, post, \"access_token\", options)\n        parse_access_token(response)\n      end\n\n      def parse_access_token(response_text)\n        JSON.parse(response_text)","sourceCodeStart":227,"sourceCodeEnd":263,"githubUrl":"https://github.com/arsduo/koala/blob/47d052063ef8b5644fb59e279da0b52687999f55/lib/koala/oauth.rb#L227-L263","documentation":"After base64-decoding the payload half of a signed_request, OAuth#parse_signed_request requires envelope[\"algorithm\"] to be exactly HMAC-SHA256, the only algorithm Facebook uses for signed requests. Anything else (including a missing algorithm key) raises OAuthSignatureError with the received value embedded in the message. This is a deliberate safety stop in the same family as JWT alg-confusion: verifying a payload under an unexpected algorithm would let the sender choose how the signature is checked.","triggerScenarios":"parse_signed_request (or get_user_info_from_cookies via parse_signed_cookie) receives a syntactically valid signature.envelope string whose decoded JSON names a different algorithm (HMAC-SHA1, RS256, a lowercase variant) or has no algorithm field: signed requests minted by another provider or a test tool, a corrupted envelope that still parses as JSON, or a hand-written fixture.","commonSituations":"Sharing JWT-style fixtures across provider test suites; routing a Google or Apple token into the Facebook parser in a multi-provider login; base64 mishandling that shifts the payload so fields land wrong; Facebook-side payload experiments.","solutions":["Decode and inspect the payload before blaming the parser: JSON.parse(Base64.decode64(payload.tr(\"-_\", \"+/\"))) and check the algorithm field.","Make sure the value came from Facebook (canvas POST signed_request param or fbsr_ cookie) and was not re-encoded on the way in.","Rescue OAuthSignatureError and reject the request; never relax the algorithm check.","Rebuild test fixtures from a real captured signed_request."],"exampleFix":"// before\nauth = @oauth.parse_signed_request(params[:signed_request])\n\n// after\nbegin\n  auth = @oauth.parse_signed_request(params[:signed_request])\nrescue Koala::Facebook::OAuthSignatureError => e\n  Rails.logger.warn(\"rejected signed_request: #{e.message}\")\n  auth = nil\nend","handlingStrategy":"try-catch","validationCode":"def facebook_signed_request?(raw)\n  sig, payload = raw.to_s.split(\".\", 2)\n  return false unless sig && payload\n  envelope = JSON.parse(Base64.decode64(payload.tr(\"-_\", \"+/\"))) rescue nil\n  envelope.is_a?(Hash) && envelope[\"algorithm\"] == \"HMAC-SHA256\"\nend","typeGuard":null,"tryCatchPattern":"begin\n  auth = @oauth.parse_signed_request(raw)\nrescue Koala::Facebook::OAuthSignatureError => e\n  report_security_event(e.message) # unexpected algorithm deserves alerting\n  head :unauthorized\nend","preventionTips":["Capture real signed_request values from Facebook for tests instead of synthesizing JWT-like tokens","Label tokens per provider so a non-Facebook token never reaches the Facebook parser","Treat any algorithm other than HMAC-SHA256 as a security signal, not just a login failure"],"tags":["oauth","signed-request","algorithm","signature","security","koala","facebook"],"backgroundTag":"unsupported-signature-algorithm","analyzedSha":"47d052063ef8b5644fb59e279da0b52687999f55","analyzedAt":"2026-08-23T10:19:03.891Z","schemaVersion":2},"datasetVersion":"2026-08-23T13:39:53.451Z"}