зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1029620 P4 Make HTTP token and header value validation accessible via nsNetUtil.h r=ehsan r=mcmanus
This commit is contained in:
Родитель
3fa4e60611
Коммит
0d01c09be4
|
@ -504,46 +504,6 @@ nsCORSListenerProxy::OnStartRequest(nsIRequest* aRequest,
|
|||
return mOuterListener->OnStartRequest(aRequest, aContext);
|
||||
}
|
||||
|
||||
bool
|
||||
IsValidHTTPToken(const nsCSubstring& aToken)
|
||||
{
|
||||
if (aToken.IsEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCSubstring::const_char_iterator iter, end;
|
||||
|
||||
aToken.BeginReading(iter);
|
||||
aToken.EndReading(end);
|
||||
|
||||
while (iter != end) {
|
||||
if (*iter <= 32 ||
|
||||
*iter >= 127 ||
|
||||
*iter == '(' ||
|
||||
*iter == ')' ||
|
||||
*iter == '<' ||
|
||||
*iter == '>' ||
|
||||
*iter == '@' ||
|
||||
*iter == ',' ||
|
||||
*iter == ';' ||
|
||||
*iter == ':' ||
|
||||
*iter == '\\' ||
|
||||
*iter == '\"' ||
|
||||
*iter == '/' ||
|
||||
*iter == '[' ||
|
||||
*iter == ']' ||
|
||||
*iter == '?' ||
|
||||
*iter == '=' ||
|
||||
*iter == '{' ||
|
||||
*iter == '}') {
|
||||
return false;
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsCORSListenerProxy::CheckRequestApproved(nsIRequest* aRequest)
|
||||
{
|
||||
|
@ -616,7 +576,7 @@ nsCORSListenerProxy::CheckRequestApproved(nsIRequest* aRequest)
|
|||
if (method.IsEmpty()) {
|
||||
continue;
|
||||
}
|
||||
if (!IsValidHTTPToken(method)) {
|
||||
if (!NS_IsValidHTTPToken(method)) {
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
foundMethod |= mPreflightMethod.Equals(method);
|
||||
|
@ -635,7 +595,7 @@ nsCORSListenerProxy::CheckRequestApproved(nsIRequest* aRequest)
|
|||
if (header.IsEmpty()) {
|
||||
continue;
|
||||
}
|
||||
if (!IsValidHTTPToken(header)) {
|
||||
if (!NS_IsValidHTTPToken(header)) {
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
headers.AppendElement(header);
|
||||
|
|
|
@ -21,9 +21,6 @@ class nsIURI;
|
|||
class nsIParser;
|
||||
class nsIPrincipal;
|
||||
|
||||
extern bool
|
||||
IsValidHTTPToken(const nsCSubstring& aToken);
|
||||
|
||||
nsresult
|
||||
NS_StartCORSPreflight(nsIChannel* aRequestChannel,
|
||||
nsIStreamListener* aListener,
|
||||
|
|
|
@ -1295,7 +1295,7 @@ nsXMLHttpRequest::IsSafeHeader(const nsACString& header, nsIHttpChannel* httpCha
|
|||
if (token.IsEmpty()) {
|
||||
continue;
|
||||
}
|
||||
if (!IsValidHTTPToken(token)) {
|
||||
if (!NS_IsValidHTTPToken(token)) {
|
||||
return false;
|
||||
}
|
||||
if (header.Equals(token, nsCaseInsensitiveCStringComparator())) {
|
||||
|
@ -3093,7 +3093,7 @@ nsXMLHttpRequest::SetRequestHeader(const nsACString& header,
|
|||
|
||||
// Step 3
|
||||
// Make sure we don't store an invalid header name in mCORSUnsafeHeaders
|
||||
if (!IsValidHTTPToken(header)) { // XXX nsHttp::IsValidToken?
|
||||
if (!NS_IsValidHTTPToken(header)) {
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
|
||||
|
|
|
@ -2421,4 +2421,18 @@ NS_Get32BitsOfPseudoRandom()
|
|||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the given string is a reasonable HTTP header value given the
|
||||
* definition in RFC 2616 section 4.2. Currently we don't pay the cost to do
|
||||
* full, sctrict validation here since it would require fulling parsing the
|
||||
* value.
|
||||
*/
|
||||
bool NS_IsReasonableHTTPHeaderValue(const nsACString& aValue);
|
||||
|
||||
/**
|
||||
* Return true if the given string is a valid HTTP token per RFC 2616 section
|
||||
* 2.2.
|
||||
*/
|
||||
bool NS_IsValidHTTPToken(const nsACString& aToken);
|
||||
|
||||
#endif // !nsNetUtil_h__
|
||||
|
|
|
@ -47,6 +47,7 @@ UNIFIED_SOURCES += [
|
|||
'nsMIMEInputStream.cpp',
|
||||
'nsNetAddr.cpp',
|
||||
'nsNetStrings.cpp',
|
||||
'nsNetUtil.cpp',
|
||||
'nsNetworkZonePolicy.cpp',
|
||||
'nsPACMan.cpp',
|
||||
'nsPreloadedStream.cpp',
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim:set ts=4 sw=4 sts=4 et cin: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsHttp.h"
|
||||
|
||||
bool NS_IsReasonableHTTPHeaderValue(const nsACString& aValue)
|
||||
{
|
||||
return mozilla::net::nsHttp::IsReasonableHeaderValue(aValue);
|
||||
}
|
||||
|
||||
bool NS_IsValidHTTPToken(const nsACString& aToken)
|
||||
{
|
||||
return mozilla::net::nsHttp::IsValidToken(aToken);
|
||||
}
|
|
@ -1119,18 +1119,12 @@ HttpBaseChannel::SetRequestHeader(const nsACString& aHeader,
|
|||
LOG(("HttpBaseChannel::SetRequestHeader [this=%p header=\"%s\" value=\"%s\" merge=%u]\n",
|
||||
this, flatHeader.get(), flatValue.get(), aMerge));
|
||||
|
||||
// Header names are restricted to valid HTTP tokens.
|
||||
if (!nsHttp::IsValidToken(flatHeader))
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
// Header values MUST NOT contain line-breaks. RFC 2616 technically
|
||||
// permits CTL characters, including CR and LF, in header values provided
|
||||
// they are quoted. However, this can lead to problems if servers do not
|
||||
// interpret quoted strings properly. Disallowing CR and LF here seems
|
||||
// reasonable and keeps things simple. We also disallow a null byte.
|
||||
if (flatValue.FindCharInSet("\r\n") != kNotFound ||
|
||||
flatValue.Length() != strlen(flatValue.get()))
|
||||
// Verify header names are valid HTTP tokens and header values are reasonably
|
||||
// close to whats allowed in RFC 2616.
|
||||
if (!nsHttp::IsValidToken(flatHeader) ||
|
||||
!nsHttp::IsReasonableHeaderValue(flatValue)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
nsHttpAtom atom = nsHttp::ResolveAtom(flatHeader.get());
|
||||
if (!atom) {
|
||||
|
|
|
@ -243,6 +243,24 @@ nsHttp::IsValidToken(const char *start, const char *end)
|
|||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
bool
|
||||
nsHttp::IsReasonableHeaderValue(const nsACString &s)
|
||||
{
|
||||
// Header values MUST NOT contain line-breaks. RFC 2616 technically
|
||||
// permits CTL characters, including CR and LF, in header values provided
|
||||
// they are quoted. However, this can lead to problems if servers do not
|
||||
// interpret quoted strings properly. Disallowing CR and LF here seems
|
||||
// reasonable and keeps things simple. We also disallow a null byte.
|
||||
const nsACString::char_type* end = s.EndReading();
|
||||
for (const nsACString::char_type* i = s.BeginReading(); i != end; ++i) {
|
||||
if (*i == '\r' || *i == '\n' || *i == '\0') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const char *
|
||||
nsHttp::FindToken(const char *input, const char *token, const char *seps)
|
||||
{
|
||||
|
|
|
@ -132,11 +132,15 @@ struct nsHttp
|
|||
// section 2.2
|
||||
static bool IsValidToken(const char *start, const char *end);
|
||||
|
||||
static inline bool IsValidToken(const nsCString &s) {
|
||||
const char *start = s.get();
|
||||
return IsValidToken(start, start + s.Length());
|
||||
static inline bool IsValidToken(const nsACString &s) {
|
||||
return IsValidToken(s.BeginReading(), s.EndReading());
|
||||
}
|
||||
|
||||
// Returns true if the specified value is reasonable given the defintion
|
||||
// in RFC 2616 section 4.2. Full strict validation is not performed
|
||||
// currently as it would require full parsing of the value.
|
||||
static bool IsReasonableHeaderValue(const nsACString &s);
|
||||
|
||||
// find the first instance (case-insensitive comparison) of the given
|
||||
// |token| in the |input| string. the |token| is bounded by elements of
|
||||
// |separators| and may appear at the beginning or end of the |input|
|
||||
|
|
Загрузка…
Ссылка в новой задаче