How to deal with overestimation of small values and underestimation of high values in XGBoost?
I dont think its necessarily related to the type of algorithm performing the regression(XGBoost here) - but to inherent nature of regression algorithms.
Many loss function are aimed to reduce distance between $y$ and $\hat{y}$.
That can lead to model predictions distribution being tighter around $y$'s mean.

Couple of things I would check to verify this:
1) Compare distribution of real $y$ and predicted $\hat{y}$.
2) Verify this error pattern on others regression model.  

Things I would try to improve results:
1) over sample low/high y values in training set.
2) Adjust loss function so errors on low/high y values will have more weight.
3) Look for features that emphasize low/high y values and engineer them better.