File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -6,10 +6,23 @@ import { ReceiptProcessor } from "./ReceiptProcessor";
66
77require ( 'isomorphic-fetch' ) ;
88
9+ // Microsoft Graph sends an opaque, URL-safe validationToken when a subscription is
10+ // created and expects it echoed back verbatim as text/plain. The value is attacker
11+ // influenceable, so strip anything outside the token's known-safe character set
12+ // before reflecting it. This is a no-op for legitimate tokens (base64url/base64)
13+ // while removing the characters needed for reflected cross-site scripting.
14+ const sanitizeValidationToken = ( value : unknown ) : string =>
15+ String ( value ) . replace ( / [ ^ A - Z a - z 0 - 9 . _ ~ + / = \- ] / g, '' ) ;
16+
917 export const onReceiptAdded = async ( req : Request , res : Response ) => {
1018 const validationToken = req . query [ 'validationToken' ] ;
1119 if ( validationToken ) {
12- res . status ( 200 ) . type ( 'text/plain' ) . send ( String ( validationToken ) ) ;
20+ const safeValidationToken = sanitizeValidationToken ( validationToken ) ;
21+ res
22+ . status ( 200 )
23+ . type ( 'text/plain' )
24+ . set ( 'X-Content-Type-Options' , 'nosniff' )
25+ . send ( safeValidationToken ) ;
1326 return ;
1427 }
1528
You can’t perform that action at this time.
0 commit comments