Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions code/datums/diseases/viruses/_virus.dm
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,8 @@
if(spread_flags & AIRBORNE)
spread += "Воздушно-капельный"
return russian_list(spread, "Неизвестено", " и ")

//List of viruses that cannot be vaccinated against using PANDEMIC. For game balance, some viruses are not intended to be preventable with a simple vaccine.
GLOBAL_LIST_INIT(no_vaccine_viruses, list(
/datum/disease/virus/loyalty = TRUE,
))
6 changes: 3 additions & 3 deletions code/datums/diseases/viruses/loyalty_syndrome.dm
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@
desc = "Болезнь, вызывающая острую массовую одержимость определённым человеком, а также различные навязчивые идеи."
spread_flags = CONTACT
permeability_mod = 0.8
can_immunity = FALSE
cure_text = "Галоперидол"
cures = list("haloperidol")
cure_text = "Галоперидол и Эфир"
cures = list("haloperidol", "ether")
visibility_flags = HIDDEN_HUD
severity = DISEASE_SEVERITY_BIOHAZARD
var/is_master = FALSE
Expand Down Expand Up @@ -164,4 +163,5 @@
need_master_death_message = FALSE
affected_mob.adjustBrainLoss(50)
addtimer(CALLBACK(affected_mob, TYPE_PROC_REF(/mob/living/carbon/human, emote), "cry"), rand(3, 10) SECONDS)

#undef STAGE_TIME
31 changes: 20 additions & 11 deletions code/modules/reagents/chemistry/machinery/pandemic.dm
Original file line number Diff line number Diff line change
Expand Up @@ -85,23 +85,27 @@
if(B)
B.pixel_x = rand(-3, 3)
B.pixel_y = rand(-3, 3)
var/path = GetResistancesByIndex(text2num(href_list["create_vaccine"]))
var/vaccine_type = path

var/vaccine_type = text2path(href_list["create_vaccine"])

if(vaccine_type in GLOB.no_vaccine_viruses)
to_chat(usr, span_warning("К этому вирусу нельзя создать вакцину."))
return

var/vaccine_name = UNKNOWN_STATUS_RUS

if(!ispath(vaccine_type))
if(GLOB.archive_diseases[path])
var/datum/disease/disease = GLOB.archive_diseases[path]
if(GLOB.archive_diseases[vaccine_type])
var/datum/disease/disease = GLOB.archive_diseases[vaccine_type]
if(disease)
vaccine_name = disease.name
vaccine_type = path
vaccine_type = vaccine_type
else if(vaccine_type)
var/datum/disease/disease = new vaccine_type
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

This section introduces a critical security vulnerability. The use of text2path on raw user input from href_list["create_vaccine"] followed by instantiation with new allows for arbitrary object instantiation. An attacker can craft a request with a path to any object (e.g., /obj/item/gun/energy/laser), bypassing the machine's intended logic and the requirement for a valid blood sample to create vaccines.

Beyond the security concern, the logic for accessing the disease archive (GLOB.archive_diseases) and subsequent checks are incorrect and redundant. After href_list["create_vaccine"] is changed to pass a string path type, vaccine_type will either be a valid type-path or null. The current if(!ispath(vaccine_type)) check only triggers if vaccine_type is null, which would cause an error when GLOB.archive_diseases[vaccine_type] attempts to use null as a key. Additionally, GLOB.archive_diseases is likely indexed by string identifiers (e.g., disease.GetDiseaseID()), not type-paths directly, requiring vaccine_type.type for correct access.

To remediate the security vulnerability, you should:

  1. Verify that the requested vaccine_type is a subtype of /datum/disease using ispath(vaccine_type, /datum/disease).
  2. Ensure that the requested vaccine_type is actually present in the resistances list of the blood sample currently in the machine's beaker.

The provided code suggestion addresses the logical issues by simplifying checks and correctly using the string representation of the type-path for GLOB.archive_diseases access.

var/vaccine_name = UNKNOWN_STATUS_RUS
var/datum/disease/disease_instance

if(!vaccine_type) // Если text2path вернул null, значит, это невалидный путь
	to_chat(usr, span_warning("Неверный тип вакцины."))
	return

// Попытка найти болезнь в архиве по строковому представлению пути
if(GLOB.archive_diseases[vaccine_type.type])
	disease_instance = GLOB.archive_diseases[vaccine_type.type]
	if(disease_instance)
		vaccine_name = disease_instance.name
else // Если не найдено в архиве, создаем новый экземпляр из тип-пути
	disease_instance = new vaccine_type
	if(disease_instance)
		vaccine_name = disease_instance.name

if(disease)
vaccine_name = disease.name

if(vaccine_type)

B.name = "вакцина [capitalize(vaccine_name)]"
B.ru_names = list(
NOMINATIVE = "вакцина [capitalize(vaccine_name)]",
Expand All @@ -117,6 +121,7 @@
temp_html = "Репликатор ещё не готов."
updateUsrDialog()
return

else if(href_list["create_disease_culture"])
if(!wait)
var/datum/disease/disease = GetDiseaseByIndex(text2num(href_list["create_disease_culture"]))
Expand Down Expand Up @@ -314,11 +319,15 @@

if(Blood.data["resistances"])
var/list/res = Blood.data["resistances"]
if(length(res))
var/list/blood_data_resists_filtered = list()
// фильтруем вирусы, для которых нельзя сделать вакцину
for(var/resists_filter in res)
if(!(resists_filter in GLOB.no_vaccine_viruses))
blood_data_resists_filtered += resists_filter

if(length(blood_data_resists_filtered))
dat += "<br><b>Содержит антитела к:</b><ul>"
var/i = 0
for(var/type in Blood.data["resistances"])
i++
for(var/type in blood_data_resists_filtered)
var/disease_name = UNKNOWN_STATUS_RUS

if(!ispath(type))
Expand All @@ -329,7 +338,7 @@
var/datum/disease/disease = new type()
disease_name = disease.name

dat += "<li>[disease_name] - <a href='byond://?src=[UID()];create_vaccine=[i]'>Создать бутылка с вакциной</a></li>"
dat += "<li>[disease_name] - <a href='byond://?src=[UID()];create_vaccine=[type]'>Создать бутылка с вакциной</a></li>"
dat += "</ul><br>"
else
dat += "<br><b>Не содержит антител</b><br>"
Expand Down
Loading