Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1207)

Side by Side Diff: Source/core/frame/csp/CSPSourceList.cpp

Issue 700463003: CSP: Harden hash parsing. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Nit. Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-malformed-expected.txt ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "config.h" 5 #include "config.h"
6 #include "core/frame/csp/CSPSourceList.h" 6 #include "core/frame/csp/CSPSourceList.h"
7 7
8 #include "core/frame/csp/CSPSource.h" 8 #include "core/frame/csp/CSPSource.h"
9 #include "core/frame/csp/ContentSecurityPolicy.h" 9 #include "core/frame/csp/ContentSecurityPolicy.h"
10 #include "platform/ParsingUtilities.h" 10 #include "platform/ParsingUtilities.h"
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 // hash-source = "'" hash-algorithm "-" hash-value "'" 281 // hash-source = "'" hash-algorithm "-" hash-value "'"
282 // hash-algorithm = "sha1" / "sha256" / "sha384" / "sha512" 282 // hash-algorithm = "sha1" / "sha256" / "sha384" / "sha512"
283 // hash-value = 1*( ALPHA / DIGIT / "+" / "/" / "=" ) 283 // hash-value = 1*( ALPHA / DIGIT / "+" / "/" / "=" )
284 // 284 //
285 bool CSPSourceList::parseHash(const UChar* begin, const UChar* end, DigestValue& hash, ContentSecurityPolicyHashAlgorithm& hashAlgorithm) 285 bool CSPSourceList::parseHash(const UChar* begin, const UChar* end, DigestValue& hash, ContentSecurityPolicyHashAlgorithm& hashAlgorithm)
286 { 286 {
287 // Any additions or subtractions from this struct should also modify the 287 // Any additions or subtractions from this struct should also modify the
288 // respective entries in the kAlgorithmMap array in checkDigest(). 288 // respective entries in the kAlgorithmMap array in checkDigest().
289 static const struct { 289 static const struct {
290 const char* prefix; 290 const char* prefix;
291 ContentSecurityPolicyHashAlgorithm algorithm; 291 ContentSecurityPolicyHashAlgorithm type;
292 } kSupportedPrefixes[] = { 292 } kSupportedPrefixes[] = {
293 { "'sha1-", ContentSecurityPolicyHashAlgorithmSha1 }, 293 { "'sha1-", ContentSecurityPolicyHashAlgorithmSha1 },
294 { "'sha256-", ContentSecurityPolicyHashAlgorithmSha256 }, 294 { "'sha256-", ContentSecurityPolicyHashAlgorithmSha256 },
295 { "'sha384-", ContentSecurityPolicyHashAlgorithmSha384 }, 295 { "'sha384-", ContentSecurityPolicyHashAlgorithmSha384 },
296 { "'sha512-", ContentSecurityPolicyHashAlgorithmSha512 } 296 { "'sha512-", ContentSecurityPolicyHashAlgorithmSha512 }
297 }; 297 };
298 298
299 String prefix; 299 String prefix;
300 hashAlgorithm = ContentSecurityPolicyHashAlgorithmNone; 300 hashAlgorithm = ContentSecurityPolicyHashAlgorithmNone;
301 size_t hashLength = end - begin;
301 302
302 // Instead of this sizeof() calculation to get the length of this array, 303 for (const auto& algorithm : kSupportedPrefixes) {
303 // it would be preferable to use WTF_ARRAY_LENGTH for simplicity and to 304 if (hashLength > strlen(algorithm.prefix) && equalIgnoringCase(algorithm .prefix, begin, strlen(algorithm.prefix))) {
304 // guarantee a compile time calculation. Unfortunately, on some 305 prefix = algorithm.prefix;
305 // compliers, the call to WTF_ARRAY_LENGTH fails on arrays of anonymous 306 hashAlgorithm = algorithm.type;
306 // stucts, so, for now, it is necessary to resort to this sizeof
307 // calculation.
308 for (size_t i = 0; i < (sizeof(kSupportedPrefixes) / sizeof(kSupportedPrefix es[0])); i++) {
309 if (equalIgnoringCase(kSupportedPrefixes[i].prefix, begin, strlen(kSuppo rtedPrefixes[i].prefix))) {
310 prefix = kSupportedPrefixes[i].prefix;
311 hashAlgorithm = kSupportedPrefixes[i].algorithm;
312 break; 307 break;
313 } 308 }
314 } 309 }
315 310
316 if (hashAlgorithm == ContentSecurityPolicyHashAlgorithmNone) 311 if (hashAlgorithm == ContentSecurityPolicyHashAlgorithmNone)
317 return true; 312 return true;
318 313
319 const UChar* position = begin + prefix.length(); 314 const UChar* position = begin + prefix.length();
320 const UChar* hashBegin = position; 315 const UChar* hashBegin = position;
321 316
317 ASSERT(position < end);
322 skipWhile<UChar, isBase64EncodedCharacter>(position, end); 318 skipWhile<UChar, isBase64EncodedCharacter>(position, end);
323 ASSERT(hashBegin <= position); 319 ASSERT(hashBegin <= position);
324 320
325 // Base64 encodings may end with exactly one or two '=' characters 321 // Base64 encodings may end with exactly one or two '=' characters
326 skipExactly<UChar>(position, position + 1, '='); 322 if (position < end)
327 skipExactly<UChar>(position, position + 1, '='); 323 skipExactly<UChar>(position, position + 1, '=');
324 if (position < end)
325 skipExactly<UChar>(position, position + 1, '=');
328 326
329 if ((position + 1) != end || *position != '\'' || !(position - hashBegin)) 327 if (position + 1 != end || *position != '\'' || position == hashBegin)
330 return false; 328 return false;
331 329
332 Vector<char> hashVector; 330 Vector<char> hashVector;
333 base64Decode(hashBegin, position - hashBegin, hashVector); 331 base64Decode(hashBegin, position - hashBegin, hashVector);
334 if (hashVector.size() > kMaxDigestSize) 332 if (hashVector.size() > kMaxDigestSize)
335 return false; 333 return false;
336 hash.append(reinterpret_cast<uint8_t*>(hashVector.data()), hashVector.size() ); 334 hash.append(reinterpret_cast<uint8_t*>(hashVector.data()), hashVector.size() );
337 return true; 335 return true;
338 } 336 }
339 337
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 } 478 }
481 479
482 void CSPSourceList::addSourceHash(const ContentSecurityPolicyHashAlgorithm& algo rithm, const DigestValue& hash) 480 void CSPSourceList::addSourceHash(const ContentSecurityPolicyHashAlgorithm& algo rithm, const DigestValue& hash)
483 { 481 {
484 m_hashes.add(CSPHashValue(algorithm, hash)); 482 m_hashes.add(CSPHashValue(algorithm, hash));
485 m_hashAlgorithmsUsed |= algorithm; 483 m_hashAlgorithmsUsed |= algorithm;
486 } 484 }
487 485
488 486
489 } // namespace blink 487 } // namespace blink
OLDNEW
« no previous file with comments | « LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-malformed-expected.txt ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698