Merge pull request #11869 from alexrford/rails/render_locals_shared

Ruby: Rails - generalize rails flow step for accessing render locals hash in view
This commit is contained in:
Alex Ford
2023-01-25 12:07:26 +00:00
committed by GitHub
8 changed files with 224 additions and 138 deletions

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Data flowing from the `locals` argument of a Rails `render` call is now tracked to uses of that data in an associated view.

View File

@@ -30,6 +30,8 @@ module SummaryComponent {
predicate withContent = SC::withContent/1;
class SyntheticGlobal = SC::SyntheticGlobal;
/** Gets a summary component that represents a receiver. */
SummaryComponent receiver() { result = argument(any(ParameterPosition pos | pos.isSelf())) }

View File

@@ -10,6 +10,43 @@ private import codeql.ruby.frameworks.ActiveStorage
private import codeql.ruby.frameworks.internal.Rails
private import codeql.ruby.ApiGraphs
private import codeql.ruby.security.OpenSSL
private import codeql.ruby.dataflow.FlowSummary
/** Provides utility predicates for extracting information from calls to `render`. */
private module RenderCallUtils {
private Expr getTemplatePathArgument(MethodCall renderCall) {
// TODO: support other ways of specifying paths (e.g. `file`)
result =
[renderCall.getKeywordArgument(["partial", "template", "action"]), renderCall.getArgument(0)]
}
private string getTemplatePathValue(MethodCall renderCall) {
result = getTemplatePathArgument(renderCall).getConstantValue().getStringlikeValue()
}
// everything up to and including the final slash, but ignoring any leading slash
private string getSubPath(MethodCall renderCall) {
result = getTemplatePathValue(renderCall).regexpCapture("^/?(.*/)?(?:[^/]*?)$", 1)
}
// everything after the final slash, or the whole string if there is no slash
private string getBaseName(MethodCall renderCall) {
result = getTemplatePathValue(renderCall).regexpCapture("^/?(?:.*/)?([^/]*?)$", 1)
}
/**
* Gets the template file to be rendered by this render call, if any.
*/
ErbFile getTemplateFile(MethodCall renderCall) {
result.getTemplateName() = getBaseName(renderCall) and
result.getRelativePath().matches("%app/views/" + getSubPath(renderCall) + "%")
}
/**
* Gets the local variables passed as context to the renderer.
*/
HashLiteral getLocals(MethodCall renderCall) { result = renderCall.getKeywordArgument("locals") }
}
/**
* Provides classes for working with Rails.
@@ -38,37 +75,15 @@ module Rails {
* rendered content.
*/
class RenderCall extends MethodCall instanceof RenderCallImpl {
private Expr getTemplatePathArgument() {
// TODO: support other ways of specifying paths (e.g. `file`)
result = [this.getKeywordArgument(["partial", "template", "action"]), this.getArgument(0)]
}
private string getTemplatePathValue() {
result = this.getTemplatePathArgument().getConstantValue().getStringlikeValue()
}
// everything up to and including the final slash, but ignoring any leading slash
private string getSubPath() {
result = this.getTemplatePathValue().regexpCapture("^/?(.*/)?(?:[^/]*?)$", 1)
}
// everything after the final slash, or the whole string if there is no slash
private string getBaseName() {
result = this.getTemplatePathValue().regexpCapture("^/?(?:.*/)?([^/]*?)$", 1)
}
/**
* Gets the template file to be rendered by this call, if any.
*/
ErbFile getTemplateFile() {
result.getTemplateName() = this.getBaseName() and
result.getRelativePath().matches("%app/views/" + this.getSubPath() + "%")
}
ErbFile getTemplateFile() { result = RenderCallUtils::getTemplateFile(this) }
/**
* Get the local variables passed as context to the renderer
* Gets the local variables passed as context to the renderer.
*/
HashLiteral getLocals() { result = this.getKeywordArgument("locals") }
HashLiteral getLocals() { result = RenderCallUtils::getLocals(this) }
// TODO: implicit renders in controller actions
}
@@ -287,5 +302,92 @@ private class CookiesSameSiteProtectionSetting extends Settings::NillableStringl
result = "Unsetting 'SameSite' can disable same-site cookie restrictions in some browsers."
}
}
// TODO: initialization hooks, e.g. before_configuration, after_initialize...
// TODO: initializers
/** A synthetic global to represent the value passed to the `locals` argument of a render call for a specific ERB file. */
private class LocalAssignsHashSyntheticGlobal extends SummaryComponent::SyntheticGlobal {
private ErbFile erbFile;
private string id;
// Note that we can't use an actual `Rails::RenderCall` here due to problems with non-monotonic recursion
private MethodCall renderCall;
LocalAssignsHashSyntheticGlobal() {
this = "LocalAssignsHashSyntheticGlobal+" + id and
id = erbFile.getRelativePath() + "+" + renderCall.getLocation() and
renderCall.getMethodName() = "render" and
RenderCallUtils::getTemplateFile(renderCall) = erbFile
}
/** Gets the `ErbFile` which this locals hash is accessible from. */
ErbFile getErbFile() { result = erbFile }
/** Gets the identifier for this particular locals hash synthetic global. */
string getId() { result = id }
/** Gets a call to render that can write to this hash. */
Rails::RenderCall getARenderCall() { result = renderCall }
}
/** A summary for `render` calls linked to some specific ERB file. */
private class RenderLocalsSummary extends SummarizedCallable {
private LocalAssignsHashSyntheticGlobal glob;
RenderLocalsSummary() { this = "rails_render_locals()" + glob.getId() }
override Rails::RenderCall getACall() { result = glob.getARenderCall() }
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
input = "Argument[locals:]" and
output = "SyntheticGlobal[" + glob + "]" and
preservesValue = true
}
}
/** A summary for calls to `local_assigns` in a view to access a `render` call `locals` hash. */
private class AccessLocalsSummary extends SummarizedCallable {
private LocalAssignsHashSyntheticGlobal glob;
AccessLocalsSummary() { this = "rails_local_assigns()" + glob.getId() }
override MethodCall getACall() {
glob.getErbFile() = result.getLocation().getFile() and
result.getMethodName() = "local_assigns"
}
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
input = "SyntheticGlobal[" + glob + "]" and
output = "ReturnValue" and
preservesValue = true
}
}
private string getAMethodNameFromErbFile(ErbFile f) {
result = any(MethodCall c | c.getLocation().getFile() = f).getMethodName()
}
private class AccessLocalsKeySummary extends SummarizedCallable {
private LocalAssignsHashSyntheticGlobal glob;
private string methodName;
AccessLocalsKeySummary() {
this = "rails_locals_key()" + glob.getId() + "#" + methodName and
methodName = getAMethodNameFromErbFile(glob.getErbFile()) and
// Limit method calls to those that could plausibly be a key in a `locals` hash argument
// TODO: this could be more precise but for problems using the dataflow library in this context
methodName =
any(HashLiteral l).getAKeyValuePair().getKey().getConstantValue().getStringlikeValue()
}
override MethodCall getACall() {
result.getLocation().getFile() = glob.getErbFile() and
result.getMethodName() = methodName and
result.getReceiver() instanceof SelfVariableReadAccess
}
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
input = "SyntheticGlobal[" + glob + "].Element[:" + methodName + "]" and
output = "ReturnValue" and
preservesValue = true
}
}

View File

@@ -162,46 +162,6 @@ private module Shared {
erb = call.getLocation().getFile()
}
/**
* Holds if some render call passes `value` for `hashKey` in the `locals`
* argument, in ERB file `erb`.
*/
pragma[noinline]
private predicate renderCallLocals(string hashKey, Expr value, ErbFile erb) {
exists(Rails::RenderCall call, Pair kvPair |
call.getLocals().getAKeyValuePair() = kvPair and
kvPair.getValue() = value and
kvPair.getKey().getConstantValue().isStringlikeValue(hashKey) and
call.getTemplateFile() = erb
)
}
pragma[noinline]
private predicate isFlowFromLocals0(
CfgNodes::ExprNodes::ElementReferenceCfgNode refNode, string hashKey, ErbFile erb
) {
exists(DataFlow::Node argNode |
argNode.asExpr() = refNode.getArgument(0) and
refNode.getReceiver().getExpr().(MethodCall).getMethodName() = "local_assigns" and
argNode.getALocalSource().getConstantValue().isStringlikeValue(hashKey) and
erb = refNode.getFile()
)
}
private predicate isFlowFromLocals(DataFlow::Node node1, DataFlow::Node node2) {
exists(string hashKey, ErbFile erb |
// node1 is a `locals` argument to a render call...
renderCallLocals(hashKey, node1.asExpr().getExpr(), erb)
|
// node2 is an element reference against `local_assigns`
isFlowFromLocals0(node2.asExpr(), hashKey, erb)
or
// ...node2 is a "method call" to a "method" with `hashKey` as its name
// TODO: This may be a variable read in reality that we interpret as a method call
isMethodCall(node2.asExpr().getExpr(), hashKey, erb)
)
}
/**
* Holds if `action` contains an assignment of `value` to an instance
* variable named `name`, in ERB file `erb`.
@@ -275,8 +235,6 @@ private module Shared {
* An additional step that is preserves dataflow in the context of XSS.
*/
predicate isAdditionalXssFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
isFlowFromLocals(node1, node2)
or
isFlowFromControllerInstanceVariable(node1, node2)
or
isFlowIntoHelperMethod(node1, node2)

View File

@@ -1,33 +1,38 @@
edges
| app/controllers/foo/bars_controller.rb:9:12:9:17 | call to params : | app/controllers/foo/bars_controller.rb:9:12:9:29 | ...[...] : |
| app/controllers/foo/bars_controller.rb:9:12:9:29 | ...[...] : | app/views/foo/bars/show.html.erb:47:5:47:13 | call to user_name |
| app/controllers/foo/bars_controller.rb:9:12:9:29 | ...[...] : | app/views/foo/bars/show.html.erb:46:5:46:13 | call to user_name |
| app/controllers/foo/bars_controller.rb:13:5:13:14 | [post] self [@user_name] : | app/controllers/foo/bars_controller.rb:13:5:13:14 | [post] self [@user_name] : |
| app/controllers/foo/bars_controller.rb:13:5:13:14 | [post] self [@user_name] : | app/views/foo/bars/show.html.erb:51:5:51:18 | call to user_name_memo |
| app/controllers/foo/bars_controller.rb:13:5:13:14 | [post] self [@user_name] : | app/views/foo/bars/show.html.erb:50:5:50:18 | call to user_name_memo |
| app/controllers/foo/bars_controller.rb:13:20:13:25 | call to params : | app/controllers/foo/bars_controller.rb:13:20:13:37 | ...[...] : |
| app/controllers/foo/bars_controller.rb:13:20:13:37 | ...[...] : | app/controllers/foo/bars_controller.rb:13:5:13:14 | [post] self [@user_name] : |
| app/controllers/foo/bars_controller.rb:13:20:13:37 | ...[...] : | app/views/foo/bars/show.html.erb:51:5:51:18 | call to user_name_memo |
| app/controllers/foo/bars_controller.rb:13:20:13:37 | ...[...] : | app/views/foo/bars/show.html.erb:50:5:50:18 | call to user_name_memo |
| app/controllers/foo/bars_controller.rb:17:21:17:26 | call to params : | app/controllers/foo/bars_controller.rb:17:21:17:36 | ...[...] : |
| app/controllers/foo/bars_controller.rb:17:21:17:36 | ...[...] : | app/views/foo/bars/show.html.erb:2:18:2:30 | @user_website |
| app/controllers/foo/bars_controller.rb:18:10:18:15 | call to params : | app/controllers/foo/bars_controller.rb:18:10:18:22 | ...[...] : |
| app/controllers/foo/bars_controller.rb:18:10:18:22 | ...[...] : | app/controllers/foo/bars_controller.rb:19:22:19:23 | dt : |
| app/controllers/foo/bars_controller.rb:18:10:18:22 | ...[...] : | app/controllers/foo/bars_controller.rb:26:53:26:54 | dt : |
| app/controllers/foo/bars_controller.rb:19:22:19:23 | dt : | app/views/foo/bars/show.html.erb:41:3:41:16 | @instance_text |
| app/controllers/foo/bars_controller.rb:19:22:19:23 | dt : | app/views/foo/bars/show.html.erb:40:3:40:16 | @instance_text |
| app/controllers/foo/bars_controller.rb:24:39:24:44 | call to params : | app/controllers/foo/bars_controller.rb:24:39:24:59 | ...[...] : |
| app/controllers/foo/bars_controller.rb:24:39:24:59 | ...[...] : | app/controllers/foo/bars_controller.rb:24:39:24:59 | ... = ... |
| app/controllers/foo/bars_controller.rb:26:53:26:54 | dt : | app/views/foo/bars/show.html.erb:5:9:5:20 | call to display_text |
| app/controllers/foo/bars_controller.rb:26:53:26:54 | dt : | app/views/foo/bars/show.html.erb:8:9:8:36 | ...[...] |
| app/controllers/foo/bars_controller.rb:26:53:26:54 | dt : | app/views/foo/bars/show.html.erb:12:9:12:26 | ...[...] |
| app/controllers/foo/bars_controller.rb:26:53:26:54 | dt : | app/views/foo/bars/show.html.erb:36:3:36:14 | call to display_text |
| app/controllers/foo/bars_controller.rb:26:53:26:54 | dt : | app/views/foo/bars/show.html.erb:44:76:44:87 | call to display_text : |
| app/controllers/foo/bars_controller.rb:26:53:26:54 | dt : | app/views/foo/bars/show.html.erb:8:9:8:21 | call to local_assigns [element :display_text] : |
| app/controllers/foo/bars_controller.rb:26:53:26:54 | dt : | app/views/foo/bars/show.html.erb:12:9:12:21 | call to local_assigns [element :display_text] : |
| app/controllers/foo/bars_controller.rb:26:53:26:54 | dt : | app/views/foo/bars/show.html.erb:17:15:17:27 | call to local_assigns [element :display_text] : |
| app/controllers/foo/bars_controller.rb:26:53:26:54 | dt : | app/views/foo/bars/show.html.erb:35:3:35:14 | call to display_text |
| app/controllers/foo/bars_controller.rb:26:53:26:54 | dt : | app/views/foo/bars/show.html.erb:43:76:43:87 | call to display_text : |
| app/controllers/foo/bars_controller.rb:30:11:30:16 | call to params : | app/controllers/foo/bars_controller.rb:30:11:30:28 | ...[...] : |
| app/controllers/foo/bars_controller.rb:30:11:30:28 | ...[...] : | app/controllers/foo/bars_controller.rb:31:5:31:7 | str |
| app/views/foo/bars/show.html.erb:44:64:44:87 | ... + ... : | app/views/foo/bars/_widget.html.erb:5:9:5:20 | call to display_text |
| app/views/foo/bars/show.html.erb:44:64:44:87 | ... + ... : | app/views/foo/bars/_widget.html.erb:8:9:8:36 | ...[...] |
| app/views/foo/bars/show.html.erb:44:76:44:87 | call to display_text : | app/views/foo/bars/show.html.erb:44:64:44:87 | ... + ... : |
| app/views/foo/bars/show.html.erb:54:29:54:34 | call to params : | app/views/foo/bars/show.html.erb:54:29:54:44 | ...[...] |
| app/views/foo/bars/show.html.erb:57:13:57:18 | call to params : | app/views/foo/bars/show.html.erb:57:13:57:28 | ...[...] |
| app/views/foo/bars/show.html.erb:74:19:74:24 | call to params : | app/views/foo/bars/show.html.erb:74:19:74:34 | ...[...] |
| app/views/foo/bars/show.html.erb:77:28:77:33 | call to params : | app/views/foo/bars/show.html.erb:77:28:77:39 | ...[...] |
| app/views/foo/bars/_widget.html.erb:8:9:8:21 | call to local_assigns [element :display_text] : | app/views/foo/bars/_widget.html.erb:8:9:8:36 | ...[...] |
| app/views/foo/bars/show.html.erb:8:9:8:21 | call to local_assigns [element :display_text] : | app/views/foo/bars/show.html.erb:8:9:8:36 | ...[...] |
| app/views/foo/bars/show.html.erb:12:9:12:21 | call to local_assigns [element :display_text] : | app/views/foo/bars/show.html.erb:12:9:12:26 | ...[...] |
| app/views/foo/bars/show.html.erb:17:15:17:27 | call to local_assigns [element :display_text] : | app/views/foo/bars/show.html.erb:17:15:17:32 | ...[...] |
| app/views/foo/bars/show.html.erb:43:64:43:87 | ... + ... : | app/views/foo/bars/_widget.html.erb:5:9:5:20 | call to display_text |
| app/views/foo/bars/show.html.erb:43:64:43:87 | ... + ... : | app/views/foo/bars/_widget.html.erb:8:9:8:21 | call to local_assigns [element :display_text] : |
| app/views/foo/bars/show.html.erb:43:76:43:87 | call to display_text : | app/views/foo/bars/show.html.erb:43:64:43:87 | ... + ... : |
| app/views/foo/bars/show.html.erb:53:29:53:34 | call to params : | app/views/foo/bars/show.html.erb:53:29:53:44 | ...[...] |
| app/views/foo/bars/show.html.erb:56:13:56:18 | call to params : | app/views/foo/bars/show.html.erb:56:13:56:28 | ...[...] |
| app/views/foo/bars/show.html.erb:73:19:73:24 | call to params : | app/views/foo/bars/show.html.erb:73:19:73:34 | ...[...] |
| app/views/foo/bars/show.html.erb:76:28:76:33 | call to params : | app/views/foo/bars/show.html.erb:76:28:76:39 | ...[...] |
nodes
| app/controllers/foo/bars_controller.rb:9:12:9:17 | call to params : | semmle.label | call to params : |
| app/controllers/foo/bars_controller.rb:9:12:9:29 | ...[...] : | semmle.label | ...[...] : |
@@ -47,25 +52,30 @@ nodes
| app/controllers/foo/bars_controller.rb:30:11:30:28 | ...[...] : | semmle.label | ...[...] : |
| app/controllers/foo/bars_controller.rb:31:5:31:7 | str | semmle.label | str |
| app/views/foo/bars/_widget.html.erb:5:9:5:20 | call to display_text | semmle.label | call to display_text |
| app/views/foo/bars/_widget.html.erb:8:9:8:21 | call to local_assigns [element :display_text] : | semmle.label | call to local_assigns [element :display_text] : |
| app/views/foo/bars/_widget.html.erb:8:9:8:36 | ...[...] | semmle.label | ...[...] |
| app/views/foo/bars/show.html.erb:2:18:2:30 | @user_website | semmle.label | @user_website |
| app/views/foo/bars/show.html.erb:5:9:5:20 | call to display_text | semmle.label | call to display_text |
| app/views/foo/bars/show.html.erb:8:9:8:21 | call to local_assigns [element :display_text] : | semmle.label | call to local_assigns [element :display_text] : |
| app/views/foo/bars/show.html.erb:8:9:8:36 | ...[...] | semmle.label | ...[...] |
| app/views/foo/bars/show.html.erb:12:9:12:21 | call to local_assigns [element :display_text] : | semmle.label | call to local_assigns [element :display_text] : |
| app/views/foo/bars/show.html.erb:12:9:12:26 | ...[...] | semmle.label | ...[...] |
| app/views/foo/bars/show.html.erb:36:3:36:14 | call to display_text | semmle.label | call to display_text |
| app/views/foo/bars/show.html.erb:41:3:41:16 | @instance_text | semmle.label | @instance_text |
| app/views/foo/bars/show.html.erb:44:64:44:87 | ... + ... : | semmle.label | ... + ... : |
| app/views/foo/bars/show.html.erb:44:76:44:87 | call to display_text : | semmle.label | call to display_text : |
| app/views/foo/bars/show.html.erb:47:5:47:13 | call to user_name | semmle.label | call to user_name |
| app/views/foo/bars/show.html.erb:51:5:51:18 | call to user_name_memo | semmle.label | call to user_name_memo |
| app/views/foo/bars/show.html.erb:54:29:54:34 | call to params : | semmle.label | call to params : |
| app/views/foo/bars/show.html.erb:54:29:54:44 | ...[...] | semmle.label | ...[...] |
| app/views/foo/bars/show.html.erb:57:13:57:18 | call to params : | semmle.label | call to params : |
| app/views/foo/bars/show.html.erb:57:13:57:28 | ...[...] | semmle.label | ...[...] |
| app/views/foo/bars/show.html.erb:74:19:74:24 | call to params : | semmle.label | call to params : |
| app/views/foo/bars/show.html.erb:74:19:74:34 | ...[...] | semmle.label | ...[...] |
| app/views/foo/bars/show.html.erb:77:28:77:33 | call to params : | semmle.label | call to params : |
| app/views/foo/bars/show.html.erb:77:28:77:39 | ...[...] | semmle.label | ...[...] |
| app/views/foo/bars/show.html.erb:17:15:17:27 | call to local_assigns [element :display_text] : | semmle.label | call to local_assigns [element :display_text] : |
| app/views/foo/bars/show.html.erb:17:15:17:32 | ...[...] | semmle.label | ...[...] |
| app/views/foo/bars/show.html.erb:35:3:35:14 | call to display_text | semmle.label | call to display_text |
| app/views/foo/bars/show.html.erb:40:3:40:16 | @instance_text | semmle.label | @instance_text |
| app/views/foo/bars/show.html.erb:43:64:43:87 | ... + ... : | semmle.label | ... + ... : |
| app/views/foo/bars/show.html.erb:43:76:43:87 | call to display_text : | semmle.label | call to display_text : |
| app/views/foo/bars/show.html.erb:46:5:46:13 | call to user_name | semmle.label | call to user_name |
| app/views/foo/bars/show.html.erb:50:5:50:18 | call to user_name_memo | semmle.label | call to user_name_memo |
| app/views/foo/bars/show.html.erb:53:29:53:34 | call to params : | semmle.label | call to params : |
| app/views/foo/bars/show.html.erb:53:29:53:44 | ...[...] | semmle.label | ...[...] |
| app/views/foo/bars/show.html.erb:56:13:56:18 | call to params : | semmle.label | call to params : |
| app/views/foo/bars/show.html.erb:56:13:56:28 | ...[...] | semmle.label | ...[...] |
| app/views/foo/bars/show.html.erb:73:19:73:24 | call to params : | semmle.label | call to params : |
| app/views/foo/bars/show.html.erb:73:19:73:34 | ...[...] | semmle.label | ...[...] |
| app/views/foo/bars/show.html.erb:76:28:76:33 | call to params : | semmle.label | call to params : |
| app/views/foo/bars/show.html.erb:76:28:76:39 | ...[...] | semmle.label | ...[...] |
subpaths
#select
| app/controllers/foo/bars_controller.rb:24:39:24:59 | ... = ... | app/controllers/foo/bars_controller.rb:24:39:24:44 | call to params : | app/controllers/foo/bars_controller.rb:24:39:24:59 | ... = ... | Cross-site scripting vulnerability due to a $@. | app/controllers/foo/bars_controller.rb:24:39:24:44 | call to params | user-provided value |
@@ -76,11 +86,12 @@ subpaths
| app/views/foo/bars/show.html.erb:5:9:5:20 | call to display_text | app/controllers/foo/bars_controller.rb:18:10:18:15 | call to params : | app/views/foo/bars/show.html.erb:5:9:5:20 | call to display_text | Cross-site scripting vulnerability due to a $@. | app/controllers/foo/bars_controller.rb:18:10:18:15 | call to params | user-provided value |
| app/views/foo/bars/show.html.erb:8:9:8:36 | ...[...] | app/controllers/foo/bars_controller.rb:18:10:18:15 | call to params : | app/views/foo/bars/show.html.erb:8:9:8:36 | ...[...] | Cross-site scripting vulnerability due to a $@. | app/controllers/foo/bars_controller.rb:18:10:18:15 | call to params | user-provided value |
| app/views/foo/bars/show.html.erb:12:9:12:26 | ...[...] | app/controllers/foo/bars_controller.rb:18:10:18:15 | call to params : | app/views/foo/bars/show.html.erb:12:9:12:26 | ...[...] | Cross-site scripting vulnerability due to a $@. | app/controllers/foo/bars_controller.rb:18:10:18:15 | call to params | user-provided value |
| app/views/foo/bars/show.html.erb:36:3:36:14 | call to display_text | app/controllers/foo/bars_controller.rb:18:10:18:15 | call to params : | app/views/foo/bars/show.html.erb:36:3:36:14 | call to display_text | Cross-site scripting vulnerability due to a $@. | app/controllers/foo/bars_controller.rb:18:10:18:15 | call to params | user-provided value |
| app/views/foo/bars/show.html.erb:41:3:41:16 | @instance_text | app/controllers/foo/bars_controller.rb:18:10:18:15 | call to params : | app/views/foo/bars/show.html.erb:41:3:41:16 | @instance_text | Cross-site scripting vulnerability due to a $@. | app/controllers/foo/bars_controller.rb:18:10:18:15 | call to params | user-provided value |
| app/views/foo/bars/show.html.erb:47:5:47:13 | call to user_name | app/controllers/foo/bars_controller.rb:9:12:9:17 | call to params : | app/views/foo/bars/show.html.erb:47:5:47:13 | call to user_name | Cross-site scripting vulnerability due to a $@. | app/controllers/foo/bars_controller.rb:9:12:9:17 | call to params | user-provided value |
| app/views/foo/bars/show.html.erb:51:5:51:18 | call to user_name_memo | app/controllers/foo/bars_controller.rb:13:20:13:25 | call to params : | app/views/foo/bars/show.html.erb:51:5:51:18 | call to user_name_memo | Cross-site scripting vulnerability due to a $@. | app/controllers/foo/bars_controller.rb:13:20:13:25 | call to params | user-provided value |
| app/views/foo/bars/show.html.erb:54:29:54:44 | ...[...] | app/views/foo/bars/show.html.erb:54:29:54:34 | call to params : | app/views/foo/bars/show.html.erb:54:29:54:44 | ...[...] | Cross-site scripting vulnerability due to a $@. | app/views/foo/bars/show.html.erb:54:29:54:34 | call to params | user-provided value |
| app/views/foo/bars/show.html.erb:57:13:57:28 | ...[...] | app/views/foo/bars/show.html.erb:57:13:57:18 | call to params : | app/views/foo/bars/show.html.erb:57:13:57:28 | ...[...] | Cross-site scripting vulnerability due to a $@. | app/views/foo/bars/show.html.erb:57:13:57:18 | call to params | user-provided value |
| app/views/foo/bars/show.html.erb:74:19:74:34 | ...[...] | app/views/foo/bars/show.html.erb:74:19:74:24 | call to params : | app/views/foo/bars/show.html.erb:74:19:74:34 | ...[...] | Cross-site scripting vulnerability due to a $@. | app/views/foo/bars/show.html.erb:74:19:74:24 | call to params | user-provided value |
| app/views/foo/bars/show.html.erb:77:28:77:39 | ...[...] | app/views/foo/bars/show.html.erb:77:28:77:33 | call to params : | app/views/foo/bars/show.html.erb:77:28:77:39 | ...[...] | Cross-site scripting vulnerability due to a $@. | app/views/foo/bars/show.html.erb:77:28:77:33 | call to params | user-provided value |
| app/views/foo/bars/show.html.erb:17:15:17:32 | ...[...] | app/controllers/foo/bars_controller.rb:18:10:18:15 | call to params : | app/views/foo/bars/show.html.erb:17:15:17:32 | ...[...] | Cross-site scripting vulnerability due to a $@. | app/controllers/foo/bars_controller.rb:18:10:18:15 | call to params | user-provided value |
| app/views/foo/bars/show.html.erb:35:3:35:14 | call to display_text | app/controllers/foo/bars_controller.rb:18:10:18:15 | call to params : | app/views/foo/bars/show.html.erb:35:3:35:14 | call to display_text | Cross-site scripting vulnerability due to a $@. | app/controllers/foo/bars_controller.rb:18:10:18:15 | call to params | user-provided value |
| app/views/foo/bars/show.html.erb:40:3:40:16 | @instance_text | app/controllers/foo/bars_controller.rb:18:10:18:15 | call to params : | app/views/foo/bars/show.html.erb:40:3:40:16 | @instance_text | Cross-site scripting vulnerability due to a $@. | app/controllers/foo/bars_controller.rb:18:10:18:15 | call to params | user-provided value |
| app/views/foo/bars/show.html.erb:46:5:46:13 | call to user_name | app/controllers/foo/bars_controller.rb:9:12:9:17 | call to params : | app/views/foo/bars/show.html.erb:46:5:46:13 | call to user_name | Cross-site scripting vulnerability due to a $@. | app/controllers/foo/bars_controller.rb:9:12:9:17 | call to params | user-provided value |
| app/views/foo/bars/show.html.erb:50:5:50:18 | call to user_name_memo | app/controllers/foo/bars_controller.rb:13:20:13:25 | call to params : | app/views/foo/bars/show.html.erb:50:5:50:18 | call to user_name_memo | Cross-site scripting vulnerability due to a $@. | app/controllers/foo/bars_controller.rb:13:20:13:25 | call to params | user-provided value |
| app/views/foo/bars/show.html.erb:53:29:53:44 | ...[...] | app/views/foo/bars/show.html.erb:53:29:53:34 | call to params : | app/views/foo/bars/show.html.erb:53:29:53:44 | ...[...] | Cross-site scripting vulnerability due to a $@. | app/views/foo/bars/show.html.erb:53:29:53:34 | call to params | user-provided value |
| app/views/foo/bars/show.html.erb:56:13:56:28 | ...[...] | app/views/foo/bars/show.html.erb:56:13:56:18 | call to params : | app/views/foo/bars/show.html.erb:56:13:56:28 | ...[...] | Cross-site scripting vulnerability due to a $@. | app/views/foo/bars/show.html.erb:56:13:56:18 | call to params | user-provided value |
| app/views/foo/bars/show.html.erb:73:19:73:34 | ...[...] | app/views/foo/bars/show.html.erb:73:19:73:24 | call to params : | app/views/foo/bars/show.html.erb:73:19:73:34 | ...[...] | Cross-site scripting vulnerability due to a $@. | app/views/foo/bars/show.html.erb:73:19:73:24 | call to params | user-provided value |
| app/views/foo/bars/show.html.erb:76:28:76:39 | ...[...] | app/views/foo/bars/show.html.erb:76:28:76:33 | call to params : | app/views/foo/bars/show.html.erb:76:28:76:39 | ...[...] | Cross-site scripting vulnerability due to a $@. | app/views/foo/bars/show.html.erb:76:28:76:33 | call to params | user-provided value |

View File

@@ -1,39 +1,49 @@
edges
| app/controllers/foo/stores_controller.rb:8:10:8:29 | call to read : | app/controllers/foo/stores_controller.rb:9:22:9:23 | dt : |
| app/controllers/foo/stores_controller.rb:8:10:8:29 | call to read : | app/controllers/foo/stores_controller.rb:13:55:13:56 | dt : |
| app/controllers/foo/stores_controller.rb:9:22:9:23 | dt : | app/views/foo/stores/show.html.erb:38:3:38:16 | @instance_text |
| app/controllers/foo/stores_controller.rb:12:28:12:48 | call to raw_name : | app/views/foo/stores/show.html.erb:83:5:83:24 | @other_user_raw_name |
| app/controllers/foo/stores_controller.rb:9:22:9:23 | dt : | app/views/foo/stores/show.html.erb:37:3:37:16 | @instance_text |
| app/controllers/foo/stores_controller.rb:12:28:12:48 | call to raw_name : | app/views/foo/stores/show.html.erb:82:5:82:24 | @other_user_raw_name |
| app/controllers/foo/stores_controller.rb:13:55:13:56 | dt : | app/views/foo/stores/show.html.erb:2:9:2:20 | call to display_text |
| app/controllers/foo/stores_controller.rb:13:55:13:56 | dt : | app/views/foo/stores/show.html.erb:5:9:5:36 | ...[...] |
| app/controllers/foo/stores_controller.rb:13:55:13:56 | dt : | app/views/foo/stores/show.html.erb:9:9:9:26 | ...[...] |
| app/controllers/foo/stores_controller.rb:13:55:13:56 | dt : | app/views/foo/stores/show.html.erb:33:3:33:14 | call to display_text |
| app/controllers/foo/stores_controller.rb:13:55:13:56 | dt : | app/views/foo/stores/show.html.erb:41:76:41:87 | call to display_text : |
| app/views/foo/stores/show.html.erb:41:64:41:87 | ... + ... : | app/views/foo/bars/_widget.html.erb:5:9:5:20 | call to display_text |
| app/views/foo/stores/show.html.erb:41:64:41:87 | ... + ... : | app/views/foo/bars/_widget.html.erb:8:9:8:36 | ...[...] |
| app/views/foo/stores/show.html.erb:41:76:41:87 | call to display_text : | app/views/foo/stores/show.html.erb:41:64:41:87 | ... + ... : |
| app/views/foo/stores/show.html.erb:87:17:87:28 | call to handle : | app/views/foo/stores/show.html.erb:87:3:87:29 | call to sprintf |
| app/controllers/foo/stores_controller.rb:13:55:13:56 | dt : | app/views/foo/stores/show.html.erb:5:9:5:21 | call to local_assigns [element :display_text] : |
| app/controllers/foo/stores_controller.rb:13:55:13:56 | dt : | app/views/foo/stores/show.html.erb:9:9:9:21 | call to local_assigns [element :display_text] : |
| app/controllers/foo/stores_controller.rb:13:55:13:56 | dt : | app/views/foo/stores/show.html.erb:14:15:14:27 | call to local_assigns [element :display_text] : |
| app/controllers/foo/stores_controller.rb:13:55:13:56 | dt : | app/views/foo/stores/show.html.erb:32:3:32:14 | call to display_text |
| app/controllers/foo/stores_controller.rb:13:55:13:56 | dt : | app/views/foo/stores/show.html.erb:40:76:40:87 | call to display_text : |
| app/views/foo/bars/_widget.html.erb:8:9:8:21 | call to local_assigns [element :display_text] : | app/views/foo/bars/_widget.html.erb:8:9:8:36 | ...[...] |
| app/views/foo/stores/show.html.erb:5:9:5:21 | call to local_assigns [element :display_text] : | app/views/foo/stores/show.html.erb:5:9:5:36 | ...[...] |
| app/views/foo/stores/show.html.erb:9:9:9:21 | call to local_assigns [element :display_text] : | app/views/foo/stores/show.html.erb:9:9:9:26 | ...[...] |
| app/views/foo/stores/show.html.erb:14:15:14:27 | call to local_assigns [element :display_text] : | app/views/foo/stores/show.html.erb:14:15:14:32 | ...[...] |
| app/views/foo/stores/show.html.erb:40:64:40:87 | ... + ... : | app/views/foo/bars/_widget.html.erb:5:9:5:20 | call to display_text |
| app/views/foo/stores/show.html.erb:40:64:40:87 | ... + ... : | app/views/foo/bars/_widget.html.erb:8:9:8:21 | call to local_assigns [element :display_text] : |
| app/views/foo/stores/show.html.erb:40:76:40:87 | call to display_text : | app/views/foo/stores/show.html.erb:40:64:40:87 | ... + ... : |
| app/views/foo/stores/show.html.erb:86:17:86:28 | call to handle : | app/views/foo/stores/show.html.erb:86:3:86:29 | call to sprintf |
nodes
| app/controllers/foo/stores_controller.rb:8:10:8:29 | call to read : | semmle.label | call to read : |
| app/controllers/foo/stores_controller.rb:9:22:9:23 | dt : | semmle.label | dt : |
| app/controllers/foo/stores_controller.rb:12:28:12:48 | call to raw_name : | semmle.label | call to raw_name : |
| app/controllers/foo/stores_controller.rb:13:55:13:56 | dt : | semmle.label | dt : |
| app/views/foo/bars/_widget.html.erb:5:9:5:20 | call to display_text | semmle.label | call to display_text |
| app/views/foo/bars/_widget.html.erb:8:9:8:21 | call to local_assigns [element :display_text] : | semmle.label | call to local_assigns [element :display_text] : |
| app/views/foo/bars/_widget.html.erb:8:9:8:36 | ...[...] | semmle.label | ...[...] |
| app/views/foo/stores/show.html.erb:2:9:2:20 | call to display_text | semmle.label | call to display_text |
| app/views/foo/stores/show.html.erb:5:9:5:21 | call to local_assigns [element :display_text] : | semmle.label | call to local_assigns [element :display_text] : |
| app/views/foo/stores/show.html.erb:5:9:5:36 | ...[...] | semmle.label | ...[...] |
| app/views/foo/stores/show.html.erb:9:9:9:21 | call to local_assigns [element :display_text] : | semmle.label | call to local_assigns [element :display_text] : |
| app/views/foo/stores/show.html.erb:9:9:9:26 | ...[...] | semmle.label | ...[...] |
| app/views/foo/stores/show.html.erb:33:3:33:14 | call to display_text | semmle.label | call to display_text |
| app/views/foo/stores/show.html.erb:38:3:38:16 | @instance_text | semmle.label | @instance_text |
| app/views/foo/stores/show.html.erb:41:64:41:87 | ... + ... : | semmle.label | ... + ... : |
| app/views/foo/stores/show.html.erb:41:76:41:87 | call to display_text : | semmle.label | call to display_text : |
| app/views/foo/stores/show.html.erb:47:5:47:16 | call to handle | semmle.label | call to handle |
| app/views/foo/stores/show.html.erb:50:5:50:18 | call to raw_name | semmle.label | call to raw_name |
| app/views/foo/stores/show.html.erb:64:3:64:18 | call to handle | semmle.label | call to handle |
| app/views/foo/stores/show.html.erb:70:3:70:20 | call to raw_name | semmle.label | call to raw_name |
| app/views/foo/stores/show.html.erb:80:5:80:22 | call to display_name | semmle.label | call to display_name |
| app/views/foo/stores/show.html.erb:83:5:83:24 | @other_user_raw_name | semmle.label | @other_user_raw_name |
| app/views/foo/stores/show.html.erb:87:3:87:29 | call to sprintf | semmle.label | call to sprintf |
| app/views/foo/stores/show.html.erb:87:17:87:28 | call to handle : | semmle.label | call to handle : |
| app/views/foo/stores/show.html.erb:14:15:14:27 | call to local_assigns [element :display_text] : | semmle.label | call to local_assigns [element :display_text] : |
| app/views/foo/stores/show.html.erb:14:15:14:32 | ...[...] | semmle.label | ...[...] |
| app/views/foo/stores/show.html.erb:32:3:32:14 | call to display_text | semmle.label | call to display_text |
| app/views/foo/stores/show.html.erb:37:3:37:16 | @instance_text | semmle.label | @instance_text |
| app/views/foo/stores/show.html.erb:40:64:40:87 | ... + ... : | semmle.label | ... + ... : |
| app/views/foo/stores/show.html.erb:40:76:40:87 | call to display_text : | semmle.label | call to display_text : |
| app/views/foo/stores/show.html.erb:46:5:46:16 | call to handle | semmle.label | call to handle |
| app/views/foo/stores/show.html.erb:49:5:49:18 | call to raw_name | semmle.label | call to raw_name |
| app/views/foo/stores/show.html.erb:63:3:63:18 | call to handle | semmle.label | call to handle |
| app/views/foo/stores/show.html.erb:69:3:69:20 | call to raw_name | semmle.label | call to raw_name |
| app/views/foo/stores/show.html.erb:79:5:79:22 | call to display_name | semmle.label | call to display_name |
| app/views/foo/stores/show.html.erb:82:5:82:24 | @other_user_raw_name | semmle.label | @other_user_raw_name |
| app/views/foo/stores/show.html.erb:86:3:86:29 | call to sprintf | semmle.label | call to sprintf |
| app/views/foo/stores/show.html.erb:86:17:86:28 | call to handle : | semmle.label | call to handle : |
subpaths
#select
| app/views/foo/bars/_widget.html.erb:5:9:5:20 | call to display_text | app/controllers/foo/stores_controller.rb:8:10:8:29 | call to read : | app/views/foo/bars/_widget.html.erb:5:9:5:20 | call to display_text | Stored cross-site scripting vulnerability due to $@. | app/controllers/foo/stores_controller.rb:8:10:8:29 | call to read | stored value |
@@ -41,12 +51,13 @@ subpaths
| app/views/foo/stores/show.html.erb:2:9:2:20 | call to display_text | app/controllers/foo/stores_controller.rb:8:10:8:29 | call to read : | app/views/foo/stores/show.html.erb:2:9:2:20 | call to display_text | Stored cross-site scripting vulnerability due to $@. | app/controllers/foo/stores_controller.rb:8:10:8:29 | call to read | stored value |
| app/views/foo/stores/show.html.erb:5:9:5:36 | ...[...] | app/controllers/foo/stores_controller.rb:8:10:8:29 | call to read : | app/views/foo/stores/show.html.erb:5:9:5:36 | ...[...] | Stored cross-site scripting vulnerability due to $@. | app/controllers/foo/stores_controller.rb:8:10:8:29 | call to read | stored value |
| app/views/foo/stores/show.html.erb:9:9:9:26 | ...[...] | app/controllers/foo/stores_controller.rb:8:10:8:29 | call to read : | app/views/foo/stores/show.html.erb:9:9:9:26 | ...[...] | Stored cross-site scripting vulnerability due to $@. | app/controllers/foo/stores_controller.rb:8:10:8:29 | call to read | stored value |
| app/views/foo/stores/show.html.erb:33:3:33:14 | call to display_text | app/controllers/foo/stores_controller.rb:8:10:8:29 | call to read : | app/views/foo/stores/show.html.erb:33:3:33:14 | call to display_text | Stored cross-site scripting vulnerability due to $@. | app/controllers/foo/stores_controller.rb:8:10:8:29 | call to read | stored value |
| app/views/foo/stores/show.html.erb:38:3:38:16 | @instance_text | app/controllers/foo/stores_controller.rb:8:10:8:29 | call to read : | app/views/foo/stores/show.html.erb:38:3:38:16 | @instance_text | Stored cross-site scripting vulnerability due to $@. | app/controllers/foo/stores_controller.rb:8:10:8:29 | call to read | stored value |
| app/views/foo/stores/show.html.erb:47:5:47:16 | call to handle | app/views/foo/stores/show.html.erb:47:5:47:16 | call to handle | app/views/foo/stores/show.html.erb:47:5:47:16 | call to handle | Stored cross-site scripting vulnerability due to $@. | app/views/foo/stores/show.html.erb:47:5:47:16 | call to handle | stored value |
| app/views/foo/stores/show.html.erb:50:5:50:18 | call to raw_name | app/views/foo/stores/show.html.erb:50:5:50:18 | call to raw_name | app/views/foo/stores/show.html.erb:50:5:50:18 | call to raw_name | Stored cross-site scripting vulnerability due to $@. | app/views/foo/stores/show.html.erb:50:5:50:18 | call to raw_name | stored value |
| app/views/foo/stores/show.html.erb:64:3:64:18 | call to handle | app/views/foo/stores/show.html.erb:64:3:64:18 | call to handle | app/views/foo/stores/show.html.erb:64:3:64:18 | call to handle | Stored cross-site scripting vulnerability due to $@. | app/views/foo/stores/show.html.erb:64:3:64:18 | call to handle | stored value |
| app/views/foo/stores/show.html.erb:70:3:70:20 | call to raw_name | app/views/foo/stores/show.html.erb:70:3:70:20 | call to raw_name | app/views/foo/stores/show.html.erb:70:3:70:20 | call to raw_name | Stored cross-site scripting vulnerability due to $@. | app/views/foo/stores/show.html.erb:70:3:70:20 | call to raw_name | stored value |
| app/views/foo/stores/show.html.erb:80:5:80:22 | call to display_name | app/views/foo/stores/show.html.erb:80:5:80:22 | call to display_name | app/views/foo/stores/show.html.erb:80:5:80:22 | call to display_name | Stored cross-site scripting vulnerability due to $@. | app/views/foo/stores/show.html.erb:80:5:80:22 | call to display_name | stored value |
| app/views/foo/stores/show.html.erb:83:5:83:24 | @other_user_raw_name | app/controllers/foo/stores_controller.rb:12:28:12:48 | call to raw_name : | app/views/foo/stores/show.html.erb:83:5:83:24 | @other_user_raw_name | Stored cross-site scripting vulnerability due to $@. | app/controllers/foo/stores_controller.rb:12:28:12:48 | call to raw_name | stored value |
| app/views/foo/stores/show.html.erb:87:3:87:29 | call to sprintf | app/views/foo/stores/show.html.erb:87:17:87:28 | call to handle : | app/views/foo/stores/show.html.erb:87:3:87:29 | call to sprintf | Stored cross-site scripting vulnerability due to $@. | app/views/foo/stores/show.html.erb:87:17:87:28 | call to handle | stored value |
| app/views/foo/stores/show.html.erb:14:15:14:32 | ...[...] | app/controllers/foo/stores_controller.rb:8:10:8:29 | call to read : | app/views/foo/stores/show.html.erb:14:15:14:32 | ...[...] | Stored cross-site scripting vulnerability due to $@. | app/controllers/foo/stores_controller.rb:8:10:8:29 | call to read | stored value |
| app/views/foo/stores/show.html.erb:32:3:32:14 | call to display_text | app/controllers/foo/stores_controller.rb:8:10:8:29 | call to read : | app/views/foo/stores/show.html.erb:32:3:32:14 | call to display_text | Stored cross-site scripting vulnerability due to $@. | app/controllers/foo/stores_controller.rb:8:10:8:29 | call to read | stored value |
| app/views/foo/stores/show.html.erb:37:3:37:16 | @instance_text | app/controllers/foo/stores_controller.rb:8:10:8:29 | call to read : | app/views/foo/stores/show.html.erb:37:3:37:16 | @instance_text | Stored cross-site scripting vulnerability due to $@. | app/controllers/foo/stores_controller.rb:8:10:8:29 | call to read | stored value |
| app/views/foo/stores/show.html.erb:46:5:46:16 | call to handle | app/views/foo/stores/show.html.erb:46:5:46:16 | call to handle | app/views/foo/stores/show.html.erb:46:5:46:16 | call to handle | Stored cross-site scripting vulnerability due to $@. | app/views/foo/stores/show.html.erb:46:5:46:16 | call to handle | stored value |
| app/views/foo/stores/show.html.erb:49:5:49:18 | call to raw_name | app/views/foo/stores/show.html.erb:49:5:49:18 | call to raw_name | app/views/foo/stores/show.html.erb:49:5:49:18 | call to raw_name | Stored cross-site scripting vulnerability due to $@. | app/views/foo/stores/show.html.erb:49:5:49:18 | call to raw_name | stored value |
| app/views/foo/stores/show.html.erb:63:3:63:18 | call to handle | app/views/foo/stores/show.html.erb:63:3:63:18 | call to handle | app/views/foo/stores/show.html.erb:63:3:63:18 | call to handle | Stored cross-site scripting vulnerability due to $@. | app/views/foo/stores/show.html.erb:63:3:63:18 | call to handle | stored value |
| app/views/foo/stores/show.html.erb:69:3:69:20 | call to raw_name | app/views/foo/stores/show.html.erb:69:3:69:20 | call to raw_name | app/views/foo/stores/show.html.erb:69:3:69:20 | call to raw_name | Stored cross-site scripting vulnerability due to $@. | app/views/foo/stores/show.html.erb:69:3:69:20 | call to raw_name | stored value |
| app/views/foo/stores/show.html.erb:79:5:79:22 | call to display_name | app/views/foo/stores/show.html.erb:79:5:79:22 | call to display_name | app/views/foo/stores/show.html.erb:79:5:79:22 | call to display_name | Stored cross-site scripting vulnerability due to $@. | app/views/foo/stores/show.html.erb:79:5:79:22 | call to display_name | stored value |
| app/views/foo/stores/show.html.erb:82:5:82:24 | @other_user_raw_name | app/controllers/foo/stores_controller.rb:12:28:12:48 | call to raw_name : | app/views/foo/stores/show.html.erb:82:5:82:24 | @other_user_raw_name | Stored cross-site scripting vulnerability due to $@. | app/controllers/foo/stores_controller.rb:12:28:12:48 | call to raw_name | stored value |
| app/views/foo/stores/show.html.erb:86:3:86:29 | call to sprintf | app/views/foo/stores/show.html.erb:86:17:86:28 | call to handle : | app/views/foo/stores/show.html.erb:86:3:86:29 | call to sprintf | Stored cross-site scripting vulnerability due to $@. | app/views/foo/stores/show.html.erb:86:17:86:28 | call to handle | stored value |

View File

@@ -14,7 +14,6 @@
<ul>
<% for key in [:display_text, :safe_text] do %>
<%# BAD: A local rendered raw via the locals hash %>
<%# TODO: we miss that `key` can take `:display_text` as a value here %>
<li><%= raw local_assigns[key] %></li>
<% end %>
</ul>

View File

@@ -11,7 +11,6 @@
<ul>
<% for key in [:display_text, :safe_text] do %>
<%# BAD: A local rendered raw via the locals hash %>
<%# TODO: we miss that `key` can take `:display_text` as a value here %>
<li><%= raw local_assigns[key] %></li>
<% end %>
</ul>
@@ -88,4 +87,4 @@
%>
<%# GOOD: The `foo.bar.baz` is not recognized as a source %>
<%= @other_user_raw_name.foo.bar.baz.html_safe %>
<%= @other_user_raw_name.foo.bar.baz.html_safe %>