Encoding the x-ycm-hmac header value as base64.

We need to respect RFC 5987.
This commit is contained in:
Strahinja Val Markovic 2014-05-09 10:37:20 -07:00
parent ec65950a9b
commit 9691bd9236
2 changed files with 18 additions and 9 deletions

View File

@ -20,6 +20,7 @@
import vim
import requests
import urlparse
from base64 import b64decode, b64encode
from retries import retries
from requests_futures.sessions import FuturesSession
from ycm.unsafe_thread_pool_executor import UnsafeThreadPoolExecutor
@ -124,8 +125,8 @@ class BaseRequest( object ):
if not request_body:
request_body = ''
headers = dict( _HEADERS )
headers[ _HMAC_HEADER ] = utils.CreateHexHmac( request_body,
BaseRequest.hmac_secret )
headers[ _HMAC_HEADER ] = b64encode(
utils.CreateHexHmac( request_body, BaseRequest.hmac_secret ) )
return headers
session = FuturesSession( executor = _EXECUTOR )
@ -171,9 +172,10 @@ def JsonFromFuture( future ):
def _ValidateResponseObject( response ):
if not utils.ContentHexHmacValid( response.content,
response.headers[ _HMAC_HEADER ],
BaseRequest.hmac_secret ):
if not utils.ContentHexHmacValid(
response.content,
b64decode( response.headers[ _HMAC_HEADER ] ),
BaseRequest.hmac_secret ):
raise RuntimeError( 'Received invalid HMAC for response!' )
return True

View File

@ -19,6 +19,7 @@
import logging
import httplib
from base64 import b64decode, b64encode
from bottle import request, response, abort
from ycm import utils
@ -30,6 +31,9 @@ _HMAC_HEADER = 'x-ycm-hmac'
# We want to ensure that every request coming in has a valid HMAC set in the
# x-ycm-hmac header and that every response coming out sets such a valid header.
# This is to prevent security issues with possible remote code execution.
# The x-ycm-hmac value is encoded as base64 during transport instead of sent raw
# because https://tools.ietf.org/html/rfc5987 says header values must be in the
# ISO-8859-1 character set.
class HmacPlugin( object ):
name = 'hmac'
api = 2
@ -54,9 +58,12 @@ class HmacPlugin( object ):
def RequestAuthenticated( body, hmac_secret ):
return utils.ContentHexHmacValid( body,
request.headers[ _HMAC_HEADER ],
hmac_secret )
return utils.ContentHexHmacValid(
body,
b64decode( request.headers[ _HMAC_HEADER ] ),
hmac_secret )
def SetHmacHeader( body, hmac_secret ):
response.headers[ _HMAC_HEADER ] = utils.CreateHexHmac( body, hmac_secret )
response.headers[ _HMAC_HEADER ] = b64encode(
utils.CreateHexHmac( body, hmac_secret ) )