Fix(chore): security hardening#55
Merged
Merged
Conversation
…URLs Add Corex.Url.allowed_href?/1 mirroring client redirect validation, use it in navigate and pagination link mode, and validate upload_field before cancel_upload.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Addresses findings from the Corex security audit across client hooks, Mix generators, the installer, components, MCP configuration, and release hygiene. Each area is a separate commit for review.
This PR is independent of #54 (
fix/mcp-security-hardening), which hardens the MCP transport itself (Tidewave alignment, relative paths, prod guard, tool validation). This branch adds configurable MCP error redaction and remote-access warnings on top of the existing plug behavior.Motivation
A full-library review identified trust-boundary gaps: DOM events treated like server payloads, generator path traversal, EEx re-evaluation on inject, installer string injection, CSS breakout in inline styles, open redirect patterns in links/pagination, and verbose MCP errors leaking stack traces to clients.
Commits
fix(toast): ignore labelHtml and execJs from untrusted DOM eventsfix(mix): contain corex.code output paths within project rootassert_within_project_root!/1for generated file pathsfix(mix): validate generator flags and migration_dirvalidate_identifier!/1,validate_migration_dir!/1, schema validationfix(mix): stop EEx re-eval in inject_eex_before_final_endEEx.eval_stringon target filesfix(installer): harden --dev path and COREX_NEW_CACHE_DIR copyFile.cp_r!/2per entry for cache copyfix(installer): validate web_module like root modulecorex.newfix(color-picker): reject CSS breakout in inline style values--value/ presetsfix(components): harden file upload cancel, navigate, and pagination URLsCorex.Url.allowed_href?/1(viaURI.parse/1); safe cancel helperchore: re-enable sobelow checks and add hex.audit to release.checkRCE.EEx/Traversal.FileModuleignores; scoped file ignoresdev(mix): add sponsor linkfix(mcp): redact tool errors by default and warn on remote accessmcp_verbose_errors, gated debug logging, init warning for remote accessChanges by area
Toast (F1)
assets/hooks/toast.ts:parseServerActionSpecvsparseDomActionSpec; DOMtoast:create/toast:updateignorelabelHtmlandexecJsassets/test/hooks/toast.test.tsMix generators and
corex.code(F3, F4, F7)lib/mix/corex.ex:project_root/0,assert_within_project_root!/1,validate_identifier!/1,validate_migration_dir!/1lib/mix/tasks/corex.code.ex: path containment before writelib/mix/tasks/corex.gen.html.ex,lib/mix/tasks/corex.gen.live.ex,lib/mix/corex/gen/context.ex: flag validation wired ininject_eex_before_final_end/3: no EEx re-eval of existing target file contenttest/mix/tasks/corex.code_test.exs,test/mix/corex_test.exs,test/mix/tasks/corex.gen.html_test.exs,test/mix/corex/gen/context_test.exsInstaller (F2, F5, F6, F16)
installer/lib/corex_new/patches.ex:inspect/1for--devpath in deps; validate before writeinstaller/lib/corex_new/post_generate.ex: validateCOREX_NEW_CACHE_DIR; copy withFile.cp_r!/2per entryinstaller/templates/corex/assets/js/app.js.eex: safe import viainspect(@corex_js_import)installer/lib/mix/tasks/corex.new.ex:web_modulevalidity and availability checksinstaller/test/core_new_test.exs,installer/test/post_generate_test.exsColor picker (F8)
lib/components/color_picker/initial.ex: removed CSS passthrough inmaybe_css_color/1lib/components/color_picker.ex: inline--valueand presets use parsed RGBA onlytest/components/color_picker_test.exsComponents (F12, F13)
lib/corex/url.ex:allowed_href?/1mirrors clientassets/lib/redirect.tspolicy usingURI.parse/1lib/components/navigate.ex: omit disallowedtovalues (with warning)lib/components/pagination/utils.ex:page_href/5returnsnilfor bad baseslib/components/file_upload_live.ex:cancel_upload_from_params/3whitelistsupload_fieldtest/corex/url_test.exs, navigate/pagination/file_upload_live testsMCP (F9, F10, F11)
lib/mcp/server.ex: generic tool failure text by default; full exceptions in logs; JSON-RPC detail logging gated onconfig :corex, debug: truelib/mcp/plug.ex:verbose_errorsin plug config; warning at init whenallow_remote_access: trueconfig/config.exs:config :corex, mcp_verbose_errors: falseguides/MCP.md: Security sectiontest/corex/mcp/server_test.exs,test/corex/mcp/plug_test.exsHygiene (F15)
.sobelow-conf: re-enableTraversal.FileModuleandRCE.EExglobally;ignore_filesonly for generator/doc tooling pathsmix.exs:release.checkrunshex.auditbeforelintRelationship to PR #54
source_path, prod guard, tool arg validationmcp_verbose_errors)Recommended merge order: land #54 first, then rebase this branch and resolve any overlap in
lib/mcp/plug.ex,lib/mcp/server.ex, andguides/MCP.md.Test plan
mix testmix lintmix release.check(includeshex.audit)cd e2e && mix test(POST/PUT controller and form tests; MCP e2e)cd integration_test && mix test --include databasenpm testinassets/(toast hook tests)javascript:URLsmcp_verbose_errors: trueBreaking changes
None for normal app usage. Generator operators passing invalid
--migration-diror schema names now get explicit errors instead of silent bad output.