0

Improve print preview checks in the PDF plugin

Special functionality is available in the PDF plugin for print preview. We
don't want to allow this functionality to be exposed when not in print
preview as it may have potential security implications. This CL improves
the checks that are used:
1) Check the document URL to determine whether we are in print preview, rather
than the URL that is passed in to load, which could be chosen by an attacker.
2) Add CHECKs to ensure we are in print preview mode and trying to load a print
preview document when print preview messages are received.

Note that we should never get into a state where these checks would be invalid
but this gives us defense in depth.

BUG=654280

Review-Url: https://codereview.chromium.org/2486683002
Cr-Commit-Position: refs/heads/master@{#430802}
This commit is contained in:
raymes
2016-11-08 17:06:29 -08:00
committed by Commit bot
parent 806eb4e449
commit 9fb7fed591
2 changed files with 21 additions and 7 deletions

@ -293,7 +293,8 @@ OutOfProcessInstance::OutOfProcessInstance(PP_Instance instance)
stop_scrolling_(false),
background_color_(0),
top_toolbar_height_(0),
accessibility_state_(ACCESSIBILITY_STATE_OFF) {
accessibility_state_(ACCESSIBILITY_STATE_OFF),
is_print_preview_(false) {
loader_factory_.Initialize(this);
timer_factory_.Initialize(this);
form_factory_.Initialize(this);
@ -325,8 +326,9 @@ bool OutOfProcessInstance::Init(uint32_t argc,
return false;
std::string document_url = document_url_var.AsString();
base::StringPiece document_url_piece(document_url);
is_print_preview_ = document_url_piece.starts_with(kChromePrint);
if (!document_url_piece.starts_with(kChromeExtension) &&
!document_url_piece.starts_with(kChromePrint)) {
!is_print_preview_) {
return false;
}
@ -377,7 +379,7 @@ bool OutOfProcessInstance::Init(uint32_t argc,
// A |kJSResetPrintPreviewModeType| message will be sent to the plugin letting
// it know the url to load. By not loading here we avoid loading the same
// document twice.
if (IsPrintPreviewUrl(original_url))
if (IsPrintPreview())
return true;
LoadUrl(stream_url);
@ -436,6 +438,10 @@ void OutOfProcessInstance::HandleMessage(const pp::Var& message) {
dict.Get(pp::Var(kJSPrintPreviewGrayscale)).is_bool() &&
dict.Get(pp::Var(kJSPrintPreviewPageCount)).is_int()) {
url_ = dict.Get(pp::Var(kJSPrintPreviewUrl)).AsString();
// For security reasons we crash if the URL that is trying to be loaded here
// isn't a print preview one.
CHECK(IsPrintPreview());
CHECK(IsPrintPreviewUrl(url_));
preview_pages_info_ = std::queue<PreviewPageInfo>();
preview_document_load_state_ = LOAD_STATE_COMPLETE;
document_load_state_ = LOAD_STATE_LOADING;
@ -452,7 +458,13 @@ void OutOfProcessInstance::HandleMessage(const pp::Var& message) {
} else if (type == kJSLoadPreviewPageType &&
dict.Get(pp::Var(kJSPreviewPageUrl)).is_string() &&
dict.Get(pp::Var(kJSPreviewPageIndex)).is_int()) {
ProcessPreviewPageInfo(dict.Get(pp::Var(kJSPreviewPageUrl)).AsString(),
std::string url = dict.Get(pp::Var(kJSPreviewPageUrl)).AsString();
// For security reasons we crash if the URL that is trying to be loaded here
// isn't a print preview one.
CHECK(IsPrintPreview());
CHECK(IsPrintPreviewUrl(url));
ProcessPreviewPageInfo(url,
dict.Get(pp::Var(kJSPreviewPageIndex)).AsInt());
} else if (type == kJSStopScrollingType) {
stop_scrolling_ = true;
@ -1485,7 +1497,7 @@ void OutOfProcessInstance::AppendBlankPrintPreviewPages() {
}
bool OutOfProcessInstance::IsPrintPreview() {
return IsPrintPreviewUrl(url_);
return is_print_preview_;
}
uint32_t OutOfProcessInstance::GetBackgroundColor() {
@ -1507,8 +1519,7 @@ void OutOfProcessInstance::IsSelectingChanged(bool is_selecting) {
void OutOfProcessInstance::ProcessPreviewPageInfo(const std::string& url,
int dst_page_index) {
if (!IsPrintPreview())
return;
DCHECK(IsPrintPreview());
int src_page_index = ExtractPrintPreviewPageIndex(url);
if (src_page_index < 1)

@ -371,6 +371,9 @@ class OutOfProcessInstance : public pp::Instance,
ACCESSIBILITY_STATE_LOADED
} accessibility_state_;
// True if the plugin is loaded in print preview, otherwise false.
bool is_print_preview_;
DISALLOW_COPY_AND_ASSIGN(OutOfProcessInstance);
};