tompave / fun_with_flags_ui Goto Github PK
View Code? Open in Web Editor NEWWeb dashboard for the FunWithFlags Elixir package
License: MIT License
Web dashboard for the FunWithFlags Elixir package
License: MIT License
The FunWithflagsUI is vulnerable to persistent XSS attacks.
For Example a request in our Application like this:
POST /feature-flags/flags/some_flag/actors HTTP/1.1
_csrf_token=ZCoOGggmewMSFTxcFVkFMBU3PDITDC4n4ngbON8wMAeqYaDB-rVgwNXr&actor_id=aa<h1>bb&enabled=true
Results in page with the following HTML:
<li class="list-group-item px-0">
<div id="actor_aa<h1>bb" class="container fwf-I-hate-grids">
<div class="row no-gutters">
<div class="col-lg-8 col-md-7 col-sm-5 col-3 text-left">
<code>aa<h1>bb</code>
</div>
Similarly GET paramaters can also generate XSS within the page:
GET /feature-flags/flags/some_other_flag#actor_cat:%3Ch1%3EXSSHERE HTTP/1.1
will get
<h1><code>XSSHERE</code>
</h1>
All user inputs must be properly sanitised and encoded . See https://owasp.org/www-community/attacks/xss/ for more details about XSS
A polite request to update fun_with_flags_ui
to use the very recently released fun_with_flags v1.12.0 - for Elixir 1.17 and 1.16 support.
We use fun_with_flags
as suggested in its README, that is:
runtime: false
FunWithFlags.Supervisor
manually in our application's supervisorIf I try to use fun_with_flags_ui
, this becomes problematic. fun_with_flags_ui
lists fun_with_flags
as a dependency without runtime: false
. This means that the fun_with_flags
application gets started anyways.
I think what we'd want to do in fun_with_flags_ui
is:
fun_with_flags
as dependency with runtime: false
fun_with_flags_ui
's Application
module, we manually start FunWithFlags.Supervisor
Thoughts?
We have a bit of a strange setup, where the app is hosted on a subpath. some.site.com/cool-app
It's also not a clever url rewrite, so the logic how to handle subpaths is a responsibility of the applications and the /cool-app
part is actually in our router scopes. It is also part of our urls for static assets.
Now, this is a challenge when using fun_with_flags_ui. The assets are hardcoded and I can't inject the /cool-app
prefix to them. Or can I, and I just don't know how?
I did a bit of research and looked how phoenix_live_dashboard does it, because the usage pattern is similar, but the assets work for them.
They made a plug for serving static assets, so it works wherever it is mounted.
If this is the solution, I would be happy to come up with a PR.
It looks like when I try and submit a form when piping through the :protect_from_forgery
plug, the request fails due to lack of CSRF token.
It would be nice to be able to use this package with the proper CSRF protection.
Similar topic was brought up here #8
What we have is a load balancer overriding the accept-encoding headers and as a result - bootstrap.css is not loaded.
Would you accept a pull request where both versions of the file are available: gzipped and not?
It would be nice if listed gates for flags are ordered the same for each row, which makes is quicker to scan.
I'm now seeing a CSRF error when the details page tries to load the details.js
script:
** (Plug.CSRFProtection.InvalidCrossOriginRequestError) security warning: an embedded <script> tag on another site requested protected JavaScript (if you know what you're doing, disable forgery protection for this route)
When this JS file does not load, there are no longer any confirmation boxes showing up.
I think we need to either ignore CSRF Protection on this route or add the token when loading up the script.
I introduced this error with PR #4 and I'll look at putting in a fix as soon as I can.
I'm currently working on a similar "embed into some phoenix/plug app" tool than this one. In my research I found in bamboos preview router that they use conn.script_name
to construct their routes. It would be nice to use this here as well, so the namespace option is no longer needed.
While trying to work with FunWithFlagsUI
(especially with any new flag) from time to time we get such weird error:
ArgumentError :erlang.binary_to_existing_atom/2
errors were found at the given arguments: * 1st argument: not an already existing atom
lib/fun_with_flags/ui/router.ex in anonymous fn/3 in FunWithFlags.UI.Router.do_match/4 at line 99
lib/plug/router.ex in anonymous fn/4 in FunWithFlags.UI.Router.dispatch/2 at line 246
/opt/app/deps/telemetry/src/telemetry.erl in :telemetry.span/3 at line 321
lib/plug/router.ex in FunWithFlags.UI.Router.dispatch/2 at line 242
lib/fun_with_flags/ui/router.ex in FunWithFlags.UI.Router.plug_builder_call/2 at line 1
lib/phoenix/router/route.ex in Phoenix.Router.Route.call/2 at line 42
lib/phoenix/router.ex in Phoenix.Router.__call__/5 at line 425
I think it comes from there:
https://github.com/tompave/fun_with_flags_ui/blob/master/lib/fun_with_flags/ui/router.ex
defmodule FunWithFlags.UI.Router do
...
get "/flags/:name" do
case Utils.get_flag(name) do
...
end
end
...
end
https://github.com/tompave/fun_with_flags_ui/blob/master/lib/fun_with_flags/ui/utils.ex
defmodule FunWithFlags.UI.Utils do
...
def get_flag(name) do
..
case FunWithFlags.SimpleStore.lookup(String.to_existing_atom(name)) do
...
end
...
end
...
end
Maybe it's worth to replace String.to_existing_atom
with String.to_atom
to avoid the issue, what do you think?
Is there anyway of customizing the header to use a different color and text/logo?
Getting
Request: GET /feature-flags/flags
** (exit) an exception was raised:
** (UndefinedFunctionError) function FunWithFlags.Store.Persistent.Redis.all_flags/0 is undefined (module FunWithFlags.Store.Persistent.Redis is not available)
FunWithFlags.Store.Persistent.Redis.all_flags()
(fun_with_flags_ui 0.7.2) lib/fun_with_flags/ui/router.ex:73: anonymous fn/2 in FunWithFlags.UI.Router.do_match/4
(fun_with_flags_ui 0.7.2) lib/plug/router.ex:280: anonymous fn/4 in FunWithFlags.UI.Router.dispatch/2
(telemetry 0.4.3) /Users/q/Developer/app/deps/telemetry/src/telemetry.erl:272: :telemetry.span/3
(fun_with_flags_ui 0.7.2) lib/plug/router.ex:276: FunWithFlags.UI.Router.dispatch/2
(fun_with_flags_ui 0.7.2) lib/fun_with_flags/ui/router.ex:1: FunWithFlags.UI.Router.plug_builder_call/2
(phoenix 1.5.13) lib/phoenix/router/route.ex:41: Phoenix.Router.Route.call/2
(phoenix 1.5.13) lib/phoenix/router.ex:352: Phoenix.Router.__call__/2
for an app setup like this:
config :fun_with_flags, :persistence,
adapter: FunWithFlags.Store.Persistent.Ecto,
repo: App.Repo,
ecto_table_name: "fun_with_flags_toggles"
config :fun_with_flags, :cache_bust_notifications, enabled: false
pipeline :admins_only do
plug :basic_auth, Application.compile_env(:app, :basic_auth)
end
scope path: "/feature-flags" do
pipe_through [:mounted_apps, :admins_only]
forward "/", FunWithFlags.UI.Router, namespace: "feature-flags"
end
%{
"fun_with_flags": {:hex, :fun_with_flags, "1.6.0", "507fcbc19374e83d34ba13d63b0816d37af952da1c6592978bbf40dad6a2e671", [:mix], [{:ecto_sql, "~> 3.0", [hex: :ecto_sql, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: true]}, {:redix, "~> 1.0", [hex: :redix, repo: "hexpm", optional: true]}], "hexpm", "96b53f54737906c5a83b5d89922ca1145fda2d50db23b1f619478460b8d5f8d8"},
"fun_with_flags_ui": {:hex, :fun_with_flags_ui, "0.7.2", "c8df9e90f92481c014824ab1ff5db7d501ac34ec28a4599b76251ec5a6db0861", [:mix], [{:cowboy, ">= 1.0.0", [hex: :cowboy, repo: "hexpm", optional: true]}, {:fun_with_flags, "~> 1.1", [hex: :fun_with_flags, repo: "hexpm", optional: false]}, {:plug, "~> 1.4", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}], "hexpm", "99b3635b067304722560ea3d5aab38ae23ea1217366c95ecb6263559488a22f2"},
}
We are using this UI to check the flags we have on redis. Since Redis has several DBs one can choose from, this raises a problem - we need to tell the UI which Redis DB to use.
After reading the docs, I couldn't find any option to do that. By default, the UI will always read from Redis DB 1, which is not where our flags are.
Is there a way to tell the UI which Redis DB to use?
We have a check_email_verified?
flag in our system which gets presented properly in the UI. But selecting it routes to feature-flags/flag/check_email_verified?
so that the ?
is interpreted as beginning of the query string.
This results in the flag not being found.
Selecting a flag with a question mark (?
) displays a "not found" details page instead of allowing to change the settings for the flag.
It's possible to see the detail page for flags with question marks (?
) when selecting them on the index page.
Hi,
In production, I'm not able to load the bootstrap gzipped file and Google Chrome is giving me this error message:
Refused to apply style from 'https://www.example.com/admin/feature-flags/assets/bootstrap.min.css'
because its MIME type ('') is not a supported stylesheet MIME type, and strict MIME checking
is enabled.
The style.css
is working correctly, but the gzipped bootstrap don't. I couldn't find any Nginx config that was blocking it somehow. I guess I would have to add gzip_static on;
for this location (didn't test though).
Wouldn't be better to load the file from bootstrap CDN instead? Like:
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
I appreciate any help :)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.