Only allow endpoints specifically marked as permitted to be accessed by the bookmarklet to be accessed by the bookmarklet.

This commit is contained in:
Simon Kornblith 2012-07-03 19:50:12 -04:00
parent d8783a93a0
commit 695cb47106
2 changed files with 40 additions and 7 deletions

View file

@ -216,7 +216,19 @@ Zotero.Server.DataListener.prototype._headerFinished = function() {
Zotero.debug(this.header, 5);
const methodRe = /^([A-Z]+) ([^ \r\n?]+)(\?[^ \r\n]+)?/;
const contentTypeRe = /[\r\n]Content-Type: +([^ \r\n]+)/i;
const contentTypeRe = /[\r\n]Content-Type: *([^ \r\n]+)/i;
if(!Zotero.isServer) {
const originRe = /[\r\n]Origin: *([^ \r\n]+)/i;
var m = originRe.exec(this.header);
if(m) {
this.origin = m[1];
} else {
const bookmarkletRe = /[\r\n]X-Zotero-Bookmarklet: *([^ \r\n]+)/i;
var m = bookmarkletRe.exec(this.header);
if(m) this.origin = "https://www.zotero.org";
}
}
// get first line of request
var method = methodRe.exec(this.header);
@ -294,11 +306,8 @@ Zotero.Server.DataListener.prototype._generateResponse = function(status, conten
if(!Zotero.isServer) {
response += "X-Zotero-Version: "+Zotero.version+"\r\n";
response += "X-Zotero-Connector-API-Version: "+CONNECTOR_API_VERSION+"\r\n";
const originRe = /[\r\n]Origin: +([^ \r\n]+)/i;
var m = originRe.exec(this.header);
if(m && (m[1] === "https://www.zotero.org" || m[1] === "http://www.zotero.org")) {
response += "Access-Control-Allow-Origin: "+m[1]+"\r\n";
if(this.origin === "https://www.zotero.org" || this.origin === "http://www.zotero.org") {
response += "Access-Control-Allow-Origin: "+this.origin+"\r\n";
response += "Access-Control-Allow-Methods: POST, GET, OPTIONS\r\n";
response += "Access-Control-Allow-Headers: Content-Type,X-Zotero-Connector-API-Version,X-Zotero-Version\r\n";
}
@ -324,12 +333,24 @@ Zotero.Server.DataListener.prototype._processEndpoint = function(method, postDat
try {
var endpoint = new this.endpoint;
// check that endpoint supports method
// Check that endpoint supports method
if(endpoint.supportedMethods && endpoint.supportedMethods.indexOf(method) === -1) {
this._requestFinished(this._generateResponse(400, "text/plain", "Endpoint does not support method\n"));
return;
}
// Check that endpoint supports bookmarklet
if(this.origin) {
var isBookmarklet = this.origin === "https://www.zotero.org" || this.origin === "http://www.zotero.org";
// Disallow bookmarklet origins to access endpoints without permitBookmarklet
// set. We allow other origins to access these endpoints because they have to
// be privileged to avoid being blocked by our headers.
if(isBookmarklet && !endpoint.permitBookmarklet) {
this._requestFinished(this._generateResponse(403, "text/plain", "Access forbidden to bookmarklet\n"));
return;
}
}
var decodedData = null;
if(postData && this.contentType) {
// check that endpoint supports contentType

View file

@ -70,6 +70,7 @@ Zotero.Server.Endpoints["/connector/getTranslators"] = Zotero.Server.Connector.G
Zotero.Server.Connector.GetTranslators.prototype = {
"supportedMethods":["POST"],
"supportedDataTypes":["application/json"],
"permitBookmarklet":true,
/**
* Gets available translator list and other important data
@ -121,6 +122,7 @@ Zotero.Server.Connector.Data = {};
Zotero.Server.Connector.Detect.prototype = {
"supportedMethods":["POST"],
"supportedDataTypes":["application/json"],
"permitBookmarklet":true,
/**
* Loads HTML into a hidden browser and initiates translator detection
@ -209,6 +211,7 @@ Zotero.Server.Endpoints["/connector/savePage"] = Zotero.Server.Connector.SavePag
Zotero.Server.Connector.SavePage.prototype = {
"supportedMethods":["POST"],
"supportedDataTypes":["application/json"],
"permitBookmarklet":true,
/**
* Either loads HTML into a hidden browser and initiates translation, or saves items directly
@ -311,6 +314,7 @@ Zotero.Server.Endpoints["/connector/saveItems"] = Zotero.Server.Connector.SaveIt
Zotero.Server.Connector.SaveItem.prototype = {
"supportedMethods":["POST"],
"supportedDataTypes":["application/json"],
"permitBookmarklet":true,
/**
* Either loads HTML into a hidden browser and initiates translation, or saves items directly
@ -372,6 +376,7 @@ Zotero.Server.Endpoints["/connector/saveSnapshot"] = Zotero.Server.Connector.Sav
Zotero.Server.Connector.SaveSnapshot.prototype = {
"supportedMethods":["POST"],
"supportedDataTypes":["application/json"],
"permitBookmarklet":true,
/**
* Save snapshot
@ -454,6 +459,7 @@ Zotero.Server.Endpoints["/connector/selectItems"] = Zotero.Server.Connector.Sele
Zotero.Server.Connector.SelectItems.prototype = {
"supportedMethods":["POST"],
"supportedDataTypes":["application/json"],
"permitBookmarklet":true,
/**
* Finishes up translation when item selection is complete
@ -487,6 +493,7 @@ Zotero.Server.Endpoints["/connector/attachmentProgress"] = Zotero.Server.Connect
Zotero.Server.Connector.Progress.prototype = {
"supportedMethods":["POST"],
"supportedDataTypes":["application/json"],
"permitBookmarklet":true,
/**
* @param {String} data POST data or GET query string
@ -511,6 +518,7 @@ Zotero.Server.Endpoints["/connector/getTranslatorCode"] = Zotero.Server.Connecto
Zotero.Server.Connector.GetTranslatorCode.prototype = {
"supportedMethods":["POST"],
"supportedDataTypes":["application/json"],
"permitBookmarklet":true,
/**
* Returns a 200 response to say the server is alive
@ -539,6 +547,7 @@ Zotero.Server.Endpoints["/connector/getSelectedCollection"] = Zotero.Server.Conn
Zotero.Server.Connector.GetSelectedCollection.prototype = {
"supportedMethods":["POST"],
"supportedDataTypes":["application/json"],
"permitBookmarklet":true,
/**
* Returns a 200 response to say the server is alive
@ -594,6 +603,7 @@ Zotero.Server.Endpoints["/connector/ping"] = Zotero.Server.Connector.Ping;
Zotero.Server.Connector.Ping.prototype = {
"supportedMethods":["POST"],
"supportedDataTypes":["application/json", "text/plain"],
"permitBookmarklet":true,
/**
* Sends nothing
@ -617,6 +627,7 @@ Zotero.Server.Connector.IEHack = function() {};
Zotero.Server.Endpoints["/connector/ieHack"] = Zotero.Server.Connector.IEHack;
Zotero.Server.Connector.IEHack.prototype = {
"supportedMethods":["GET"],
"permitBookmarklet":true,
/**
* Sends a fixed webpage
@ -642,6 +653,7 @@ Zotero.Server.Endpoints["/translate/select"] = Zotero.Server.Connector.Incompati
Zotero.Server.Connector.IncompatibleVersion.prototype = {
"supportedMethods":["POST"],
"supportedDataTypes":["application/json"],
"permitBookmarklet":true,
"init":function(postData, sendResponseCallback) {
sendResponseCallback(404);