Skip to content

Commit ed249a2

Browse files
cbiesingermibrunin
authored andcommitted
[Backport] Security bug 340895241 (2/2)
Partial manual cherry-pick of patch originally reviewed on https://chromium-review.googlesource.com/c/chromium/src/+/5574105: [FedCM] Also decode the image in IdpNetworkRequestManager This will make it much easier to let Android use the downloaded image instead of re-downloading it. It also reduces code duplication between desktop and Android. I will make the Android change in a later CL to reduce the size of this CL. Bug: 340895241 Change-Id: I0aad63dd22a06af690473e788a25dc719305d94f Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5574105 Commit-Queue: Christian Biesinger <[email protected]> Reviewed-by: Yi Gu <[email protected]> Reviewed-by: Nasko Oskov <[email protected]> Cr-Commit-Position: refs/heads/main@{#1307731} Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/580290 Reviewed-by: Michal Klocek <[email protected]>
1 parent cec06e5 commit ed249a2

File tree

5 files changed

+62
-26
lines changed

5 files changed

+62
-26
lines changed

chromium/content/browser/webid/federated_auth_request_impl.cc

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1597,7 +1597,7 @@ void FederatedAuthRequestImpl::FetchAccountPictures(
15971597
accounts, client_metadata));
15981598
for (const auto& account : accounts) {
15991599
if (account.picture.is_valid()) {
1600-
network_manager_->DownloadUncredentialedUrl(
1600+
network_manager_->DownloadAndDecodeImage(
16011601
account.picture,
16021602
base::BindOnce(&FederatedAuthRequestImpl::OnAccountPictureReceived,
16031603
weak_ptr_factory_.GetWeakPtr(), callback,
@@ -1613,12 +1613,8 @@ void FederatedAuthRequestImpl::FetchAccountPictures(
16131613
void FederatedAuthRequestImpl::OnAccountPictureReceived(
16141614
base::RepeatingClosure cb,
16151615
GURL url,
1616-
std::unique_ptr<std::string> response_body,
1617-
int response_code,
1618-
const std::string& mime_type) {
1619-
if (response_body) {
1620-
downloaded_images_[url] = std::move(response_body);
1621-
}
1616+
const gfx::Image& image) {
1617+
downloaded_images_[url] = image;
16221618
cb.Run();
16231619
}
16241620

@@ -1629,10 +1625,9 @@ void FederatedAuthRequestImpl::OnAllAccountPicturesReceived(
16291625
for (auto& account : accounts) {
16301626
auto it = downloaded_images_.find(account.picture);
16311627
if (it != downloaded_images_.end()) {
1632-
// We do not use std::move here in case multiple accounts use the
1633-
// same picture URL.
1634-
DCHECK(it->second);
1635-
account.picture_data = *it->second;
1628+
// We do not use std::move here in case multiple accounts use the same
1629+
// picture URL, and the underlying gfx::Image data is refcounted anyway.
1630+
account.decoded_picture = it->second;
16361631
}
16371632
}
16381633
downloaded_images_.clear();

chromium/content/browser/webid/federated_auth_request_impl.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929
#include "third_party/blink/public/mojom/webid/federated_auth_request.mojom.h"
3030
#include "url/gurl.h"
3131

32+
namespace gfx {
33+
class Image;
34+
}
35+
3236
namespace content {
3337

3438
class FederatedAuthUserInfoRequest;
@@ -247,9 +251,7 @@ class CONTENT_EXPORT FederatedAuthRequestImpl
247251
const IdpNetworkRequestManager::ClientMetadata& client_metadata);
248252
void OnAccountPictureReceived(base::RepeatingClosure cb,
249253
GURL url,
250-
std::unique_ptr<std::string> response_body,
251-
int response_code,
252-
const std::string& mime_type);
254+
const gfx::Image& image);
253255
void OnAllAccountPicturesReceived(
254256
std::unique_ptr<IdentityProviderInfo> idp_info,
255257
IdpNetworkRequestManager::AccountList accounts,
@@ -373,7 +375,7 @@ class CONTENT_EXPORT FederatedAuthRequestImpl
373375
std::vector<IdentityProviderData> idp_data_for_display_;
374376

375377
// The downloaded image data.
376-
std::map<GURL, std::unique_ptr<std::string>> downloaded_images_;
378+
std::map<GURL, gfx::Image> downloaded_images_;
377379

378380
raw_ptr<FederatedIdentityApiPermissionContextDelegate>
379381
api_permission_delegate_ = nullptr;

chromium/content/browser/webid/idp_network_request_manager.cc

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "net/cookies/site_for_cookies.h"
2525
#include "net/http/http_request_headers.h"
2626
#include "net/http/http_status_code.h"
27+
#include "services/data_decoder/public/cpp/decode_image.h"
2728
#include "services/network/public/cpp/is_potentially_trustworthy.h"
2829
#include "services/network/public/cpp/resource_request.h"
2930
#include "services/network/public/cpp/shared_url_loader_factory.h"
@@ -33,6 +34,7 @@
3334
#include "third_party/blink/public/common/manifest/manifest_icon_selector.h"
3435
#include "third_party/skia/include/core/SkBitmap.h"
3536
#include "ui/gfx/color_utils.h"
37+
#include "ui/gfx/image/image.h"
3638
#include "url/origin.h"
3739

3840
namespace content {
@@ -813,15 +815,17 @@ void IdpNetworkRequestManager::SendLogout(const GURL& logout_url,
813815
maxResponseSizeInKiB * 1024);
814816
}
815817

816-
void IdpNetworkRequestManager::DownloadUncredentialedUrl(
817-
const GURL& url,
818-
DownloadCallback callback) {
818+
void IdpNetworkRequestManager::DownloadAndDecodeImage(const GURL& url,
819+
ImageCallback callback) {
819820
std::unique_ptr<network::ResourceRequest> resource_request =
820821
CreateUncredentialedResourceRequest(url, /*send_origin=*/false);
821822

822-
DownloadUrl(std::move(resource_request),
823-
/*url_encoded_post_data=*/std::nullopt, std::move(callback),
824-
maxResponseSizeInKiB * 1024);
823+
DownloadUrl(
824+
std::move(resource_request),
825+
/*url_encoded_post_data=*/absl::nullopt,
826+
base::BindOnce(&IdpNetworkRequestManager::OnDownloadedImage,
827+
weak_ptr_factory_.GetWeakPtr(), std::move(callback)),
828+
maxResponseSizeInKiB * 1024);
825829
}
826830

827831
void IdpNetworkRequestManager::DownloadJsonAndParse(
@@ -903,6 +907,29 @@ void IdpNetworkRequestManager::FetchClientMetadata(
903907
maxResponseSizeInKiB * 1024);
904908
}
905909

910+
void IdpNetworkRequestManager::OnDownloadedImage(
911+
ImageCallback callback,
912+
std::unique_ptr<std::string> response_body,
913+
int response_code,
914+
const std::string& mime_type) {
915+
if (!response_body || response_code != net::HTTP_OK) {
916+
std::move(callback).Run(gfx::Image());
917+
return;
918+
}
919+
920+
data_decoder::DecodeImageIsolated(
921+
base::as_bytes(base::make_span(*response_body)),
922+
data_decoder::mojom::ImageCodec::kDefault, /*shrink_to_fit=*/false,
923+
data_decoder::kDefaultMaxSizeInBytes, gfx::Size(),
924+
base::BindOnce(&IdpNetworkRequestManager::OnDecodedImage,
925+
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
926+
}
927+
928+
void IdpNetworkRequestManager::OnDecodedImage(ImageCallback callback,
929+
const SkBitmap& decoded_bitmap) {
930+
std::move(callback).Run(gfx::Image::CreateFrom1xBitmap(decoded_bitmap));
931+
}
932+
906933
std::unique_ptr<network::ResourceRequest>
907934
IdpNetworkRequestManager::CreateUncredentialedResourceRequest(
908935
const GURL& target_url,

chromium/content/browser/webid/idp_network_request_manager.h

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121
#include "url/gurl.h"
2222
#include "url/origin.h"
2323

24+
namespace gfx {
25+
class Image;
26+
}
27+
2428
namespace net {
2529
enum class ReferrerPolicy;
2630
}
@@ -170,6 +174,7 @@ class CONTENT_EXPORT IdpNetworkRequestManager {
170174
using TokenRequestCallback =
171175
base::OnceCallback<void(FetchStatus, TokenResult)>;
172176
using ContinueOnCallback = base::OnceCallback<void(FetchStatus, const GURL&)>;
177+
using ImageCallback = base::OnceCallback<void(const gfx::Image&)>;
173178

174179
static std::unique_ptr<IdpNetworkRequestManager> Create(
175180
RenderFrameHostImpl* host);
@@ -230,9 +235,8 @@ class CONTENT_EXPORT IdpNetworkRequestManager {
230235
// Send logout request to a single target.
231236
virtual void SendLogout(const GURL& logout_url, LogoutCallback);
232237

233-
// Download a URL. The request is made uncredentialed.
234-
virtual void DownloadUncredentialedUrl(const GURL& url,
235-
DownloadCallback callback);
238+
// Download and decode an image. The request is made uncredentialed.
239+
virtual void DownloadAndDecodeImage(const GURL& url, ImageCallback callback);
236240

237241
private:
238242
// Starts download request using `url_loader`. Calls `parse_json_callback`
@@ -255,6 +259,13 @@ class CONTENT_EXPORT IdpNetworkRequestManager {
255259
DownloadCallback callback,
256260
std::unique_ptr<std::string> response_body);
257261

262+
void OnDownloadedImage(ImageCallback callback,
263+
std::unique_ptr<std::string> response_body,
264+
int response_code,
265+
const std::string& mime_type);
266+
267+
void OnDecodedImage(ImageCallback callback, const SkBitmap& decoded_bitmap);
268+
258269
std::unique_ptr<network::ResourceRequest> CreateUncredentialedResourceRequest(
259270
const GURL& target_url,
260271
bool send_origin,

chromium/content/public/browser/identity_request_account.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "content/common/content_export.h"
1212
#include "third_party/abseil-cpp/absl/types/optional.h"
1313
#include "third_party/skia/include/core/SkColor.h"
14+
#include "ui/gfx/image/image.h"
1415
#include "url/gurl.h"
1516

1617
namespace content {
@@ -57,8 +58,8 @@ struct CONTENT_EXPORT IdentityRequestAccount {
5758
std::string name;
5859
std::string given_name;
5960
GURL picture;
60-
// This will be an empty string if fetching failed.
61-
std::string picture_data;
61+
// This will be an empty image if fetching failed.
62+
gfx::Image decoded_picture;
6263

6364
std::vector<std::string> login_hints;
6465
std::vector<std::string> hosted_domains;

0 commit comments

Comments
 (0)