summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/newview/llbuycurrencyhtml.cpp2
-rw-r--r--indra/newview/llcommandhandler.cpp82
-rw-r--r--indra/newview/llcommandhandler.h10
-rw-r--r--indra/newview/llfloatersearch.cpp2
-rw-r--r--indra/newview/llfloaterworldmap.cpp4
-rw-r--r--indra/newview/llgroupactions.cpp27
-rw-r--r--indra/newview/llpaneleditwearable.cpp2
-rw-r--r--indra/newview/llpanelprofile.cpp24
-rw-r--r--indra/newview/llpanelprofileclassifieds.cpp24
-rw-r--r--indra/newview/llpanelprofilepicks.cpp24
-rw-r--r--indra/newview/llviewerfloaterreg.cpp98
-rw-r--r--indra/newview/llviewerinventory.cpp2
12 files changed, 266 insertions, 35 deletions
diff --git a/indra/newview/llbuycurrencyhtml.cpp b/indra/newview/llbuycurrencyhtml.cpp
index 1c69dadb12..7ad06f8eaa 100644
--- a/indra/newview/llbuycurrencyhtml.cpp
+++ b/indra/newview/llbuycurrencyhtml.cpp
@@ -41,7 +41,7 @@ class LLBuyCurrencyHTMLHandler :
{
public:
// requests will be throttled from a non-trusted browser
- LLBuyCurrencyHTMLHandler() : LLCommandHandler( "buycurrencyhtml", UNTRUSTED_ALLOW ) {}
+ LLBuyCurrencyHTMLHandler() : LLCommandHandler( "buycurrencyhtml", UNTRUSTED_THROTTLE) {}
bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
{
diff --git a/indra/newview/llcommandhandler.cpp b/indra/newview/llcommandhandler.cpp
index 23e2271eae..74f37961c7 100644
--- a/indra/newview/llcommandhandler.cpp
+++ b/indra/newview/llcommandhandler.cpp
@@ -39,6 +39,7 @@
#define THROTTLE_PERIOD 5 // required seconds between throttled commands
static LLCommandDispatcherListener sCommandDispatcherListener;
+const std::string LLCommandHandler::NAV_TYPE_CLICKED = "clicked";
//---------------------------------------------------------------------------
// Underlying registry for command handlers, not directly accessible.
@@ -64,6 +65,9 @@ public:
bool trusted_browser);
private:
+ void notifySlurlBlocked();
+ void notifySlurlThrottled();
+
friend LLSD LLCommandDispatcher::enumerate();
std::map<std::string, LLCommandHandlerInfo> mMap;
};
@@ -96,8 +100,6 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd,
const std::string& nav_type,
bool trusted_browser)
{
- static bool slurl_blocked = false;
- static bool slurl_throttled = false;
static F64 last_throttle_time = 0.0;
F64 cur_time = 0.0;
std::map<std::string, LLCommandHandlerInfo>::iterator it = mMap.find(cmd);
@@ -115,44 +117,45 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd,
// block request from external browser, but report as
// "handled" because it was well formatted.
LL_WARNS_ONCE("SLURL") << "Blocked SLURL command from untrusted browser" << LL_ENDL;
- if (! slurl_blocked)
- {
- if (LLStartUp::getStartupState() >= STATE_BROWSER_INIT)
- {
- // Note: commands can arrive before we initialize everything we need for Notification.
- LLNotificationsUtil::add("BlockedSLURL");
- }
- slurl_blocked = true;
- }
+ notifySlurlBlocked();
return true;
+ case LLCommandHandler::UNTRUSTED_CLICK_ONLY:
+ if (nav_type == LLCommandHandler::NAV_TYPE_CLICKED
+ && info.mHandler->canHandleUntrusted(params, query_map, web, nav_type))
+ {
+ break;
+ }
+ LL_WARNS_ONCE("SLURL") << "Blocked SLURL click-only command " << cmd << " from untrusted browser" << LL_ENDL;
+ notifySlurlBlocked();
+ return true;
+
case LLCommandHandler::UNTRUSTED_THROTTLE:
+ //skip initial request from external browser before STATE_BROWSER_INIT
+ if (LLStartUp::getStartupState() == STATE_FIRST)
+ {
+ return true;
+ }
+ if (!info.mHandler->canHandleUntrusted(params, query_map, web, nav_type))
+ {
+ LL_WARNS_ONCE("SLURL") << "Blocked SLURL command from untrusted browser" << LL_ENDL;
+ notifySlurlBlocked();
+ return true;
+ }
// if users actually click on a link, we don't need to throttle it
// (throttling mechanism is used to prevent an avalanche of clicks via
// javascript
- if ( nav_type == "clicked" )
+ if (nav_type == LLCommandHandler::NAV_TYPE_CLICKED)
{
break;
}
- //skip initial request from external browser before STATE_BROWSER_INIT
- if (LLStartUp::getStartupState() == STATE_FIRST)
- {
- return true;
- }
cur_time = LLTimer::getElapsedSeconds();
if (cur_time < last_throttle_time + THROTTLE_PERIOD)
{
// block request from external browser if it happened
// within THROTTLE_PERIOD seconds of the last command
LL_WARNS_ONCE("SLURL") << "Throttled SLURL command from untrusted browser" << LL_ENDL;
- if (! slurl_throttled)
- {
- if (LLStartUp::getStartupState() >= STATE_BROWSER_INIT)
- {
- LLNotificationsUtil::add("ThrottledSLURL");
- }
- slurl_throttled = true;
- }
+ notifySlurlThrottled();
return true;
}
last_throttle_time = cur_time;
@@ -163,6 +166,34 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd,
return info.mHandler->handle(params, query_map, web);
}
+void LLCommandHandlerRegistry::notifySlurlBlocked()
+{
+ static bool slurl_blocked = false;
+ if (!slurl_blocked)
+ {
+ if (LLStartUp::getStartupState() >= STATE_BROWSER_INIT)
+ {
+ // Note: commands can arrive before we initialize everything we need for Notification.
+ LLNotificationsUtil::add("BlockedSLURL");
+ }
+ slurl_blocked = true;
+ }
+}
+
+void LLCommandHandlerRegistry::notifySlurlThrottled()
+{
+ static bool slurl_throttled = false;
+ if (!slurl_throttled)
+ {
+ if (LLStartUp::getStartupState() >= STATE_BROWSER_INIT)
+ {
+ // Note: commands can arrive before we initialize everything we need for Notification.
+ LLNotificationsUtil::add("ThrottledSLURL");
+ }
+ slurl_throttled = true;
+ }
+}
+
//---------------------------------------------------------------------------
// Automatic registration of commands, runs before main()
//---------------------------------------------------------------------------
@@ -230,6 +261,7 @@ symbol_info symbols[] =
{
ent(LLCommandHandler::UNTRUSTED_ALLOW), // allow commands from untrusted browsers
ent(LLCommandHandler::UNTRUSTED_BLOCK), // ignore commands from untrusted browsers
+ ent(LLCommandHandler::UNTRUSTED_CLICK_ONLY), // allow untrusted, but only if clicked
ent(LLCommandHandler::UNTRUSTED_THROTTLE) // allow untrusted, but only a few per min.
};
diff --git a/indra/newview/llcommandhandler.h b/indra/newview/llcommandhandler.h
index 1e0895565a..763e3ee51f 100644
--- a/indra/newview/llcommandhandler.h
+++ b/indra/newview/llcommandhandler.h
@@ -65,9 +65,12 @@ public:
{
UNTRUSTED_ALLOW, // allow commands from untrusted browsers
UNTRUSTED_BLOCK, // ignore commands from untrusted browsers
+ UNTRUSTED_CLICK_ONLY, // allow untrusted, but only if clicked
UNTRUSTED_THROTTLE // allow untrusted, but only a few per min.
};
+ static const std::string NAV_TYPE_CLICKED;
+
LLCommandHandler(const char* command, EUntrustedAccess untrusted_access);
// Automatically registers object to get called when
// command is executed. All commands can be processed
@@ -76,6 +79,13 @@ public:
virtual ~LLCommandHandler();
+ virtual bool canHandleUntrusted(
+ const LLSD& params,
+ const LLSD& query_map,
+ LLMediaCtrl* web,
+ const std::string& nav_type)
+ { return true; }
+
virtual bool handle(const LLSD& params,
const LLSD& query_map,
LLMediaCtrl* web) = 0;
diff --git a/indra/newview/llfloatersearch.cpp b/indra/newview/llfloatersearch.cpp
index bb3ed77772..7e6af45515 100644
--- a/indra/newview/llfloatersearch.cpp
+++ b/indra/newview/llfloatersearch.cpp
@@ -45,7 +45,7 @@ class LLSearchHandler : public LLCommandHandler
{
public:
// requires trusted browser to trigger
- LLSearchHandler() : LLCommandHandler("search", UNTRUSTED_THROTTLE) { }
+ LLSearchHandler() : LLCommandHandler("search", UNTRUSTED_CLICK_ONLY) { }
bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web)
{
if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableSearch"))
diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp
index 977023cfe4..4f772aa141 100644
--- a/indra/newview/llfloaterworldmap.cpp
+++ b/indra/newview/llfloaterworldmap.cpp
@@ -123,7 +123,7 @@ class LLWorldMapHandler : public LLCommandHandler
{
public:
// requires trusted browser to trigger
- LLWorldMapHandler() : LLCommandHandler("worldmap", UNTRUSTED_THROTTLE ) { }
+ LLWorldMapHandler() : LLCommandHandler("worldmap", UNTRUSTED_CLICK_ONLY ) { }
bool handle(const LLSD& params, const LLSD& query_map,
LLMediaCtrl* web)
@@ -160,7 +160,7 @@ class LLMapTrackAvatarHandler : public LLCommandHandler
{
public:
// requires trusted browser to trigger
- LLMapTrackAvatarHandler() : LLCommandHandler("maptrackavatar", UNTRUSTED_THROTTLE)
+ LLMapTrackAvatarHandler() : LLCommandHandler("maptrackavatar", UNTRUSTED_CLICK_ONLY)
{
}
diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp
index 84a1278767..815840f990 100644
--- a/indra/newview/llgroupactions.cpp
+++ b/indra/newview/llgroupactions.cpp
@@ -52,7 +52,32 @@ class LLGroupHandler : public LLCommandHandler
{
public:
// requires trusted browser to trigger
- LLGroupHandler() : LLCommandHandler("group", UNTRUSTED_THROTTLE) { }
+ LLGroupHandler() : LLCommandHandler("group", UNTRUSTED_CLICK_ONLY) { }
+
+ virtual bool canHandleUntrusted(
+ const LLSD& params,
+ const LLSD& query_map,
+ LLMediaCtrl* web,
+ const std::string& nav_type)
+ {
+ if (params.size() < 1)
+ {
+ return true; // don't block, will fail later
+ }
+
+ if (nav_type == NAV_TYPE_CLICKED)
+ {
+ return true;
+ }
+
+ const std::string verb = params[0].asString();
+ if (verb == "create")
+ {
+ return false;
+ }
+ return true;
+ }
+
bool handle(const LLSD& tokens, const LLSD& query_map,
LLMediaCtrl* web)
{
diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp
index ea10aa75ae..0103bf628a 100644
--- a/indra/newview/llpaneleditwearable.cpp
+++ b/indra/newview/llpaneleditwearable.cpp
@@ -1663,7 +1663,7 @@ void LLPanelEditWearable::initPreviousAlphaTextureEntry(LLAvatarAppearanceDefine
class LLMetricSystemHandler : public LLCommandHandler
{
public:
- LLMetricSystemHandler() : LLCommandHandler("metricsystem", UNTRUSTED_THROTTLE) { }
+ LLMetricSystemHandler() : LLCommandHandler("metricsystem", UNTRUSTED_CLICK_ONLY) { }
bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
{
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index d3898afcbd..deebf0cd1b 100644
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -484,6 +484,30 @@ public:
// requires trusted browser to trigger
LLAgentHandler() : LLCommandHandler("agent", UNTRUSTED_THROTTLE) { }
+ virtual bool canHandleUntrusted(
+ const LLSD& params,
+ const LLSD& query_map,
+ LLMediaCtrl* web,
+ const std::string& nav_type)
+ {
+ if (params.size() < 2)
+ {
+ return true; // don't block, will fail later
+ }
+
+ if (nav_type == NAV_TYPE_CLICKED)
+ {
+ return true;
+ }
+
+ const std::string verb = params[1].asString();
+ if (verb == "about" || verb == "inspect" || verb == "reportAbuse")
+ {
+ return true;
+ }
+ return false;
+ }
+
bool handle(const LLSD& params, const LLSD& query_map,
LLMediaCtrl* web)
{
diff --git a/indra/newview/llpanelprofileclassifieds.cpp b/indra/newview/llpanelprofileclassifieds.cpp
index a3913ddc49..1ff12b4f37 100644
--- a/indra/newview/llpanelprofileclassifieds.cpp
+++ b/indra/newview/llpanelprofileclassifieds.cpp
@@ -81,6 +81,30 @@ public:
std::set<LLUUID> mClassifiedIds;
std::string mRequestVerb;
+
+ virtual bool canHandleUntrusted(
+ const LLSD& params,
+ const LLSD& query_map,
+ LLMediaCtrl* web,
+ const std::string& nav_type)
+ {
+ if (params.size() < 1)
+ {
+ return true; // don't block, will fail later
+ }
+
+ if (nav_type == NAV_TYPE_CLICKED)
+ {
+ return true;
+ }
+
+ const std::string verb = params[0].asString();
+ if (verb == "create")
+ {
+ return false;
+ }
+ return true;
+ }
bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
{
diff --git a/indra/newview/llpanelprofilepicks.cpp b/indra/newview/llpanelprofilepicks.cpp
index 774119f169..45d0252e4f 100644
--- a/indra/newview/llpanelprofilepicks.cpp
+++ b/indra/newview/llpanelprofilepicks.cpp
@@ -63,6 +63,30 @@ public:
// requires trusted browser to trigger
LLPickHandler() : LLCommandHandler("pick", UNTRUSTED_THROTTLE) { }
+ virtual bool canHandleUntrusted(
+ const LLSD& params,
+ const LLSD& query_map,
+ LLMediaCtrl* web,
+ const std::string& nav_type)
+ {
+ if (params.size() < 1)
+ {
+ return true; // don't block, will fail later
+ }
+
+ if (nav_type == NAV_TYPE_CLICKED)
+ {
+ return true;
+ }
+
+ const std::string verb = params[0].asString();
+ if (verb == "create")
+ {
+ return false;
+ }
+ return true;
+ }
+
bool handle(const LLSD& params, const LLSD& query_map,
LLMediaCtrl* web)
{
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 06a6c5e373..5ac58d97be 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -173,11 +173,103 @@
class LLFloaterOpenHandler : public LLCommandHandler
{
public:
- // requires trusted browser to trigger
+ // requires trusted browser to trigger or an explicit click
LLFloaterOpenHandler() : LLCommandHandler("openfloater", UNTRUSTED_THROTTLE) { }
- bool handle(const LLSD& params, const LLSD& query_map,
- LLMediaCtrl* web)
+ virtual bool canHandleUntrusted(
+ const LLSD& params,
+ const LLSD& query_map,
+ LLMediaCtrl* web,
+ const std::string& nav_type)
+ {
+ if (params.size() != 1)
+ {
+ return true; // will fail silently
+ }
+
+ std::string fl_name = params[0].asString();
+
+ if (nav_type == NAV_TYPE_CLICKED)
+ {
+ const std::list<std::string> blacklist_clicked = {
+ "camera_presets",
+ "delete_pref_preset",
+ "forget_username",
+ "god_tools",
+ "group_picker",
+ "hud",
+ "incoming_call",
+ "linkreplace",
+ "message_critical", // Modal!!! Login specific.
+ "message_tos", // Modal!!! Login specific.
+ "save_pref_preset",
+ "save_camera_preset",
+ "region_restarting",
+ "outfit_snapshot",
+ "upload_anim_bvh",
+ "upload_anim_anim",
+ "upload_image",
+ "upload_model",
+ "upload_script",
+ "upload_sound"
+ };
+ return std::find(blacklist_clicked.begin(), blacklist_clicked.end(), fl_name) == blacklist_clicked.end();
+ }
+ else
+ {
+ const std::list<std::string> blacklist_untrusted = {
+ "360capture",
+ "block_timers",
+ "add_payment_method",
+ "appearance",
+ "associate_listing",
+ "avatar_picker",
+ "camera",
+ "camera_presets",
+ "classified",
+ "add_landmark",
+ "delete_pref_preset",
+ "env_fixed_environmentent_water",
+ "env_fixed_environmentent_sky",
+ "env_edit_extdaycycle",
+ "font_test",
+ "forget_username",
+ "god_tools",
+ "group_picker",
+ "hud",
+ "incoming_call",
+ "linkreplace",
+ "mem_leaking",
+ "marketplace_validation",
+ "message_critical", // Modal!!! Login specific. If this is in use elsewhere, better to create a non modal variant
+ "message_tos", // Modal!!! Login specific.
+ "mute_object_by_name",
+ "publish_classified",
+ "save_pref_preset",
+ "save_camera_preset",
+ "region_restarting",
+ "script_debug",
+ "script_debug_output",
+ "sell_land",
+ "outfit_snapshot",
+ "upload_anim_bvh",
+ "upload_anim_anim",
+ "upload_image",
+ "upload_model",
+ "upload_script",
+ "upload_sound"
+ };
+ return std::find(blacklist_untrusted.begin(), blacklist_untrusted.end(), fl_name) == blacklist_untrusted.end();
+ }
+
+
+ return true;
+ }
+
+ bool handle(
+ const LLSD& params,
+ const LLSD& query_map,
+ LLMediaCtrl* web) override
{
if (params.size() != 1)
{
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 55ac817479..50252556de 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -232,7 +232,7 @@ class LLInventoryHandler : public LLCommandHandler
{
public:
// requires trusted browser to trigger
- LLInventoryHandler() : LLCommandHandler("inventory", UNTRUSTED_THROTTLE) { }
+ LLInventoryHandler() : LLCommandHandler("inventory", UNTRUSTED_CLICK_ONLY) { }
bool handle(const LLSD& params, const LLSD& query_map,
LLMediaCtrl* web)