Closed8

「$.ajax()」を使えば Header インジェクションを防げるのは何故か

kyoune01kyoune01

問題定義;「 jQuery の ajax 関数を使ってるのでHTTPリクエストの Header インジェクションは起きません」と言われたので起きないのかどうか確認する

kyoune01kyoune01

状況;※ajax() へ document から値を独自エスケープ無しで挿入する意図

const credentials = document.getElementById('target').dataset.credentials;
const type = 'hogefuga';
// ...
$.ajax({
  // >= 1.5
  header: {'Authorization' : type + credentials },
  // <=1.4
  beforeSend: function(xhr) {
    xhr.setRequestHeader('Authorization', type + credentials);
  },
}).done(function() {
    console.log('成功');
});
kyoune01kyoune01

header: {'Authorization' : type + credentials } を使う場合
※jquery-3.6.0.js を読む

kyoune01kyoune01

メインの処理

jQuery.extend( {
  // Main method
  ajax: function( url, options ) {
    // If url is an object, simulate pre-1.5 signature
    if ( typeof url === "object" ) {
      options = url;
      url = undefined;
    }

    // Create the final options object
    s = jQuery.ajaxSetup( {}, options ),

    // Check for headers option
    for ( i in s.headers ) {
      jqXHR.setRequestHeader( i, s.headers[ i ] );
    }
} );
kyoune01kyoune01

jqXHR.setRequestHeader() の中身
そのまま入れてそう

// jQuery.extend 内

// Headers (they are sent all at once)
requestHeaders = {},
requestHeadersNames = {},

// Fake xhr
jqXHR = {
  // Caches the header
  setRequestHeader: function( name, value ) {
      if ( completed == null ) {
          name = requestHeadersNames[ name.toLowerCase() ] =
              requestHeadersNames[ name.toLowerCase() ] || name;
          requestHeaders[ name ] = value;
      }
      return this;
  },
};
kyoune01kyoune01

送信処理

// jQuery.extend 内

// Get transport
transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );

// If no transport, we auto-abort
if ( !transport ) {
  done( -1, "No Transport" );
} else {

  try {
    completed = false;
    transport.send( requestHeaders, done );
  } else {
    // ...
  }
}
kyoune01kyoune01

beforeSend: function(xhr) {} を使う場合
※jquery-1.4.js を読む

このスクラップは2024/02/06にクローズされました