From 48c002b36165148cdb84e151bd726d7fd5cd77f6 Mon Sep 17 00:00:00 2001 From: Tayyyyyyy Date: Sun, 11 Aug 2019 19:15:54 -0700 Subject: [PATCH 1/3] Add admin pencode: style, class, and img --- code/__HELPERS/text.dm | 29 +++++++++++++++++++++++++ code/modules/admin/admin_verbs.dm | 2 +- code/modules/admin/topic.dm | 2 +- code/modules/admin/verbs/adminpm.dm | 2 +- code/modules/admin/verbs/randomverbs.dm | 5 ++++- 5 files changed, 36 insertions(+), 4 deletions(-) diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index 04d63e0e862..e97fb5729ea 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -545,6 +545,35 @@ proc/checkhtml(var/t) text = copytext(text, 1, MAX_PAPER_MESSAGE_LEN) return text +/proc/convert_pencode_arg(text, tag, arg) + arg = replacetext(replacetext(html_encode(arg), "'", ""), "\"", "") + if(tag == "class") + return "" + + if(tag == "style") + return "" + + if(tag == "img") + var/list/img_props = splittext(arg, ";") + if(img_props.len == 3) + return "" + if(img_props.len == 2) + return "" + return "" + + return text + +/proc/admin_pencode_to_html() + var/text = pencode_to_html(arglist(args)) + var/regex/R = new(@"\[(.*?) (.*?)\]", "ge") + text = R.Replace(text, /proc/convert_pencode_arg) + + text = replacetext(text, "\[/class\]", "") + text = replacetext(text, "\[/style\]", "") + text = replacetext(text, "\[/img\]", "") + + return text + /proc/html_to_pencode(text) text = replacetext(text, "
", "\n") text = replacetext(text, "
", "\[center\]") diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 3b282fa6893..8201a7cc303 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -642,7 +642,7 @@ var/list/admin_verbs_ticket = list( if(!message) return for(var/mob/V in hearers(O)) - V.show_message(message, 2) + V.show_message(admin_pencode_to_html(message), 2) log_admin("[key_name(usr)] made [O] at [O.x], [O.y], [O.z] make a sound") message_admins("[key_name_admin(usr)] made [O] at [O.x], [O.y], [O.z] make a sound") feedback_add_details("admin_verb","MS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index ebe2219d90b..69f9813627f 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -2181,7 +2181,7 @@ if(!input) qdel(P) return - input = P.parsepencode(input) // Encode everything from pencode to html + input = admin_pencode_to_html(html_encode(input)) // Encode everything from pencode to html var/customname = clean_input("Pick a title for the fax.", "Fax Title", , owner) if(!customname) diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm index 1d35a621217..126b1d14d14 100644 --- a/code/modules/admin/verbs/adminpm.dm +++ b/code/modules/admin/verbs/adminpm.dm @@ -110,7 +110,7 @@ if(!msg) return else - msg = pencode_to_html(msg) + msg = admin_pencode_to_html(msg) var/recieve_span = "playerreply" var/send_pm_type = " " diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 6a4d1e8dc18..7484850f5e2 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -58,6 +58,9 @@ if(!msg) return + + msg = admin_pencode_to_html(msg) + if(usr) if(usr.client) if(usr.client.holder) @@ -136,7 +139,7 @@ if( !msg ) return - msg = pencode_to_html(msg) + msg = admin_pencode_to_html(msg) to_chat(M, msg) log_admin("DirectNarrate: [key_name(usr)] to ([key_name(M)]): [msg]") From 6c6ef64ccb5db53ba79938afc357ca882ef60fa1 Mon Sep 17 00:00:00 2001 From: Tayyyyyyy Date: Mon, 12 Aug 2019 21:51:07 -0700 Subject: [PATCH 2/3] Make img a bit more secure --- code/__HELPERS/text.dm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index e97fb5729ea..07f65b412ea 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -546,7 +546,8 @@ proc/checkhtml(var/t) return text /proc/convert_pencode_arg(text, tag, arg) - arg = replacetext(replacetext(html_encode(arg), "'", ""), "\"", "") + arg = sanitize_simple(html_encode(arg), list("''"="","\""="", "?"="")) + if(tag == "class") return "" @@ -554,6 +555,8 @@ proc/checkhtml(var/t) return "" if(tag == "img") + if(dd_hasprefix(arg, "byond:") || dd_hasprefix(arg, "file:")) + return text var/list/img_props = splittext(arg, ";") if(img_props.len == 3) return "" From ff44a27ef69ab7cf3cb942073a9249c754e50728 Mon Sep 17 00:00:00 2001 From: Tayyyyyyy Date: Wed, 14 Aug 2019 18:25:21 -0700 Subject: [PATCH 3/3] Secure style attribute from XSS --- code/__HELPERS/text.dm | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index 07f65b412ea..08af11a128c 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -547,6 +547,13 @@ proc/checkhtml(var/t) /proc/convert_pencode_arg(text, tag, arg) arg = sanitize_simple(html_encode(arg), list("''"="","\""="", "?"="")) + // https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html#rule-4---css-escape-and-strictly-validate-before-inserting-untrusted-data-into-html-style-property-values + var/list/style_attacks = list("javascript:", "expression", "byond:", "file:") + + for(var/style_attack in style_attacks) + if(findtext(arg, style_attack)) + // Do not attempt to render dangerous things + return text if(tag == "class") return "" @@ -555,8 +562,6 @@ proc/checkhtml(var/t) return "" if(tag == "img") - if(dd_hasprefix(arg, "byond:") || dd_hasprefix(arg, "file:")) - return text var/list/img_props = splittext(arg, ";") if(img_props.len == 3) return ""