PluginProbe
wpForo Forum / 3.2.1
wpForo Forum v3.2.1
3.2.1 3.2.0 3.1.7 3.1.6 3.1.5 3.1.4 3.1.2 3.1.1 3.1.0 3.0.9 3.0.8 3.0.7 trunk 1.0.0 1.0.1 1.0.2 1.1.0 1.1.1 1.1.2 1.2.0 1.3.0 1.3.1 1.4.0 1.4.1 1.4.10 All 141 releases
← All changes | classes/Members.php +19 -11 3.1.2 → 3.2.1 View file →
@@ -710,8 +710,17 @@
710 710
711 711 //Define $user
712 712 $user = $data[ $form ];
713 713
714 + // SECURITY: Strip admin-only profile fields from form input unless
715 + // user has edit members permission. Prevents mass assignment attacks
716 + // where users manipulate status, reputation, or email confirmation.
717 + if( ! WPF()->usergroup->can( 'em' ) ) {
718 + unset( $user['custom_points'] );
719 + unset( $user['status'] );
720 + unset( $user['is_email_confirmed'] );
721 + }
722 +
714 723 //Define $userid
715 724 $userid = intval( $data[ $form ]['userid'] );
716 725
717 726 //Check profile editor permissions
@@ -892,8 +901,10 @@
892 901 $this->upload_avatar( $userid );
893 902 }
894 903
895 904 //Update Custom Fields
905 + // $custom_fields is still the raw $_POST['data']. The same values were merged into $user, where validate() has since dropped every field the current user may not edit and sanitize() has cleaned the rest, so read them back from $user: a key that is still there is one this user was allowed to submit, and its value is the sanitized one.
906 + $custom_fields = array_intersect_key( $user, $custom_fields );
896 907 if( ! empty( $custom_fields ) && ( in_array( 'full', $type ) || in_array( 'custom_fields', $type ) ) ) {
897 908 $result_fields = $this->update_custom_fields( $userid, $custom_fields, false );
898 909 }
899 910
@@ -1657,16 +1668,17 @@
1657 1668 } else {
1658 1669 $wheres[] = "`" . esc_sql( $field ) . "` LIKE '%" . esc_sql( $needle ) . "%'";
1659 1670 }
1660 1671 } else {
1661 - $needle = preg_quote( preg_quote( $needle ) );
1672 + // Local var: $needle must stay raw for the remaining fields of this loop
1673 + $n = wpforo_json_regexp_needle( $needle );
1662 1674 if( in_array( $f['type'], [ 'text', 'search', 'textarea' ], true ) ) {
1663 1675 $wheres[] = "`fields` REGEXP '[{,]\"" . $field . "\":(\\\[[^\\\[]*)?\"[^\"]*" . esc_sql(
1664 - $needle
1676 + $n
1665 1677 ) . "[^\"]*\"'";
1666 1678 } else {
1667 1679 $wheres[] = "`fields` REGEXP '[{,]\"" . $field . "\":(\\\[[^\\\[]*)?\"" . esc_sql(
1668 - $needle
1680 + $n
1669 1681 ) . "\"'";
1670 1682 }
1671 1683 }
1672 1684 }
@@ -1709,31 +1721,27 @@
1709 1721 }
1710 1722 } else {
1711 1723 if( in_array( $f['type'], [ 'text', 'search', 'textarea' ], true ) ) {
1712 1724 if( is_scalar( $needle ) ) {
1713 - $needle = preg_quote( preg_quote( wpforo_encode( $needle ) ) );
1714 1725 $wheres[] = "`fields` REGEXP '[{,]\"" . $field . "\":(\\\[[^\\\[]*)?\"[^\"]*" . esc_sql(
1715 - $needle
1726 + wpforo_json_regexp_needle( wpforo_encode( $needle ) )
1716 1727 ) . "[^\"]*\"'";
1717 1728 } elseif( is_array( $needle ) ) {
1718 1729 foreach( $needle as $n ) {
1719 - $n = preg_quote( preg_quote( wpforo_encode( $n ) ) );
1720 1730 $wheres[] = "`fields` REGEXP '[{,]\"" . $field . "\":(\\\[[^\\\[]*)?\"[^\"]*" . esc_sql(
1721 - $n
1731 + wpforo_json_regexp_needle( wpforo_encode( $n ) )
1722 1732 ) . "[^\"]*\"'";
1723 1733 }
1724 1734 }
1725 1735 } else {
1726 1736 if( is_scalar( $needle ) ) {
1727 - $needle = preg_quote( preg_quote( wpforo_encode( $needle ) ) );
1728 1737 $wheres[] = "`fields` REGEXP '[{,]\"" . $field . "\":(\\\[[^\\\[]*)?\"" . esc_sql(
1729 - $needle
1738 + wpforo_json_regexp_needle( wpforo_encode( $needle ) )
1730 1739 ) . "\"'";
1731 1740 } elseif( is_array( $needle ) ) {
1732 1741 foreach( $needle as $n ) {
1733 - $n = preg_quote( preg_quote( wpforo_encode( $n ) ) );
1734 1742 $wheres[] = "`fields` REGEXP '[{,]\"" . $field . "\":(\\\[[^\\\[]*)?\"" . esc_sql(
1735 - $n
1743 + wpforo_json_regexp_needle( wpforo_encode( $n ) )
1736 1744 ) . "\"'";
1737 1745 }
1738 1746 }
1739 1747 }