Skip to content

Commit

Permalink
Merge pull request #318 from duracelltomi/fix/unprotected_headers_ip_…
Browse files Browse the repository at this point in the history
…address

Fix/unprotected headers ip address
  • Loading branch information
duracelltomi authored Jan 23, 2024
2 parents cbdf800 + 3975941 commit 390b220
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 56 deletions.
65 changes: 35 additions & 30 deletions admin/admin-tab-basicdata.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,119 +9,124 @@
*/

$GLOBALS['gtm4wp_includefieldtexts'] = array(
GTM4WP_OPTION_INCLUDE_POSTTYPE => array(
GTM4WP_OPTION_INCLUDE_POSTTYPE => array(
'label' => esc_html__( 'Posttype of current post/archive', 'duracelltomi-google-tag-manager' ),
'description' => esc_html__( 'Check this option to include the type of the current post or archive page (post, page or any custom post type).', 'duracelltomi-google-tag-manager' ),
'phase' => GTM4WP_PHASE_STABLE,
),
GTM4WP_OPTION_INCLUDE_CATEGORIES => array(
GTM4WP_OPTION_INCLUDE_CATEGORIES => array(
'label' => esc_html__( 'Category list of current post/archive', 'duracelltomi-google-tag-manager' ),
'description' => esc_html__( 'Check this option to include the category names of the current post or archive page', 'duracelltomi-google-tag-manager' ),
'phase' => GTM4WP_PHASE_STABLE,
),
GTM4WP_OPTION_INCLUDE_TAGS => array(
GTM4WP_OPTION_INCLUDE_TAGS => array(
'label' => esc_html__( 'Tags of current post', 'duracelltomi-google-tag-manager' ),
'description' => esc_html__( 'Check this option to include the tags of the current post.', 'duracelltomi-google-tag-manager' ),
'phase' => GTM4WP_PHASE_STABLE,
),
GTM4WP_OPTION_INCLUDE_AUTHORID => array(
GTM4WP_OPTION_INCLUDE_AUTHORID => array(
'label' => esc_html__( 'Post author ID', 'duracelltomi-google-tag-manager' ),
'description' => esc_html__( 'Check this option to include the ID of the author on the current post or author page.', 'duracelltomi-google-tag-manager' ),
'phase' => GTM4WP_PHASE_STABLE,
),
GTM4WP_OPTION_INCLUDE_AUTHOR => array(
GTM4WP_OPTION_INCLUDE_AUTHOR => array(
'label' => esc_html__( 'Post author name', 'duracelltomi-google-tag-manager' ),
'description' => esc_html__( 'Check this option to include the name of the author on the current post or author page.', 'duracelltomi-google-tag-manager' ),
'phase' => GTM4WP_PHASE_STABLE,
),
GTM4WP_OPTION_INCLUDE_POSTDATE => array(
GTM4WP_OPTION_INCLUDE_POSTDATE => array(
'label' => esc_html__( 'Post date', 'duracelltomi-google-tag-manager' ),
'description' => esc_html__( 'Check this option to include the date of the current post. This will include 4 dataLayer variables: full date, post year, post month, post date.', 'duracelltomi-google-tag-manager' ),
'phase' => GTM4WP_PHASE_STABLE,
),
GTM4WP_OPTION_INCLUDE_POSTTITLE => array(
GTM4WP_OPTION_INCLUDE_POSTTITLE => array(
'label' => esc_html__( 'Post title', 'duracelltomi-google-tag-manager' ),
'description' => esc_html__( 'Check this option to include the title of the current post.', 'duracelltomi-google-tag-manager' ),
'phase' => GTM4WP_PHASE_STABLE,
),
GTM4WP_OPTION_INCLUDE_POSTCOUNT => array(
GTM4WP_OPTION_INCLUDE_POSTCOUNT => array(
'label' => esc_html__( 'Post count', 'duracelltomi-google-tag-manager' ),
'description' => esc_html__( 'Check this option to include the count of the posts currently shown on the page and the total number of posts in the category/tag/any taxonomy.', 'duracelltomi-google-tag-manager' ),
'phase' => GTM4WP_PHASE_STABLE,
),
GTM4WP_OPTION_INCLUDE_POSTID => array(
GTM4WP_OPTION_INCLUDE_POSTID => array(
'label' => esc_html__( 'Post ID', 'duracelltomi-google-tag-manager' ),
'description' => esc_html__( 'Check this option to include the post id.', 'duracelltomi-google-tag-manager' ),
'phase' => GTM4WP_PHASE_STABLE,
),
GTM4WP_OPTION_INCLUDE_POSTFORMAT => array(
GTM4WP_OPTION_INCLUDE_POSTFORMAT => array(
'label' => esc_html__( 'Post Format', 'duracelltomi-google-tag-manager' ),
'description' => esc_html__( 'Check this option to include the post format.', 'duracelltomi-google-tag-manager' ),
'phase' => GTM4WP_PHASE_STABLE,
),
GTM4WP_OPTION_INCLUDE_POSTTERMLIST => array(
GTM4WP_OPTION_INCLUDE_POSTTERMLIST => array(
'label' => esc_html__( 'Post Terms', 'duracelltomi-google-tag-manager' ),
'description' => esc_html__( 'Check this option to include taxonomy values associated with a given post.', 'duracelltomi-google-tag-manager' ),
'phase' => GTM4WP_PHASE_STABLE,
),
GTM4WP_OPTION_INCLUDE_SEARCHDATA => array(
GTM4WP_OPTION_INCLUDE_SEARCHDATA => array(
'label' => esc_html__( 'Search data', 'duracelltomi-google-tag-manager' ),
'description' => esc_html__( 'Check this option to include the search term, referring page URL and number of results on the search page.', 'duracelltomi-google-tag-manager' ),
'phase' => GTM4WP_PHASE_STABLE,
),
GTM4WP_OPTION_INCLUDE_LOGGEDIN => array(
GTM4WP_OPTION_INCLUDE_LOGGEDIN => array(
'label' => esc_html__( 'Logged in status', 'duracelltomi-google-tag-manager' ),
'description' => esc_html__( 'Check this option to include whether there is a logged in user on your website.', 'duracelltomi-google-tag-manager' ),
'phase' => GTM4WP_PHASE_STABLE,
),
GTM4WP_OPTION_INCLUDE_USERROLE => array(
GTM4WP_OPTION_INCLUDE_USERROLE => array(
'label' => esc_html__( 'Logged in user role', 'duracelltomi-google-tag-manager' ),
'description' => esc_html__( 'Check this option to include the role of the logged in user.', 'duracelltomi-google-tag-manager' ),
'phase' => GTM4WP_PHASE_STABLE,
),
GTM4WP_OPTION_INCLUDE_USERID => array(
GTM4WP_OPTION_INCLUDE_USERID => array(
'label' => esc_html__( 'Logged in user ID', 'duracelltomi-google-tag-manager' ),
'description' => esc_html__( 'Check this option to include the ID of the logged in user.', 'duracelltomi-google-tag-manager' ),
'phase' => GTM4WP_PHASE_STABLE,
),
GTM4WP_OPTION_INCLUDE_USERNAME => array(
GTM4WP_OPTION_INCLUDE_USERNAME => array(
'label' => esc_html__( 'Logged in user name', 'duracelltomi-google-tag-manager' ),
'description' => esc_html__( 'Check this option to include the username of the logged in user.', 'duracelltomi-google-tag-manager' ),
'phase' => GTM4WP_PHASE_STABLE,
),
GTM4WP_OPTION_INCLUDE_USEREMAIL => array(
GTM4WP_OPTION_INCLUDE_USEREMAIL => array(
'label' => esc_html__( 'Logged in user email', 'duracelltomi-google-tag-manager' ),
'description' => esc_html__( 'Check this option to include the email address of the logged in user.', 'duracelltomi-google-tag-manager' ),
'phase' => GTM4WP_PHASE_STABLE,
),
GTM4WP_OPTION_INCLUDE_USERREGDATE => array(
GTM4WP_OPTION_INCLUDE_USERREGDATE => array(
'label' => esc_html__( 'Logged in user creation date', 'duracelltomi-google-tag-manager' ),
'description' => esc_html__( 'Check this option to include the date of creation (registration) of the logged in user.', 'duracelltomi-google-tag-manager' ),
'phase' => GTM4WP_PHASE_STABLE,
),
GTM4WP_OPTION_INCLUDE_VISITOR_IP => array(
GTM4WP_OPTION_INCLUDE_VISITOR_IP => array(
'label' => esc_html__( 'Visitor IP', 'duracelltomi-google-tag-manager' ),
'description' => esc_html__( 'Check this option to include the IP address of the visitor. You might use this to filter internal traffic inside your GTM container. Please be aware that per GDPR its not allowed to transmit this full IP address to Google Analytics or to any other measurement system without explicit consent from the visitor.', 'duracelltomi-google-tag-manager' ),
'phase' => GTM4WP_PHASE_STABLE,
),
GTM4WP_OPTION_INCLUDE_BROWSERDATA => array(
GTM4WP_OPTION_INCLUDE_VISITOR_IP_HEADER => array(
'label' => esc_html__( 'Visitor IP - Read from custom header.', 'duracelltomi-google-tag-manager' ),
'description' => esc_html__( 'By default, the plugin will check the so called REMOTE_ADDR system variable for IP addresses. In some cases, this might not include the correct address. You may specify a custom header to read the IP address from.', 'duracelltomi-google-tag-manager' ),
'phase' => GTM4WP_PHASE_STABLE,
),
GTM4WP_OPTION_INCLUDE_BROWSERDATA => array(
'label' => esc_html__( 'Browser data *', 'duracelltomi-google-tag-manager' ),
'description' => esc_html__( 'Check this option to include the name, version and engine data of the browser the visitor uses.', 'duracelltomi-google-tag-manager' ),
),
GTM4WP_OPTION_INCLUDE_OSDATA => array(
GTM4WP_OPTION_INCLUDE_OSDATA => array(
'label' => esc_html__( 'OS data *', 'duracelltomi-google-tag-manager' ),
'description' => esc_html__( 'Check this option to include the name and version of the operating system the visitor uses.', 'duracelltomi-google-tag-manager' ),
),
GTM4WP_OPTION_INCLUDE_DEVICEDATA => array(
GTM4WP_OPTION_INCLUDE_DEVICEDATA => array(
'label' => esc_html__( 'Device data *', 'duracelltomi-google-tag-manager' ),
'description' => esc_html__( 'Check this option to include the type of device the user is currently using (desktop, tablet or mobile) including manufacturer and model data.', 'duracelltomi-google-tag-manager' ),
),
GTM4WP_OPTION_INCLUDE_MISCGEO => array(
GTM4WP_OPTION_INCLUDE_MISCGEO => array(
'label' => esc_html__( 'Geo data', 'duracelltomi-google-tag-manager' ),
'description' => esc_html__( 'Add geo data (latitude, longitude, country, city, etc) of the current visitor (provided by ipstack.com)', 'duracelltomi-google-tag-manager' ),
'phase' => GTM4WP_PHASE_EXPERIMENTAL,
),
GTM4WP_OPTION_INCLUDE_MISCGEOAPI => array(
GTM4WP_OPTION_INCLUDE_MISCGEOAPI => array(
'label' => esc_html__( 'IPStack.com API key', 'duracelltomi-google-tag-manager' ),
'description' => sprintf(
// translators: 1: the anchor eleemnt pointing to ipstack.com to register for API keys. 2: closing anchor tag.
Expand All @@ -134,12 +139,12 @@
),
'phase' => GTM4WP_PHASE_EXPERIMENTAL,
),
GTM4WP_OPTION_INCLUDE_MISCGEOCF => array(
GTM4WP_OPTION_INCLUDE_MISCGEOCF => array(
'label' => esc_html__( 'Cloudflare country code', 'duracelltomi-google-tag-manager' ),
'description' => esc_html__( 'Add the country code of the user provided by Cloudflare (if Cloudflare is used with your site)', 'duracelltomi-google-tag-manager' ),
'phase' => GTM4WP_PHASE_EXPERIMENTAL,
),
GTM4WP_OPTION_INCLUDE_WEATHER => array(
GTM4WP_OPTION_INCLUDE_WEATHER => array(
'label' => esc_html__( 'Weather data', 'duracelltomi-google-tag-manager' ),
'description' => sprintf(
gtm4wp_safe_admin_html(
Expand All @@ -162,12 +167,12 @@
),
'phase' => GTM4WP_PHASE_EXPERIMENTAL,
),
GTM4WP_OPTION_INCLUDE_WEATHERUNITS => array(
GTM4WP_OPTION_INCLUDE_WEATHERUNITS => array(
'label' => esc_html__( 'Weather data units', 'duracelltomi-google-tag-manager' ),
'description' => esc_html__( 'Select which temperature units you would like to use.', 'duracelltomi-google-tag-manager' ),
'phase' => GTM4WP_PHASE_EXPERIMENTAL,
),
GTM4WP_OPTION_INCLUDE_WEATHEROWMAPI => array(
GTM4WP_OPTION_INCLUDE_WEATHEROWMAPI => array(
'label' => esc_html__( 'OpenWeatherMap API key', 'duracelltomi-google-tag-manager' ),
'description' => sprintf(
// translators: 1: opening anchor tag linking to Open Weather Map's pricing page. 2: closing anchor tag.
Expand All @@ -180,12 +185,12 @@
),
'phase' => GTM4WP_PHASE_EXPERIMENTAL,
),
GTM4WP_OPTION_INCLUDE_SITEID => array(
GTM4WP_OPTION_INCLUDE_SITEID => array(
'label' => esc_html__( 'Site ID', 'duracelltomi-google-tag-manager' ),
'description' => esc_html__( 'ID of the current site in a WordPress Multisite environment', 'duracelltomi-google-tag-manager' ),
'phase' => GTM4WP_PHASE_STABLE,
),
GTM4WP_OPTION_INCLUDE_SITENAME => array(
GTM4WP_OPTION_INCLUDE_SITENAME => array(
'label' => esc_html__( 'Site name', 'duracelltomi-google-tag-manager' ),
'description' => esc_html__( 'Name of the current site in a WordPress Multisite environment', 'duracelltomi-google-tag-manager' ),
'phase' => GTM4WP_PHASE_STABLE,
Expand Down
13 changes: 12 additions & 1 deletion admin/admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,18 @@ function gtm4wp_sanitize_options( $options ) {
$newoptionvalue = '';
}

if ( 'include-' === substr( $optionname, 0, 8 ) ) {
if ( GTM4WP_OPTION_INCLUDE_VISITOR_IP_HEADER === $optionname ) {
if ( '' !== $newoptionvalue ) {
$custom_header = strtoupper( str_replace( '-', '_', $newoptionvalue ) );
if ( preg_match( '/[A-Z0-9_]+/', $custom_header ) ) {
$output[ $optionname ] = $custom_header;
} else {
$output[ $optionname ] = '';
}
} else {
$output[ $optionname ] = $newoptionvalue;
}
} elseif ( 'include-' === substr( $optionname, 0, 8 ) ) {
// "include" settings.
$output[ $optionname ] = (bool) $newoptionvalue;

Expand Down
2 changes: 2 additions & 0 deletions common/readoptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
define( 'GTM4WP_OPTION_INCLUDE_USERREGDATE', 'include-userregdate' );
define( 'GTM4WP_OPTION_INCLUDE_USERNAME', 'include-username' );
define( 'GTM4WP_OPTION_INCLUDE_VISITOR_IP', 'include-visitor-ip' );
define( 'GTM4WP_OPTION_INCLUDE_VISITOR_IP_HEADER', 'include-visitor-ip-header' );
define( 'GTM4WP_OPTION_INCLUDE_POSTTYPE', 'include-posttype' );
define( 'GTM4WP_OPTION_INCLUDE_CATEGORIES', 'include-categories' );
define( 'GTM4WP_OPTION_INCLUDE_TAGS', 'include-tags' );
Expand Down Expand Up @@ -133,6 +134,7 @@
GTM4WP_OPTION_INCLUDE_USERREGDATE => false,
GTM4WP_OPTION_INCLUDE_USERNAME => false,
GTM4WP_OPTION_INCLUDE_VISITOR_IP => false,
GTM4WP_OPTION_INCLUDE_VISITOR_IP_HEADER => '',
GTM4WP_OPTION_INCLUDE_POSTTYPE => true,
GTM4WP_OPTION_INCLUDE_CATEGORIES => true,
GTM4WP_OPTION_INCLUDE_TAGS => true,
Expand Down
2 changes: 1 addition & 1 deletion js/admin-subtabs.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ var adminsubtabs = {
},
"visitor": {
tabtext: gtm4wp.visitortabtitle,
numitems: 7
numitems: 8
},
"whichbrowser": {
tabtext: gtm4wp.browsertabtitle,
Expand Down
56 changes: 32 additions & 24 deletions public/frontend.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,32 +87,40 @@ function gtm4wp_amp_running() {
}

/**
* Original copyright:
* By Grant Burton @ BURTONTECH.COM
* Returns the IP address of the user either from REMOVE_ADDR server variable or a custom HTTP header specified in the parameter of the funcion.
*
* Code improved by Thomas Geiger
* Originally this function iterated through many commonly used custom headers however since they are unprotected, one could send a bogus
* IP address for tracking purposes. Therefore function has been changed to only use the safe server variable and a user option to allow one
* specific custom HTTP header.
*
* The function will translate the given custom header to a PHP server varibale, no need to directly input the PHP form of the header.
* If custom the header is not found, the function will fall back to REMOTE_ADDR.
*
* @param string $use_custom_header A custom HTTP header to use instead of the default REMOTE_ADDR server variable.
* @return string IP address of the user if found, empty string otherwise.
*/
function gtm4wp_get_user_ip() {
if ( ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
foreach ( explode( ',', sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) ) as $ip ) {
if ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) !== false ) {
return $ip;
}
function gtm4wp_get_user_ip( $use_custom_header = '' ) {
$custom_header = '';

if ( '' !== $use_custom_header ) {
$custom_header = strtoupper( str_replace( '-', '_', $use_custom_header ) );
if ( preg_match( '/[A-Z0-9_]+/', $custom_header ) ) {
$custom_header = 'HTTP_' . $custom_header;
} else {
$custom_header = '';
}
}

$possible_ip_variables = array(
'HTTP_CLIENT_IP',
'HTTP_X_FORWARDED',
'HTTP_X_CLUSTER_CLIENT_IP',
'HTTP_FORWARDED_FOR',
'HTTP_FORWARDED',
'REMOTE_ADDR',
);

foreach ( $possible_ip_variables as $one_ip_variable ) {
if ( ! empty( $_SERVER[ $one_ip_variable ] ) ) {
$ip = filter_var( wp_unslash( $_SERVER[ $one_ip_variable ] ), FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE );
if ( ( '' !== $custom_header ) && ( ! empty( $_SERVER[ $custom_header ] ) ) ) {
if ( 'HTTP_X_FORWARDED_FOR' === $custom_header ) {
// X-Forwarded-For is a comma+space separated list of IPs.
foreach ( explode( ',', sanitize_text_field( wp_unslash( $_SERVER[ $custom_header ] ) ) ) as $ip ) {
if ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) !== false ) {
return $ip;
}
}
} else {
$ip = filter_var( wp_unslash( $_SERVER[ $custom_header ] ), FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE );
if ( false !== $ip ) {
return $ip;
}
Expand Down Expand Up @@ -199,7 +207,7 @@ function gtm4wp_add_basic_datalayer_data( $data_layer ) {
}

if ( $gtm4wp_options[ GTM4WP_OPTION_INCLUDE_VISITOR_IP ] ) {
$data_layer['visitorIP'] = esc_js( gtm4wp_get_user_ip() );
$data_layer['visitorIP'] = esc_js( gtm4wp_get_user_ip( $gtm4wp_options[ GTM4WP_OPTION_INCLUDE_VISITOR_IP_HEADER ] ) );
}

if ( $gtm4wp_options[ GTM4WP_OPTION_INCLUDE_POSTTITLE ] ) {
Expand Down Expand Up @@ -509,7 +517,7 @@ function( $class ) {
$data_layer['geoLongitude'] = esc_js( __( '(no geo data available)', 'duracelltomi-google-tag-manager' ) );
}

$client_ip = gtm4wp_get_user_ip();
$client_ip = gtm4wp_get_user_ip( $gtm4wp_options[ GTM4WP_OPTION_INCLUDE_VISITOR_IP_HEADER ] );

if ( '' !== $client_ip ) {
if ( $gtm4wp_options[ GTM4WP_OPTION_INCLUDE_WEATHER ] ) {
Expand Down Expand Up @@ -578,7 +586,7 @@ function gtm4wp_wp_loaded() {
( $gtm4wp_options[ GTM4WP_OPTION_INCLUDE_WEATHER ] || $gtm4wp_options[ GTM4WP_OPTION_INCLUDE_MISCGEO ] )
&& ( ! $blocking_cookie )
) {
$client_ip = gtm4wp_get_user_ip();
$client_ip = gtm4wp_get_user_ip( $gtm4wp_options[ GTM4WP_OPTION_INCLUDE_VISITOR_IP_HEADER ] );
$geodata = get_transient( 'gtm4wp-geodata-' . esc_attr( $client_ip ) );

if ( false === $geodata ) {
Expand Down
1 change: 1 addition & 0 deletions readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ please update the plugin on a test version of your website before updating your
* Added: stockstatus key into the product array of every ecommerce action. Returns the value of WP_Product->get_stock_status(). Thanks [hans2103](https://github.com/hans2103).
* Added: integration with WebToffee GDPR Cookie Consent plugin. GTM4WP can not fire a GTM event when user consent changes or when a previously stored consent has been loaded.
* Fixed: add_payment_info and add_shipping_info events were not fired during checkout submit when not fired before on the page.
* Fixed: GTM4WP will only look for the user's IP address in the REMOTE_ADDR server variable. You may enter a custom HTTP header instead in plugin settings.

= 1.19.1 =

Expand Down

0 comments on commit 390b220

Please sign in to comment.