Add additional checks around link preview domains.
We never make requests to non-whitelisted domains, but there were situations where some links would redirect to non-whitelisted domains, which would hit a final failsafe that resulted in a crash. To prevent this, we detect bad redirects earlier and fail more gracefully. Fixes #8796pull/9/head
parent
6c44437c6f
commit
59f362495a
@ -0,0 +1,58 @@
|
||||
package org.thoughtcrime.securesms.net;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import org.thoughtcrime.securesms.linkpreview.LinkPreviewUtil;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.Interceptor;
|
||||
import okhttp3.Response;
|
||||
|
||||
/**
|
||||
* Interceptor to do extra safety checks on requests through the {@link ContentProxySelector}
|
||||
* to prevent non-whitelisted requests from getting to it. In particular, this guards against
|
||||
* requests redirecting to non-whitelisted domains.
|
||||
*
|
||||
* Note that because of the way interceptors are ordered, OkHttp will hit the proxy with the
|
||||
* bad-redirected-domain before we can intercept the request, so we have to "look ahead" by
|
||||
* detecting a redirected response on the first pass.
|
||||
*/
|
||||
public class ContentProxySafetyInterceptor implements Interceptor {
|
||||
|
||||
private static final String TAG = Log.tag(ContentProxySafetyInterceptor.class);
|
||||
|
||||
@Override
|
||||
public @NonNull Response intercept(@NonNull Chain chain) throws IOException {
|
||||
if (isWhitelisted(chain.request().url())) {
|
||||
Response response = chain.proceed(chain.request());
|
||||
|
||||
if (response.isRedirect()) {
|
||||
if (isWhitelisted(response.header("Location"))) {
|
||||
return response;
|
||||
} else {
|
||||
Log.w(TAG, "Tried to redirect to a non-whitelisted domain!");
|
||||
chain.call().cancel();
|
||||
throw new IOException("Tried to redirect to a non-whitelisted domain!");
|
||||
}
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
} else {
|
||||
Log.w(TAG, "Request was for a non-whitelisted domain!");
|
||||
chain.call().cancel();
|
||||
throw new IOException("Request was for a non-whitelisted domain!");
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isWhitelisted(@NonNull HttpUrl url) {
|
||||
return isWhitelisted(url.toString());
|
||||
}
|
||||
|
||||
private static boolean isWhitelisted(@Nullable String url) {
|
||||
return LinkPreviewUtil.isWhitelistedLinkUrl(url) || LinkPreviewUtil.isWhitelistedMediaUrl(url);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue