Disclosure Statement: This site contains affiliate links, which means that I may receive a commission if you make a purchase using these links. As an eBay Partner, I earn from qualifying purchases.
How To Close Or ByPass Content Security Policy(CSP)
How To Close Or ByPass Content Security Policy(CSP)
How To Close Or ByPass Content Security Policy(CSP)?
I have tried these step ..
1, in event :onResourceResponse onResourceLoadComplete try to Modify the response with new map...because csp response to browser by headers...but it seemed not work.
2,
GlobalCEFApp.DisableWebSecurity := True;
GlobalCEFApp.DisableSafeBrowsing := True;
not work.....
3、 in firefox,we can set the csp option to false in about:config tab ,but cef seem have no choose on it .
Any other solution? Thanks very much.
I have tried these step ..
1, in event :onResourceResponse onResourceLoadComplete try to Modify the response with new map...because csp response to browser by headers...but it seemed not work.
2,
GlobalCEFApp.DisableWebSecurity := True;
GlobalCEFApp.DisableSafeBrowsing := True;
not work.....
3、 in firefox,we can set the csp option to false in about:config tab ,but cef seem have no choose on it .
Any other solution? Thanks very much.
- salvadordf
- Posts: 4374
- Joined: Thu Feb 02, 2017 12:24 pm
- Location: Spain
- Contact:
Re: How To Close Or ByPass Content Security Policy(CSP)
I've never done that but this web page seems to show a way to disable it removing headers :
https://stackoverflow.com/questions/379 ... f-cefsharp
https://stackoverflow.com/questions/379 ... f-cefsharp
Re: How To Close Or ByPass Content Security Policy(CSP)
yes, disable it by removing headers is a good idea , which is also the first one I'v tried, using event onResourceResponse onResourceLoadComplete, I want to remove or replace response header with the function :
procedure SetResponseHeaders(response: ICefResponse;
toAddHeaders: TDictionary<String, String>);
var
map: ICefStringMultimap;
ds: TDictionary<String, String>.TPairEnumerator;
begin
map := TCefStringMultimapOwn.Create;
response.GetHeaderMap(map);
ds := toAddHeaders.GetEnumerator;
while ds.MoveNext do
map.Append(ds.Current.Key, ds.Current.value);
// map.Append('User-Agent', 'CEF4Delphi Browser');
// map.Append('Accept-Language', 'en;q=0.8');
response.SetHeaderMap(map);
end;
but nothing changed after this step. maybe there is someting wrong in my codes?, could you share me some example about this aspect?
procedure SetResponseHeaders(response: ICefResponse;
toAddHeaders: TDictionary<String, String>);
var
map: ICefStringMultimap;
ds: TDictionary<String, String>.TPairEnumerator;
begin
map := TCefStringMultimapOwn.Create;
response.GetHeaderMap(map);
ds := toAddHeaders.GetEnumerator;
while ds.MoveNext do
map.Append(ds.Current.Key, ds.Current.value);
// map.Append('User-Agent', 'CEF4Delphi Browser');
// map.Append('Accept-Language', 'en;q=0.8');
response.SetHeaderMap(map);
end;
but nothing changed after this step. maybe there is someting wrong in my codes?, could you share me some example about this aspect?
- salvadordf
- Posts: 4374
- Joined: Thu Feb 02, 2017 12:24 pm
- Location: Spain
- Contact:
Re: How To Close Or ByPass Content Security Policy(CSP)
I just checked the code comments in the CEF code and it's not possible to change the response headers in the TChromium.OnResourceResponse, TChromium.OnResourceLoadComplete and TChromium.OnGetResourceResponseFilter events.
However, this old comment from the CEF maintainer states that it's possible to get the a ICefResourceHandler in the TChromium.OnGetResourceHandler event :
http://magpcss.org/ceforum/viewtopic.ph ... 794#p17348
With a ICefResourceHandler you can execute the request/return the response contents yourself using CefURLRequest.
I've never done this but this web page shows how to do that :
https://stackoverflow.com/questions/304 ... r-response
However, this old comment from the CEF maintainer states that it's possible to get the a ICefResourceHandler in the TChromium.OnGetResourceHandler event :
http://magpcss.org/ceforum/viewtopic.ph ... 794#p17348
With a ICefResourceHandler you can execute the request/return the response contents yourself using CefURLRequest.
I've never done this but this web page shows how to do that :
https://stackoverflow.com/questions/304 ... r-response
Re: How To Close Or ByPass Content Security Policy(CSP)
Has anyone implemented something like this with CEF4Delphi? I'm trying to implement a response header filter with a similar custom resource handler and it's sort of working but cookies aren't being set or passed on with the requests.salvadordf wrote: ↑Thu Apr 05, 2018 6:37 pm With a ICefResourceHandler you can execute the request/return the response contents yourself using CefURLRequest.
I've never done this but this web page shows how to do that :
https://stackoverflow.com/questions/304 ... r-response
What I'm testing at the moment is the CRBrowser demo and I'm using
Code: Select all
TCefUrlRequestRef.New(Request, TCustomCefUrlrequestClient.Create(Self), nil);
The request context is nil so the global context should be used but I'm not sure if there should be the global cookie manager somewhere. CanSet/GetCookie is set to True but should I use that to set the cookie manually to the manager?
- salvadordf
- Posts: 4374
- Joined: Thu Feb 02, 2017 12:24 pm
- Location: Spain
- Contact:
Re: How To Close Or ByPass Content Security Policy(CSP)
I recently added a new demo called URLRequest which uses a new component called TCEFUrlRequestClientComponent.
It should be easier to handle URLRequests with that component and the code from that demo. Read the code comments in that demo.
You need to set some flags in the ICefRequest to use the cookies. Try the UR_FLAG_ALLOW_STORED_CREDENTIALS flag but there are a few more available in the uCEFConstants unit.
These are code comments for the flags :
It should be easier to handle URLRequests with that component and the code from that demo. Read the code comments in that demo.
You need to set some flags in the ICefRequest to use the cookies. Try the UR_FLAG_ALLOW_STORED_CREDENTIALS flag but there are a few more available in the uCEFConstants unit.
These are code comments for the flags :
Code: Select all
///
// Default behavior.
///
UR_FLAG_NONE = 0,
///
// If set the cache will be skipped when handling the request. Setting this
// value is equivalent to specifying the "Cache-Control: no-cache" request
// header. Setting this value in combination with UR_FLAG_ONLY_FROM_CACHE will
// cause the request to fail.
///
UR_FLAG_SKIP_CACHE = 1 << 0,
///
// If set the request will fail if it cannot be served from the cache (or some
// equivalent local store). Setting this value is equivalent to specifying the
// "Cache-Control: only-if-cached" request header. Setting this value in
// combination with UR_FLAG_SKIP_CACHE will cause the request to fail.
///
UR_FLAG_ONLY_FROM_CACHE = 1 << 1,
///
// If set user name, password, and cookies may be sent with the request, and
// cookies may be saved from the response.
///
UR_FLAG_ALLOW_STORED_CREDENTIALS = 1 << 2,
///
// If set upload progress events will be generated when a request has a body.
///
UR_FLAG_REPORT_UPLOAD_PROGRESS = 1 << 3,
///
// If set the CefURLRequestClient::OnDownloadData method will not be called.
///
UR_FLAG_NO_DOWNLOAD_DATA = 1 << 4,
///
// If set 5XX redirect errors will be propagated to the observer instead of
// automatically re-tried. This currently only applies for requests
// originated in the browser process.
///
UR_FLAG_NO_RETRY_ON_5XX = 1 << 5,
///
// If set 3XX responses will cause the fetch to halt immediately rather than
// continue through the redirect.
///
UR_FLAG_STOP_ON_REDIRECT = 1 << 6,
Re: How To Close Or ByPass Content Security Policy(CSP)
Whoa, thanks! I was just trying to figure out how to use ICefUrlRequest to get Cef4Delphi to download a file using a POST without the full browser GUI. ...and lo and behold I just saw your reply about your new TCEFUrlRequestClientComponent.
Thanks again,
Bill.
Thanks again,
Bill.
Re: How To Close Or ByPass Content Security Policy(CSP)
I finally had some time to get back to this and thanks to the ClientComponent I got this more or less working now. Using the ClientComponent did make things a bit easier. I think I was missing the UR_FLAG_ALLOW_STORED_CREDENTIALS and I was using a blank scheme in TCustomResourceHandler.Create, using http/https (from the original request) does make a difference.
Here's an example of filtering Response headers with a custom resource handler, this is based on the CRBrowser demo and the stackoverflow discussion mentioned before.
The header filtering in GetResponseHeaders isn't pretty but there doesn't seem to be a way to manipulate them directly. I couldn't figure out how to cancel the request either but not sure if this makes a difference.
Here's an example of filtering Response headers with a custom resource handler, this is based on the CRBrowser demo and the stackoverflow discussion mentioned before.
Code: Select all
// ************************************************************************
// ***************************** CEF4Delphi *******************************
// ************************************************************************
//
// CEF4Delphi is based on DCEF3 which uses CEF3 to embed a chromium-based
// browser in Delphi applications.
//
// The original license of DCEF3 still applies to CEF4Delphi.
//
// For more information about CEF4Delphi visit :
// https://www.briskbard.com/index.php?lang=en&pageid=cef
//
// Copyright © 2018 Salvador Diaz Fau. All rights reserved.
//
// ************************************************************************
// ************ vvvv Original license and comments below vvvv *************
// ************************************************************************
(*
* Delphi Chromium Embedded 3
*
* Usage allowed under the restrictions of the Lesser GNU General Public License
* or alternatively the restrictions of the Mozilla Public License 1.1
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
* the specific language governing rights and limitations under the License.
*
* Unit owner : Henri Gourvest <hgourvest@gmail.com>
* Web site : http://www.progdigy.com
* Repository : http://code.google.com/p/delphichromiumembedded/
* Group : http://groups.google.com/group/delphichromiumembedded
*
* Embarcadero Technologies, Inc is not permitted to use or redistribute
* this source code without explicit permission.
*
*)
unit uCustomResourceHandler;
{$I cef.inc}
interface
uses
{$IFDEF DELPHI16_UP}
System.Classes, WinApi.Windows, System.SysUtils, dialogs,
{$ELSE}
Classes, Windows, SysUtils,
{$ENDIF}
uCEFInterfaces, uCEFTypes, uCEFResourceHandler, uCEFStringMultimap, uCEFUrlrequestClient,
uCEFUrlRequest, uCEFUrlRequestClientComponent, uCEFRequest;
type
TCustomResourceHandler = class(TCefResourceHandlerOwn)
private
FOffset: NativeUInt;
FStream: TMemoryStream;
FCallback: ICefCallback;
FResponse: ICefResponse;
FClient: TCEFUrlRequestClientComponent;
FRequest: ICefRequest;
procedure GetResponseHeaders(const response: ICefResponse; out responseLength: Int64; out redirectUrl: ustring); override;
function ProcessRequest(const Request: ICefRequest; const Callback: ICefCallback): Boolean; override;
procedure OnRequestComplete(Sender: TObject; const request: ICefUrlRequest);
procedure OnCreateURLRequest(Sender: TObject);
procedure OnDownloadData(Sender: TObject; const request: ICefUrlRequest; data: Pointer; dataLength: NativeUInt);
function ReadResponse(const DataOut: Pointer; BytesToRead: Integer; var BytesRead: Integer; const Callback: ICefCallback): Boolean; override;
procedure Cancel;
public
constructor Create(const browser: ICefBrowser; const frame: ICefFrame; const schemeName: ustring; const request: ICefRequest); reintroduce;
destructor Destroy; override;
procedure CompleteRequest(const Request: ICefUrlRequest); virtual;
end;
implementation
uses uCEFConstants;
procedure TCustomResourceHandler.Cancel;
begin
end;
procedure TCustomResourceHandler.CompleteRequest(const Request: ICefUrlRequest);
begin
FStream.Position := 0;
FResponse := Request.GetResponse;
if Assigned(FCallback) then
FCallback.Cont;
end;
constructor TCustomResourceHandler.Create(const browser : ICefBrowser;
const frame : ICefFrame;
const schemeName : ustring;
const request : ICefRequest);
begin
inherited Create(browser, frame, schemeName, request);
FStream := TMemoryStream.Create;
FClient := TCEFUrlRequestClientComponent.Create(nil);
FClient.OnRequestComplete := Self.OnRequestComplete;
FClient.OnCreateURLRequest := Self.OnCreateURLRequest;
FClient.OnDownloadData := Self.OnDownloadData;
end;
destructor TCustomResourceHandler.Destroy;
begin
FStream.Destroy;
FClient.Destroy;
inherited Destroy;
end;
procedure TCustomResourceHandler.GetResponseHeaders(const response : ICefResponse;
out responseLength : Int64;
out redirectUrl : ustring);
var
HeaderMapTemp: ICefStringMultimap;
FinalHeaderMap: ICefStringMultiMap;
i: Integer;
begin
ResponseLength := FStream.Size;
Response.Status := FResponse.Status;
Response.StatusText := FResponse.StatusText;
Response.MimeType := FResponse.MimeType;
Response.Error := FResponse.Error;
HeaderMapTemp := TCefStringMultimapOwn.Create;
FinalHeaderMap := TCefStringMultimapOwn.Create;
FResponse.GetHeaderMap(HeaderMapTemp);
if HeaderMapTemp.Size <> 0 then
begin
for i := 0 to HeaderMapTemp.Size do
begin
if (Lowercase(HeaderMapTemp.Key[i]) <> 'x-frame-options') then
FinalHeaderMap.Append(HeaderMapTemp.Key[i], HeaderMapTemp.Value[i]);
end;
end;
Response.SetHeaderMap(FinalHeaderMap);
end;
procedure TCustomResourceHandler.OnCreateURLRequest(Sender: TObject);
begin
TCefUrlRequestRef.New(FRequest, FClient.Client, nil);
end;
procedure TCustomResourceHandler.OnDownloadData(Sender: TObject;
const request: ICefUrlRequest; data: Pointer; dataLength: NativeUInt);
begin
if (data <> nil) and (dataLength > 0) then
FStream.WriteBuffer(data^, dataLength);
end;
procedure TCustomResourceHandler.OnRequestComplete(Sender: TObject;
const request: ICefUrlRequest);
begin
Self.CompleteRequest(request);
end;
function TCustomResourceHandler.ProcessRequest(const Request: ICefRequest;
const Callback: ICefCallback): Boolean;
var
HeaderMapTemp: ICefStringMultimap;
i: Integer;
begin
Result := True;
FOffset := 0;
FCallback := Callback;
FRequest := TCefRequestRef.New;
HeaderMapTemp := TCefStringMultimapOwn.Create;
Request.GetHeaderMap(HeaderMapTemp);
FRequest.SetReferrer(Request.ReferrerUrl, Request.ReferrerPolicy);
FRequest.Assign(Request.Url, Request.Method, Request.PostData, HeaderMapTemp);
FRequest.Flags := UR_FLAG_ALLOW_STORED_CREDENTIALS;
FClient.AddURLRequest;
end;
function TCustomResourceHandler.ReadResponse(const DataOut: Pointer;
BytesToRead: Integer; var BytesRead: Integer;
const Callback: ICefCallback): Boolean;
begin
if FOffset < FStream.Size then
begin
Result := True;
BytesRead := BytesToRead;
Move(Pointer(NativeUInt(FStream.Memory) + FOffset)^, DataOut^, BytesRead);
Inc(FOffset, BytesRead);
end
else
Result := False;
end;
end.
Re: How To Close Or ByPass Content Security Policy(CSP)
430am wrote: ↑Fri Jan 18, 2019 11:50 am I finally had some time to get back to this and thanks to the ClientComponent I got this more or less working now. Using the ClientComponent did make things a bit easier. I think I was missing the UR_FLAG_ALLOW_STORED_CREDENTIALS and I was using a blank scheme in TCustomResourceHandler.Create, using http/https (from the original request) does make a difference.
Here's an example of filtering Response headers with a custom resource handler, this is based on the CRBrowser demo and the stackoverflow discussion mentioned before.The header filtering in GetResponseHeaders isn't pretty but there doesn't seem to be a way to manipulate them directly. I couldn't figure out how to cancel the request either but not sure if this makes a difference.Code: Select all
// ************************************************************************ // ***************************** CEF4Delphi ******************************* // ************************************************************************ // // CEF4Delphi is based on DCEF3 which uses CEF3 to embed a chromium-based // browser in Delphi applications. // // The original license of DCEF3 still applies to CEF4Delphi. // // For more information about CEF4Delphi visit : // https://www.briskbard.com/index.php?lang=en&pageid=cef // // Copyright © 2018 Salvador Diaz Fau. All rights reserved. // // ************************************************************************ // ************ vvvv Original license and comments below vvvv ************* // ************************************************************************ (* * Delphi Chromium Embedded 3 * * Usage allowed under the restrictions of the Lesser GNU General Public License * or alternatively the restrictions of the Mozilla Public License 1.1 * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for * the specific language governing rights and limitations under the License. * * Unit owner : Henri Gourvest <hgourvest@gmail.com> * Web site : http://www.progdigy.com * Repository : http://code.google.com/p/delphichromiumembedded/ * Group : http://groups.google.com/group/delphichromiumembedded * * Embarcadero Technologies, Inc is not permitted to use or redistribute * this source code without explicit permission. * *) unit uCustomResourceHandler; {$I cef.inc} interface uses {$IFDEF DELPHI16_UP} System.Classes, WinApi.Windows, System.SysUtils, dialogs, {$ELSE} Classes, Windows, SysUtils, {$ENDIF} uCEFInterfaces, uCEFTypes, uCEFResourceHandler, uCEFStringMultimap, uCEFUrlrequestClient, uCEFUrlRequest, uCEFUrlRequestClientComponent, uCEFRequest; type TCustomResourceHandler = class(TCefResourceHandlerOwn) private FOffset: NativeUInt; FStream: TMemoryStream; FCallback: ICefCallback; FResponse: ICefResponse; FClient: TCEFUrlRequestClientComponent; FRequest: ICefRequest; procedure GetResponseHeaders(const response: ICefResponse; out responseLength: Int64; out redirectUrl: ustring); override; function ProcessRequest(const Request: ICefRequest; const Callback: ICefCallback): Boolean; override; procedure OnRequestComplete(Sender: TObject; const request: ICefUrlRequest); procedure OnCreateURLRequest(Sender: TObject); procedure OnDownloadData(Sender: TObject; const request: ICefUrlRequest; data: Pointer; dataLength: NativeUInt); function ReadResponse(const DataOut: Pointer; BytesToRead: Integer; var BytesRead: Integer; const Callback: ICefCallback): Boolean; override; procedure Cancel; public constructor Create(const browser: ICefBrowser; const frame: ICefFrame; const schemeName: ustring; const request: ICefRequest); reintroduce; destructor Destroy; override; procedure CompleteRequest(const Request: ICefUrlRequest); virtual; end; implementation uses uCEFConstants; procedure TCustomResourceHandler.Cancel; begin end; procedure TCustomResourceHandler.CompleteRequest(const Request: ICefUrlRequest); begin FStream.Position := 0; FResponse := Request.GetResponse; if Assigned(FCallback) then FCallback.Cont; end; constructor TCustomResourceHandler.Create(const browser : ICefBrowser; const frame : ICefFrame; const schemeName : ustring; const request : ICefRequest); begin inherited Create(browser, frame, schemeName, request); FStream := TMemoryStream.Create; FClient := TCEFUrlRequestClientComponent.Create(nil); FClient.OnRequestComplete := Self.OnRequestComplete; FClient.OnCreateURLRequest := Self.OnCreateURLRequest; FClient.OnDownloadData := Self.OnDownloadData; end; destructor TCustomResourceHandler.Destroy; begin FStream.Destroy; FClient.Destroy; inherited Destroy; end; procedure TCustomResourceHandler.GetResponseHeaders(const response : ICefResponse; out responseLength : Int64; out redirectUrl : ustring); var HeaderMapTemp: ICefStringMultimap; FinalHeaderMap: ICefStringMultiMap; i: Integer; begin ResponseLength := FStream.Size; Response.Status := FResponse.Status; Response.StatusText := FResponse.StatusText; Response.MimeType := FResponse.MimeType; Response.Error := FResponse.Error; HeaderMapTemp := TCefStringMultimapOwn.Create; FinalHeaderMap := TCefStringMultimapOwn.Create; FResponse.GetHeaderMap(HeaderMapTemp); if HeaderMapTemp.Size <> 0 then begin for i := 0 to HeaderMapTemp.Size do begin if (Lowercase(HeaderMapTemp.Key[i]) <> 'x-frame-options') then FinalHeaderMap.Append(HeaderMapTemp.Key[i], HeaderMapTemp.Value[i]); end; end; Response.SetHeaderMap(FinalHeaderMap); end; procedure TCustomResourceHandler.OnCreateURLRequest(Sender: TObject); begin TCefUrlRequestRef.New(FRequest, FClient.Client, nil); end; procedure TCustomResourceHandler.OnDownloadData(Sender: TObject; const request: ICefUrlRequest; data: Pointer; dataLength: NativeUInt); begin if (data <> nil) and (dataLength > 0) then FStream.WriteBuffer(data^, dataLength); end; procedure TCustomResourceHandler.OnRequestComplete(Sender: TObject; const request: ICefUrlRequest); begin Self.CompleteRequest(request); end; function TCustomResourceHandler.ProcessRequest(const Request: ICefRequest; const Callback: ICefCallback): Boolean; var HeaderMapTemp: ICefStringMultimap; i: Integer; begin Result := True; FOffset := 0; FCallback := Callback; FRequest := TCefRequestRef.New; HeaderMapTemp := TCefStringMultimapOwn.Create; Request.GetHeaderMap(HeaderMapTemp); FRequest.SetReferrer(Request.ReferrerUrl, Request.ReferrerPolicy); FRequest.Assign(Request.Url, Request.Method, Request.PostData, HeaderMapTemp); FRequest.Flags := UR_FLAG_ALLOW_STORED_CREDENTIALS; FClient.AddURLRequest; end; function TCustomResourceHandler.ReadResponse(const DataOut: Pointer; BytesToRead: Integer; var BytesRead: Integer; const Callback: ICefCallback): Boolean; begin if FOffset < FStream.Size then begin Result := True; BytesRead := BytesToRead; Move(Pointer(NativeUInt(FStream.Memory) + FOffset)^, DataOut^, BytesRead); Inc(FOffset, BytesRead); end else Result := False; end; end.
Code: Select all
function TCustomResourceHandler.ReadResponse(const DataOut: Pointer;
BytesToRead: Integer; var BytesRead: Integer;
const Callback: ICefCallback): Boolean;
begin
if FOffset < FStream.Size then
begin
Result := True;
BytesRead := BytesToRead;
Move(Pointer(NativeUInt(FStream.Memory) + FOffset)^, DataOut^, BytesRead);
Inc(FOffset, BytesRead);
end
else
Result := False;
end;
Code: Select all
if FStream.Size-FOffset<BytesToRead then
BytesRead:=FStream.Size-FOffset else
BytesRead := BytesToRead;
Re: How To Close Or ByPass Content Security Policy(CSP)
Thank you for the solution
The only thing I would change is ReadResponse function.
I think it will be better:
The only thing I would change is ReadResponse function.
I think it will be better:
Code: Select all
function TCustomResourceHandler.ReadResponse(const DataOut: Pointer;
BytesToRead: Integer; var BytesRead: Integer;
const Callback: ICefCallback): Boolean;
begin
Result := False;
BytesRead := 0;
if Assigned(FStream) and (FOffset < FStream.Size) then
begin
BytesRead:=Min(BytesToRead, FStream.Size - FOffset);
Move(Pointer(NativeUInt(FStream.Memory) + FOffset)^, DataOut^, BytesRead);
Inc(FOffset, BytesRead);
Result:=True;
end;
end;