Repository: cloudflare/wildebeest
File: backend/src/utils/httpsigjs/parser.ts (TypeScript)

Code before:
						if (c === ',') {
							tmpName = ''
							substate = ParamsState.Name
						} else {
							throw new InvalidHeaderError('bad param format')
						}
						break

					default:
						throw new Error('Invalid substate')
				}
				break

			default:
				throw new Error('Invalid substate')
		}
	}

	if (!parsed.params.headers || parsed.params.headers === '') {
		if (request.headers.has('x-date')) {
			parsed.params.headers = ['x-date']
		} else {
			parsed.params.headers = ['date']
		}
	} else {
		parsed.params.headers = (parsed.params.headers as string).split(' ')
	}

	// Minimally validate the parsed object
	if (!parsed.scheme || parsed.scheme !== 'Signature') throw new InvalidHeaderError('scheme was not "Signature"')

	if (!parsed.params.keyId) throw new InvalidHeaderError('keyId was not specified')

	if (!parsed.params.algorithm) throw new InvalidHeaderError('algorithm was not specified')

	if (!parsed.params.signature) throw new InvalidHeaderError('signature was not specified')

	if (['date', 'x-date', '(created)'].every((hdr) => (parsed.params.headers as string[]).indexOf(hdr) < 0)) {
		throw new MissingHeaderError('no signed date header')
	}

	// Check the algorithm against the official list
	try {
		validateAlgorithm(parsed.params.algorithm, 'rsa')
	} catch (e) {
		if (e instanceof InvalidAlgorithmError)
			throw new InvalidParamsError(parsed.params.algorithm + ' is not ' + 'supported')
		else throw e
	}

	// Build the signingString

Review comment (security):
Rather than casting here we should create a new `headers: string[]` variable that is assigned from the `parsed.params.headers` property.
Also that property should get a proper type above, e.g.

```
  interface ParsedRequest {
    scheme: string
    params: Record<string, string>
    signingString: string
  }
	const parsed: ParsedRequest = {
		scheme: authz === request.headers.get(HEADER.SIG) ? 'Signature' : '',
		params: {},
		signingString: '',
	}
```

Code after:
							}
							tmpValue += c
						}
						break

					case ParamsState.Comma:
						if (c === ',') {
							tmpName = ''
							substate = ParamsState.Name
						} else {
							throw new InvalidHeaderError('bad param format')
						}
						break

					default:
						throw new Error('Invalid substate')
				}
				break

			default:
				throw new Error('Invalid substate')
		}
	}

	let parsedHeaders: string[] = []

	if (!parsed.params.headers || parsed.params.headers === '') {
		if (request.headers.has('x-date')) {
			parsedHeaders = ['x-date']
		} else {
			parsedHeaders = ['date']
		}
	} else if (typeof parsed.params.headers === 'string') {
		parsedHeaders = parsed.params.headers.split(' ')
	}

	// Minimally validate the parsed object
	if (!parsed.scheme || parsed.scheme !== 'Signature') throw new InvalidHeaderError('scheme was not "Signature"')

	if (!parsed.params.keyId) throw new InvalidHeaderError('keyId was not specified')

	if (!parsed.params.algorithm) throw new InvalidHeaderError('algorithm was not specified')

	if (!parsed.params.signature) throw new InvalidHeaderError('signature was not specified')

	if (['date', 'x-date', '(created)'].every((hdr) => parsedHeaders.indexOf(hdr) < 0)) {
		throw new MissingHeaderError('no signed date header')
	}

	// Check the algorithm against the official list
	try {