Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | 5x 5x 6x 5x 19x 1x 18x 1x 17x 17x 3x 2x 1x 14x 14x 14x 1x 15x 15x 2x 19x 69x 69x 6x 6x 6x | import { FlowError } from '../errors'
import { IdentificationEvent } from './identificationClient'
import { getIp } from '../utils/headers'
const ALLOWED_REQUEST_TIMESTAMP_DIFF_MS = 3000
const methodsWithoutOrigin = ['GET', 'HEAD']
export class TamperingError extends FlowError {
constructor(message: string) {
super({
message,
isPrivate: true,
httpStatus: 403,
})
}
}
type TamperingHandler = {
verify: (event: IdentificationEvent, request: Request) => void | Promise<void>
}
const tamperingHandlers: TamperingHandler[] = [
{
verify: (event) => {
if (event.replayed) {
throw new TamperingError('Identification request was replayed.')
}
},
},
{
verify: (event) => {
if (new Date().valueOf() - event.timestamp.valueOf() > ALLOWED_REQUEST_TIMESTAMP_DIFF_MS) {
throw new TamperingError('Old identification request, potential replay attack.')
}
},
},
{
verify: (event, request) => {
const originHeader = request.headers.get('origin')
if (!originHeader) {
if (methodsWithoutOrigin.includes(request.method)) {
return
}
throw new TamperingError('Missing origin header, potential tampering or malformed request.')
}
const origin = new URL(originHeader).origin
const identificationOrigin = new URL(event.url).origin
if (origin !== identificationOrigin) {
throw new TamperingError(
`Unexpected origin (${origin} is not ${identificationOrigin}), potential replay attack.`
)
}
},
},
{
verify: async (event, request) => {
const requestIp = await getIp(request.headers)
if (requestIp !== event.ip_address) {
throw new TamperingError('Unexpected IP address, potential replay attack.')
}
},
},
]
export async function handleTampering(event: IdentificationEvent, request: Request) {
for (const handler of tamperingHandlers) {
try {
await handler.verify(event, request)
} catch (error) {
Eif (error instanceof TamperingError) {
console.error('Tampering verification failed:', error.message, event)
throw error
}
console.error('Error verifying tampering protection:', error)
throw new TamperingError('Tampering verification failed.')
}
}
}
|