2016-02-14 2 views
1

Я программно развертывается конечной точки Java WebSocket (JSR356 3.1), и я хочу, чтобы проверить значение заголовка Origin запроса в целях смягчения CSRF атак, и принимать только запросы, рукопожатия которых Host и Origin значения заголовка совпадают.Origin проверка в Java-сокетов, чтобы предотвратить CSRF

Мне кажется, что путь является переопределение метода:

ServerEndpointConfig.Configurator.checkOrigin(String originHeaderValue)

(реализации предоставленной Tomcat 8 всегда возвращает true), но проблема, которую я вижу, что этот метод имеет только один параметр, и я пропускаю значение заголовка хоста, чтобы сравнить это значение с.

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

Я рассматриваю возможность выполнения этой проверки внутри реализации modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response), где я могу читать все значения заголовка, но я уверен, что я что-то недопонимаю.

Так что мой вопрос:

Что такое правильный способ выполнения этой проверки?

Спасибо, Него

+0

да это не кажется правильным; API должен был предоставить приложению возможность отклонить или принять рукопожатие. – ZhongYu

+0

Спасибо @ bayou.io, я боюсь. Я просто отметил вопрос «tyrus», надеясь, что эксперт JSR сможет его прочитать. – idelvall

ответ

1

Порывшись немного в проблему, я пришел к выводу, что WebSocket API (JSR-356) предназначен для выполнения проверки происхождения против «белого списка», ряд предопределенных допускается происхождение (как вы можете видеть в this example от Weblogic):

... 
import javax.websocket.server.ServerEndpointConfig; 

public class MyConfigurator extends ServerEndpointConfig.Configurator { 
... 
    private static final String ORIGIN = "http://www.example.com:7001"; 

    @Override 
    public boolean checkOrigin(String originHeaderValue) { 
     return ORIGIN.equals(originHeaderValue) 
    } 
} 
... 

но, к сожалению, этот API не предусматривает возможность осуществления проверки заголовка Host против Origin.

В качестве обходного пути для тех поставщиков услуг, которые размещают конечную точку websocket позади стека сервлетов (например, Tomcat, где механизм Websocket запускается с помощью фильтра сервлета org.apache.tomcat.websocket.server.WsFilter), вы можете создать внешний фильтр, который разрешает threadlocal доступ к запросу , чтобы использовать его в методе checkOrigin() для получения значения заголовка Host.

Это заставляет меня задаться вопросом, почему этот тип проверки не предпочтительнее белый список решения, и только что нашел этот интересный пост: Origin and Host headers for same domain requests