Fix multiple href exploits from incorrectly scoped locates

Also adds a helper to flatten a keyed list to it's contents as it
turns out that byond cannot locate in a keyed list
This commit is contained in:
oranges
2016-09-27 22:04:08 +00:00
parent e3ce14d8fc
commit 8b7eb11df9
10 changed files with 70 additions and 129 deletions

View File

@@ -392,5 +392,18 @@
if(islist(.[i])) if(islist(.[i]))
.[i] = .(.[i]) .[i] = .(.[i])
#if DM_VERSION > 512
#error Remie said that lummox was adding a way to get a lists
#error contents via list.values, if that is true remove this
#error otherwise, update the version and bug lummox
#elseif
//Flattens a keyed list into a list of it's contents
/proc/flatten_list(list/key_list)
if(!islist(key_list))
return null
. = list()
for(var/key in key_list)
. |= key_list[key]
//Picks from the list, with some safeties, and returns the "default" arg if it fails //Picks from the list, with some safeties, and returns the "default" arg if it fails
#define DEFAULTPICK(L, default) ((istype(L, /list) && L:len) ? pick(L) : default) #define DEFAULTPICK(L, default) ((istype(L, /list) && L:len) ? pick(L) : default)

View File

@@ -21,6 +21,7 @@ var/global/list/crafting_recipes = list() //list of all table craft recipes
var/global/list/rcd_list = list() //list of Rapid Construction Devices. var/global/list/rcd_list = list() //list of Rapid Construction Devices.
var/global/list/apcs_list = list() //list of all Area Power Controller machines, seperate from machines for powernet speeeeeeed. var/global/list/apcs_list = list() //list of all Area Power Controller machines, seperate from machines for powernet speeeeeeed.
var/global/list/tracked_implants = list() //list of all current implants that are tracked to work out what sort of trek everyone is on. Sadly not on lavaworld not implemented... var/global/list/tracked_implants = list() //list of all current implants that are tracked to work out what sort of trek everyone is on. Sadly not on lavaworld not implemented...
var/global/list/tracked_chem_implants = list() //list of implants the prisoner console can track and send inject commands too
var/global/list/poi_list = list() //list of points of interest for observe/follow var/global/list/poi_list = list() //list of points of interest for observe/follow
var/global/list/pinpointer_list = list() //list of all pinpointers. Used to change stuff they are pointing to all at once. var/global/list/pinpointer_list = list() //list of all pinpointers. Used to change stuff they are pointing to all at once.
var/global/list/zombie_infection_list = list() // A list of all zombie_infection organs, for any mass "animation" var/global/list/zombie_infection_list = list() // A list of all zombie_infection organs, for any mass "animation"

View File

@@ -32,7 +32,7 @@
dat += "<H3>Prisoner Implant Management</H3>" dat += "<H3>Prisoner Implant Management</H3>"
dat += "<HR>Chemical Implants<BR>" dat += "<HR>Chemical Implants<BR>"
var/turf/Tr = null var/turf/Tr = null
for(var/obj/item/weapon/implant/chem/C in tracked_implants) for(var/obj/item/weapon/implant/chem/C in tracked_chem_implants)
Tr = get_turf(C) Tr = get_turf(C)
if((Tr) && (Tr.z != src.z)) if((Tr) && (Tr.z != src.z))
continue//Out of range continue//Out of range
@@ -114,17 +114,17 @@
num = min(num,1000) //Cap the quota to the equivilent of 10 minutes. num = min(num,1000) //Cap the quota to the equivilent of 10 minutes.
inserted_id.goal = num inserted_id.goal = num
else if(href_list["inject1"]) else if(href_list["inject1"])
var/obj/item/weapon/implant/I = locate(href_list["inject1"]) var/obj/item/weapon/implant/I = locate(href_list["inject1"]) in tracked_chem_implants
if(I) if(I && istype(I))
I.activate(1) I.activate(1)
else if(href_list["inject5"]) else if(href_list["inject5"])
var/obj/item/weapon/implant/I = locate(href_list["inject5"]) var/obj/item/weapon/implant/I = locate(href_list["inject5"]) in tracked_chem_implants
if(I) if(I && istype(I))
I.activate(5) I.activate(5)
else if(href_list["inject10"]) else if(href_list["inject10"])
var/obj/item/weapon/implant/I = locate(href_list["inject10"]) var/obj/item/weapon/implant/I = locate(href_list["inject10"]) in tracked_chem_implants
if(I) if(I && istype(I))
I.activate(10) I.activate(10)
else if(href_list["lock"]) else if(href_list["lock"])
@@ -136,8 +136,8 @@
else if(href_list["warn"]) else if(href_list["warn"])
var/warning = copytext(sanitize(input(usr,"Message:","Enter your message here!","")),1,MAX_MESSAGE_LEN) var/warning = copytext(sanitize(input(usr,"Message:","Enter your message here!","")),1,MAX_MESSAGE_LEN)
if(!warning) return if(!warning) return
var/obj/item/weapon/implant/I = locate(href_list["warn"]) var/obj/item/weapon/implant/I = locate(href_list["warn"]) in tracked_chem_implants
if((I)&&(I.imp_in)) if(I && istype(I) && I.imp_in)
var/mob/living/carbon/R = I.imp_in var/mob/living/carbon/R = I.imp_in
R << "<span class='italics'>You hear a voice in your head saying: '[warning]'</span>" R << "<span class='italics'>You hear a voice in your head saying: '[warning]'</span>"
log_say("[usr]/[usr.ckey] sent an implant message to [R]/[R.ckey]: '[warning]'") log_say("[usr]/[usr.ckey] sent an implant message to [R]/[R.ckey]: '[warning]'")

View File

@@ -136,11 +136,16 @@
return .(cameras) return .(cameras)
return html return html
/obj/item/device/camera_bug/proc/get_seens()
if(current && current.can_use())
var/list/seen = current.can_see()
return seen
/obj/item/device/camera_bug/proc/camera_report() /obj/item/device/camera_bug/proc/camera_report()
// this should only be called if current exists // this should only be called if current exists
var/dat = "" var/dat = ""
if(current && current.can_use()) var/list/seen = get_seens()
var/list/seen = current.can_see() if(seen && seen.len >= 1)
var/list/names = list() var/list/names = list()
for(var/obj/singularity/S in seen) // god help you if you see more than one for(var/obj/singularity/S in seen) // god help you if you see more than one
if(S.name in names) if(S.name in names)
@@ -190,23 +195,29 @@
if("mode" in href_list) if("mode" in href_list)
track_mode = text2num(href_list["mode"]) track_mode = text2num(href_list["mode"])
if("monitor" in href_list) if("monitor" in href_list)
var/obj/machinery/camera/C = locate(href_list["monitor"]) //You can't locate on a list with keys
if(C) var/list/cameras = flatten_list(bugged_cameras)
var/obj/machinery/camera/C = locate(href_list["monitor"]) in cameras
if(C && istype(C))
track_mode = BUGMODE_MONITOR track_mode = BUGMODE_MONITOR
current = C current = C
usr.reset_perspective(null) usr.reset_perspective(null)
interact() interact()
if("track" in href_list) if("track" in href_list)
var/atom/A = locate(href_list["track"]) var/list/seen = get_seens()
if(A) if(seen && seen.len >= 1)
var/atom/A = locate(href_list["track"]) in seen
if(A && istype(A))
tracking = A tracking = A
tracked_name = A.name tracked_name = A.name
last_found = current.c_tag last_found = current.c_tag
last_seen = world.time last_seen = world.time
track_mode = BUGMODE_TRACK track_mode = BUGMODE_TRACK
if("emp" in href_list) if("emp" in href_list)
var/obj/machinery/camera/C = locate(href_list["emp"]) //You can't locate on a list with keys
if(istype(C) && C.bug == src) var/list/cameras = flatten_list(bugged_cameras)
var/obj/machinery/camera/C = locate(href_list["emp"]) in cameras
if(C && istype(C) && C.bug == src)
C.emp_act(1) C.emp_act(1)
C.bug = null C.bug = null
bugged_cameras -= C.c_tag bugged_cameras -= C.c_tag
@@ -217,8 +228,10 @@
current = null current = null
return return
if("view" in href_list) if("view" in href_list)
var/obj/machinery/camera/C = locate(href_list["view"]) //You can't locate on a list with keys
if(istype(C)) var/list/cameras = flatten_list(bugged_cameras)
var/obj/machinery/camera/C = locate(href_list["view"]) in cameras
if(C && istype(C))
if(!C.can_use()) if(!C.can_use())
usr << "<span class='warning'>Something's wrong with that camera! You can't get a feed.</span>" usr << "<span class='warning'>Something's wrong with that camera! You can't get a feed.</span>"
return return

View File

@@ -24,11 +24,11 @@
/obj/item/weapon/implant/chem/New() /obj/item/weapon/implant/chem/New()
..() ..()
create_reagents(50) create_reagents(50)
tracked_implants += src tracked_chem_implants += src
/obj/item/weapon/implant/chem/Destroy() /obj/item/weapon/implant/chem/Destroy()
..() ..()
tracked_implants -= src tracked_chem_implants -= src

View File

@@ -76,7 +76,9 @@
/obj/structure/guncase/Topic(href, href_list) /obj/structure/guncase/Topic(href, href_list)
if(href_list["retrieve"]) if(href_list["retrieve"])
var/obj/item/O = locate(href_list["retrieve"]) var/obj/item/O = locate(href_list["retrieve"]) in contents
if(!O || !istype(O))
return
if(!usr.canUseTopic(src)) if(!usr.canUseTopic(src))
return return
if(ishuman(usr)) if(ishuman(usr))

View File

@@ -264,9 +264,8 @@
if (istype(hclient)) if (istype(hclient))
switch (href_list["action"]) switch (href_list["action"])
if ("play_card") if ("play_card")
var/datum/playingcard/card = locate(href_list["card"]) var/datum/playingcard/card = locate(href_list["card"]) in cards
if (card && istype(card))
if (card in src.cards)
src.discard(card) src.discard(card)
if ("toggle_conceal") if ("toggle_conceal")
src.toggle_conceal() src.toggle_conceal()

View File

@@ -374,10 +374,12 @@ var/global/list/datum/cachedbook/cachedbooks // List of our cached book datums
b.duedate = world.time + (checkoutperiod * 600) b.duedate = world.time + (checkoutperiod * 600)
checkouts.Add(b) checkouts.Add(b)
if(href_list["checkin"]) if(href_list["checkin"])
var/datum/borrowbook/b = locate(href_list["checkin"]) var/datum/borrowbook/b = locate(href_list["checkin"]) in checkouts
if(b && istype(b))
checkouts.Remove(b) checkouts.Remove(b)
if(href_list["delbook"]) if(href_list["delbook"])
var/obj/item/weapon/book/b = locate(href_list["delbook"]) var/obj/item/weapon/book/b = locate(href_list["delbook"]) in inventory
if(b && istype(b))
inventory.Remove(b) inventory.Remove(b)
if(href_list["setauthor"]) if(href_list["setauthor"])
var/newauthor = copytext(sanitize(input("Enter the author's name: ") as text|null),1,MAX_MESSAGE_LEN) var/newauthor = copytext(sanitize(input("Enter the author's name: ") as text|null),1,MAX_MESSAGE_LEN)

View File

@@ -683,90 +683,6 @@
update_fire() update_fire()
/mob/living/silicon/robot/proc/installed_modules()
if(!module)
pick_module()
return
var/dat = {"<A HREF='?src=\ref[src];mach_close=robotmod'>Close</A>
<BR>
<BR>
<B>Activated Modules</B>
<BR>
<table border='0'>
<tr><td>Module 1:</td><td>[module_state_1 ? "<A HREF=?src=\ref[src];mod=\ref[module_state_1]>[module_state_1]<A>" : "No Module"]</td></tr>
<tr><td>Module 2:</td><td>[module_state_2 ? "<A HREF=?src=\ref[src];mod=\ref[module_state_2]>[module_state_2]<A>" : "No Module"]</td></tr>
<tr><td>Module 3:</td><td>[module_state_3 ? "<A HREF=?src=\ref[src];mod=\ref[module_state_3]>[module_state_3]<A>" : "No Module"]</td></tr>
</table><BR>
<B>Installed Modules</B><BR><BR>
<table border='0'>"}
for (var/obj in module.modules)
if (!obj)
dat += text("<tr><td><B>Resource depleted</B></td></tr>")
else if(activated(obj))
dat += text("<tr><td>[obj]</td><td><B>Activated</B></td></tr>")
else
dat += text("<tr><td>[obj]</td><td><A HREF=?src=\ref[src];act=\ref[obj]>Activate</A></td></tr>")
if (emagged)
if(activated(module.emag))
dat += text("<tr><td>[module.emag]</td><td><B>Activated</B></td></tr>")
else
dat += text("<tr><td>[module.emag]</td><td><A HREF=?src=\ref[src];act=\ref[module.emag]>Activate</A></td></tr>")
dat += "</table>"
/*
if(activated(obj))
dat += text("[obj]: \[<B>Activated</B> | <A HREF=?src=\ref[src];deact=\ref[obj]>Deactivate</A>\]<BR>")
else
dat += text("[obj]: \[<A HREF=?src=\ref[src];act=\ref[obj]>Activate</A> | <B>Deactivated</B>\]<BR>")
*/
var/datum/browser/popup = new(src, "robotmod", "Modules")
popup.set_content(dat)
popup.open()
/mob/living/silicon/robot/Topic(href, href_list)
..()
if(usr && (src != usr))
return
if (href_list["mach_close"])
var/t1 = text("window=[href_list["mach_close"]]")
unset_machine()
src << browse(null, t1)
return
if (href_list["showalerts"])
robot_alerts()
return
if (href_list["mod"])
var/obj/item/O = locate(href_list["mod"])
if (O)
O.attack_self(src)
if (href_list["act"])
var/obj/item/O = locate(href_list["act"])
activate_module(O)
installed_modules()
if (href_list["deact"])
var/obj/item/O = locate(href_list["deact"])
if(activated(O))
if(module_state_1 == O)
module_state_1 = null
contents -= O
else if(module_state_2 == O)
module_state_2 = null
contents -= O
else if(module_state_3 == O)
module_state_3 = null
contents -= O
else
src << "Module isn't activated."
else
src << "Module isn't activated"
installed_modules()
#define BORG_CAMERA_BUFFER 30 #define BORG_CAMERA_BUFFER 30
/mob/living/silicon/robot/Move(a, b, flag) /mob/living/silicon/robot/Move(a, b, flag)
var/oldLoc = src.loc var/oldLoc = src.loc

View File

@@ -248,7 +248,7 @@ a.updated {
usr.machine = src usr.machine = src
if (href_list["viewhistory"]) if (href_list["viewhistory"])
var/datum/stock/S = locate(href_list["viewhistory"]) var/datum/stock/S = locate(href_list["viewhistory"]) in stockExchange.stocks
if (S) if (S)
S.displayValues(usr) S.displayValues(usr)
@@ -256,20 +256,15 @@ a.updated {
logged_in = null logged_in = null
if (href_list["buyshares"]) if (href_list["buyshares"])
var/datum/stock/S = locate(href_list["buyshares"]) var/datum/stock/S = locate(href_list["buyshares"]) in stockExchange.stocks
if (S) if (S)
buy_some_shares(S, usr) buy_some_shares(S, usr)
if (href_list["sellshares"]) if (href_list["sellshares"])
var/datum/stock/S = locate(href_list["sellshares"]) var/datum/stock/S = locate(href_list["sellshares"]) in stockExchange.stocks
if (S) if (S)
sell_some_shares(S, usr) sell_some_shares(S, usr)
if (href_list["take"])
var/datum/borrow/B = locate(href_list["take"])
if (B && !B.lease_expires)
do_borrowing_deal(B, usr)
if (href_list["show_logs"]) if (href_list["show_logs"])
var/dat = "<html><head><title>Stock Transaction Logs</title></head><body><h2>Stock Transaction Logs</h2><div><a href='?src=\ref[src];show_logs=1'>Refresh</a></div><br>" var/dat = "<html><head><title>Stock Transaction Logs</title></head><body><h2>Stock Transaction Logs</h2><div><a href='?src=\ref[src];show_logs=1'>Refresh</a></div><br>"
for(var/D in stockExchange.logs) for(var/D in stockExchange.logs)