rails / strong_parameters Goto Github PK
View Code? Open in Web Editor NEWTaint and required checking for Action Pack and enforcement in Active Model
License: MIT License
Taint and required checking for Action Pack and enforcement in Active Model
License: MIT License
In the latest master revision. Had to revert to the gem....
Hi,
So I've been getting this error: Couldn't find Address with ID=47 for CarrierOffice with ID=
with this code:
params.require(:claim).permit(
:review_type,
:number,
:point_of_impact,
:deductible,
:company_id,
:appraisal_author,
:type_of_loss,
:estimate_written_on,
:carrier_id,
:carrier_office_id,
:carrier_number,
:carrier_office_adjuster_id,
:vehicle_attributes,
:carrier_office_adjuster_attributes,
carrier_office_attributes: [:name, :address_attributes]
)
but when I change carrier_office_attributes: [:name, :address_attributes]
to carrier_office_attributes: [:id, :name, :address_attributes]
everything works just fine. I'm guessing this is because it doesn't think it has access to id
unless I specify it. The issue with that is, I don't want people to be able to updated the id but obviously rails has to search on id.
Which then led me to another related issue, with nested attributes like vehicle_attributes
, address_attributes
etc... it allows you to pass any attribute to it which doesn't seem to be right either as it should required you to specify what fields of the nested attributes are allowed. Even better, it should be able to inherit the rules from the vehicle and address controllers.
Any ideas on this?
I have a question about mass assignment outside of controllers.
If I call #update_attributes
on an model using ForbiddenAttributesProtection and pass it a vanilla ruby hash, my understanding is the permitted check is bypassed.
What is the recommended practice for such mass assignments if the hash hasn't been wrapped by ActionController::Parameters because it's not in a controller context?
The README.md
mentions ActionController::MissingParameter
instead of ActionController::ParameterMissing
.
There is also no mentioning of ActionController::UnpermittedParameters
Was just reading back through the Parameters#permit!
method and saw two possible paths. I will help with either need be.
Scenarios:
You create a User model and UsersController, and decide (for some insane reason?) to do a params.require(:user).permit!
. Sometime later you add an admin boolean to users, forget to update your controller; tests pass, app keeps chugging, but now there's a problem.
On the flip side, perhaps there are legit instances where you want to just whitelist everything with #permit!
. I've been searching blogs for examples but so far have found mention but no great use cases.
Thoughts?
Here's an example:
app/views/projects/_form.html.erb:
<%= form_for(@project) do |f| %>
<%= f.label :start_date %> <%= f.datetime_select :start_date, :twelve_hour => true %>
<% end %>
params[:project]:
'start_date(1i)' = '2012'
'start_date(2i)' = '9'
'start_date(3i)' = '19'
'start_date(4i)' = '13'
'start_date(5i)' = '43'
Validation message:
1 error prohibited this project from being saved:
Rails XSS protection is handled in the view layer, however, 95 out of the 100 fields on forms should not have any html or javascript in them anyway (or SQL for that matter).
I propose to add sanitation to all the 'permit' and 'required' keys, (that is currently by the way an inconsistency in language in the dsl, required and permit, probably should be require & permit or required & permitted) a third option could be added like permit_unsanitized for the fields where html is allowed.
I can create a pull request if you agree and if the proposed names are ok: require_unsanitized & permit_unsanitized
Any way to use a blacklisted attributes (vs whitelist). This would be useful in the case when the user can specify his own attributes (nosql / hstore). Another alternative would be something to skip the recursive attribute permit on a hash.
params = {user: { name: "Bob", info: {custom: "info"}}}
params.require("user").permit(:name, :info)
#gives {name: "Bob"}
#maybe something like
params.require("user").permit(:name, :info).allow_all(:info)
#would give the expected {name: "Bob", info: {custom: "info"}}
In an app i'm working on we sanitise some params inside of a controller and then serialise them for later use. When we deserialize the values the permitted? flag is lost.
params_hash = ActionController::Parameters.new(:foo => 'bar').permit(:foo)
params_hash.permitted? #=> true
YAML.load(params_hash.to_yaml).permitted? #=> false
We could easily convert the paramaters to a regular hash, but nested hashes are a problem, it must be done recursively which is not ideal.
Would it be good to override the serialisation of the parameters hash to record the permitted value? rather than serialising like a regular hash? Would there be any issues associated with that?
This video states that it is possible to protect the input coming in via the controller yet still be able to do mass assignment via models and specs. However, I have not seen this documented as a feature when using strong_parameters in 3.2.8.
I understand that I need to mix in ActiveModel::ForbiddenAttributesProtection
into my models and set config.active_record.whitelist_attributes = false
in config/application.rb
. I have also pulled all of my attr_accessible
calls from the model.
With or without the mixin I am getting mass assignment errors.
ActiveModel::MassAssignmentSecurity::Error: Can't mass-assign protected attributes: home_phone, cell_phone
Am I missing something?
It's not clear what the intention of #require is. Are all parameters that are 'required' to be in the parameters list for a model supposed to be in the #require? I read :
params.require(:person).permit(:name, :age)
to mean that in the params hash, there MUST be a :person key and there may also be a name and age key. ie:
params = { :person => 'person', :name => 'John', :age => "23" }
Whereas it seems that the code means that there must be a person key and inside of that there may be a name and age key. ie:
params => { :person => { :name => "John", :age => "23" } }
It would be useful to clarify the documentation as to what 'require' and 'permit' mean. I thought that because I have a validation for name being required, that I needed to have name as a required parameter, not as a permitted parameter. Alternately, I thought I could force name to be required by adding it in the require (and have another way of doing a validation). ie: This would work:
params => { :person => 'blah', :name => "John" }
and this would fail (because :name was also required):
params => { :person => "blah", :age => "23" }
It's also unclear from the documentation that #permit only works after a require and why it works that way.
I've forked strong_parameters with the aim of improving the error output when no permit is set. To do this I've started by modifying the ActiveModelMassUpdateProtectionTest by splitting "forbidden attributes cannot be used for mass updating" into two so that I can test both when the permit is not set, and when its contents don't match the original parameter.
My problem is that now I have done this I think both tests should pass, but the first one fails.
test "forbidden attributes cannot be used for mass updating" do
assert_raises(ActiveModel::ForbiddenAttributes) do
Person.new.sanitize_for_mass_assignment(ActionController::Parameters.new(:a => "b").permit(:c))
end
end
test "attributes cannot be used for mass updating when nothing permitted" do
assert_raises(ActiveModel::ForbiddenAttributes) do
Person.new.sanitize_for_mass_assignment(ActionController::Parameters.new(:a => "b"))
end
end
Shouldn't the first test pass?
2 months without an update <-> would be nice to get rid of a git-dependency
lib/action_controller/parameters.rb#L116
def params=(val)
@_params = val.is_a?(Hash) ? Parameters.new(val) : val
end
Was it intentional to wipe the permit value when setting a ::ActionController::Parameters to the controller's params?
new_params = ::ActionController::Parameters.new.permit
new_params.permitted? # returns true
new_params.is_a?(Hash) # returns true
controller.params = new_params
controller.params.permitted? # returns false
I was playing with Strong Parameters with nested attributes and noticed that empty fields were automatically filled in with existing records.
It's difficult to explain and it only happens when updating a record. Here's a video that shows the problem. http://www.screenr.com/OMK7
I created a bare-bones application so you can play with it yourself.
http://cl.ly/3l0p2P0v3P1y
I can't pass an array of arrays like this:
tips = [[:photo_suggest, 3], [:foo, "bar"]]
put :update, id: 34, tips: tips, format: :json
...
params.require(:tips)
# => [[:photo_suggest, 3], [:foo, "bar"]]
params.permit(:tips => [])
# => {}
I believe this is because Arrays are only allowed explicitly and even still the contents of the Array must be a scalar value, of which an Array is not.
I have a simple has_many / belongs_to relationship in an example project app, something like:
class A < AR
has_many :bs
end
class B < AR
belongs_to :a
end
Passing the following params hash in an update unpermits b_ids
:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"...", "a"=>{"b_ids"=>["1", "2", ""]}, "id"=>"1"}
Does this have to do with the fact that Array
is missing out in the PERMITTED_SCALAR_TYPES
constant? At first sight, it is what it seems to me.
Let me know if you need more info.
I'm not sure if this is a Rails issue (and whether it will apply to Rails 4) or properly belongs here.
I have a Project model and a ProjectType model. Projects belong_to ProjectTypes. The foreign key (and the attribute) is named project_type_id but I had named the association as 'type' so that I could refer to project.type which seemed natural. This (seemed to) work while using attr_accessible but when I changed the Project model over to use strong_parameters I got MassAssignmentSecurity::Error as "id" and "type" appear to be protected by default.
It may have been foolish to use 'type' as an association name but no useful errors were reported and finding documentation to this effect isn't easy either.
For my purposes this is no longer an important issue as I have renamed the association but I thought by raising the issue here at the very least it could provide documentation for any others looking to understand why MassAssignmentSecurity::Error are occuring with all attr_protected/attr_accessible removed from the project and "config.active_record.whitelist_attributes = false" set in application.rb.
def account_params
params.require(:account).permit :name, users_attributes: [:email, :first_name, :last_name, :password, :password_confirmation]
end
users_attributes
ends up as a blank hash.
It appears that calling fetch
will modify the receiver via convert_hashes_to_parameters
. The 2nd argument to fetch
should not assign the default value to the provided key.
params = ActionController::Parameters.new :controller => 'foo', :action => 'bar' #=> {"controller"=>"foo", "action"=>"bar"}
params.fetch(:message, {})[:id] #=> nil
params #=> {"controller"=>"foo", "action"=>"bar", "message"=>{}}
hsh = {:controller => 'foo', :action => 'bar'} #=> {"controller"=>"foo", "action"=>"bar"}
hsh.fetch(:message, {})[:id] #=> nil
hsh #=> {"controller"=>"foo", "action"=>"bar"}
Forgive me if I am missing something, please. I love the idea of this, but I am struggling to see the difference between using this and config.active_record.whitelist_attributes = true
in application.rb
config.
It looks like DHH has said this is going in rails core, so I would love to understand a little more what it is all about.
As soon as I add the strong_parameters gem (0.1.4) to a 4.0.0.beta app, bundle and restart, this is thrown:
TypeError: superclass mismatch for class ParameterMissing
I am testing avatar upload with strong parameter
And I have been using Rack::Test::UploadedFile to perform testing
I wonder if Rack::Test::UploadedFile can be supported
Or is there a way to test with ActionDispatch::Http::UploadedFile?
Testing the gem, I never had to include the ForbiddenAttributesProtection model like it says I had to in the readme.
class Post < ActiveRecord::Base
include ActiveModel::ForbiddenAttributesProtection
end
Is this still required? Seems to be working fine without it, and the scaffold generator doesn't place it either.
One common pattern I use a lot is:
def post_hash
params[:post] || {}
end
With TaintedHash, that looks something like:
def post_hash
(params[:post] ||= TaintedHash.new).expose :title, :body
end
I'd like to change it to this:
def post_hash
params.require(:post).permit(:title, :body)
end
If no post
value is given, the Post record won't be saved due to a validation on title/body. I guess I'd prefer that over worrying about catching a new exception.
Kudos to this library. I'm planning on tweaking TaintedHash to use the same API, and suggesting Rails 3 users look at this gem first.
I am porting an application that uses Carrierwave to Rails 4, but I have problems with strong params. I have a model with
accepts_nested_attributes_for :photos
Here is how CW passes uploaded images:
{
# ...
"model"=>
{
# ...
"photos_attributes"=>
{
"1362752177921"=>
{
"image"=>"test.jpg",
"title"=>"test",
"_destroy"=>"false"
}
}
}
}
However I can't seem to figure out how to write parameters that will accept photos_attributes
.
I have tried .permit(photos_attributes: {})
but it simply skips everything inside the photo params hash (image
, title
, _destroy
) . When I use permit!
, it might almost work, but first of all this is kinda lame. And then the uuid
that is created inside the model before saving doesn't appear in SQL on save and this is the second issue:
photos.uuid may not be NULL: INSERT INTO "photos" ("created_at", "model_id", "image", "title", "updated_at") VALUES (?, ?, ?, ?, ?)
Documentation is seriously lacking here and I am not even sure how to proceed.
How to accept an array of nested parameters? How to add additional parameters for nested models when saving?
My scenario involves two sets of controllers for v1 and v2 of an API. Both sets of controllers operate on the same models. I want the v1 controllers to continue using attr_accessible and for v2 to start using strong_parameters. Since using this gem requires patching each of the models (or ActiveRecord::Base), I'm wondering what the right pattern to use might be for accomplishing what I want .. or if this is even possible.
Thoughts?
It would be nice (as a default option) if development mode was loud about unpermitted parameters.
Started POST "/users/2"...
...
Parameters: ... POST "user"=>{"first_name"=>"Joe", "last_name"=>"Bob"}
...
params.require(:user).permit(:first, :last)
As a developer I'd like to see this blow up with some meaningful explanation:
"Received unpermitted parameter first_name..."
I'm willing to throw some time at this if it seems like a reasonable idea.
The nested params tests fail if a non-numeric parameter similar to the following is added:
test "fields_for_style_nested_params" do
params = ActionController::Parameters.new({
book: {
authors_attributes: {
:'0' => { name: 'William Shakespeare', age_of_death: '52' },
:'1' => { name: 'Unattributed Assistant' },
:new => { name: 'Failing' } # <== ADDED
}
}
})
permitted = params.permit book: { authors_attributes: [ :name ] } # <== permitted is: {"book"=>{"authors_attributes"=>{}}}
assert_not_nil permitted[:book][:authors_attributes]['0']
assert_not_nil permitted[:book][:authors_attributes]['1']
assert_nil permitted[:book][:authors_attributes]['0'][:age_of_death]
assert_equal 'William Shakespeare', permitted[:book][:authors_attributes]['0'][:name]
assert_equal 'Unattributed Assistant', permitted[:book][:authors_attributes]['1'][:name]
end
Turns out that one illegal key (:new) will do away with the entire authors_attributes hash in permitted
. Is this behavior intentional?
Wouldn't it be better if only the illegal key were dropped and the other valid keys (:'0' and :'1') remained in the hash?
(I'm getting such a :new key in a project of mine because the same fields_for partial is used for both existing as well as newly added nested records. In order to do that, the template requires a child index and all numerical ones are already in use; 0 up for existing, -1 and below for new records.)
Did I do something wrong or must I set at least one permitted param to disallow everything else? From my understanding of the readme, everything not explicitly allowed should be rejected, but in my app both
@comment = @entry.comments.new text: params[:comment][:text]
and
@comment = @entry.comments.new params[:comment]
didn't raised any exception. Only after
@comment = @entry.comments.new params.required(:comment).allowed(:status)
I've got a 422 Unprocessable Entity (tried to mass assign comment[text]
)
Of course it would be really nice, if strong_parameters would allow the first example, but I didn't expected it to do so. The second example shouldn't work, should it?
Is there any way to have ActiveModel::ForbiddenAttributesProtection by default in all models instead of having to explicitly add the line to every single model?
Ryan Bates from Railscasts gives this example:
#create ./initializers/strong_parameters.rb with:
ActiveRecord::Base.send(:include, ActiveModel::ForbiddenAttributesProtection)
But this depends on ActiveRecord and doesn't work with Mongoid.
Any more uniform approach or a workaround for Mongoid?
Not really an issue, but I think it won’t hurt to add the fact ActiveModel::ForbiddenAttributesProtection has to be included in the target model in the README :) (I was wondering why my model was accepting any parameters)
I'm trying to figure out a good solution for handling nested attribute parameters coming in through the controller and wanted to get some input from you guys. While there is now support for nested parameters, it doesn't currently play nice with form#fields_for
and ActiveRecord nested attributes.
As an example, here are the parameters that get submitted for a Parent that has many Children:
{
"parent" => {
"children_attributes" => {
"0" => {"id" => "1", "public" => "Public", "private" => "Private" },
"1" => {"id" => "2", "public" => "Public", "private" => "Private" }
}
}
}
With the current implementation of permit
and nested parameters, I need to first convert nested attributes into an array using code similar to what already exists in ActiveRecord: https://github.com/rails/rails/blob/master/activerecord/lib/active_record/nested_attributes.rb#L398
def permitted_params
params[:parent][:children_attributes] = params[:parent][:children_attributes].values
params.required(:parent).permit(:children_attributes => [:public])
end
Should this be a feature included in strong_parameters to play nicely with ActiveRecord nested attributes? I'm happy to start working on it, but would love any feedback on whether or not it should be included before diving in :)
Thanks!
In 0.1.6, the following code worked in whitelisting a key that represents a collection of values:
params.require(:mode).permit(:collection_ids)
As of 0.2.0, the above code no longer white-lists the collection_ids
key, and the following code is necessary:
params.require(:mode).permit({:collection_ids => []})
Is this intended functionality, or a regression?
If one has a simple params def like this
def book_params
params.require(:book).permit(:a, :b, :c)
end
and pass parameter book with empty hash or parameters that get deleted individually such as position it will returns a 400 error.
patch request {:book => {:position => 2 } }
def update
position = params[:book][:position].delete
if @book.update_attributes(book_params)
@book.insert_at(new_position)
#etc
end
This seems counter intuitive since if you are dealing with a PATCH request it is feasible that the only parameters passed might be deleted from the hash but still be a valid request and that other requests to the same url might need the definition in place.
It should be acceptable that a hash is passed with neither permitted nor non permitted parameters should pass and not return a 400 error.
Since the date form helpers use parameters like published_at(1i)
, published_at(2i)
, etc, calling params.permit(:published_at)
fails. Our current solution is to just list the generated parameter names in the permit call, but it might be worth revisiting this at some point.
On rails 3.2.11, putting the following in config/application.rb
config.action_controller.action_on_unpermitted_parameters = :raise
raises an exception
undefined method `action_on_unpermitted_parameters=' for ActionController::Base:Class
Am I doing something wrong?
I'm running strong_parameters 0.2.0, rails 3.2.12 and ruby 2.0:
$ rails c
Loading development environment (Rails 3.2.12)
[1] pry(main)> raw_params = {"layout"=>"layout_04", "zone_ids"=>["", "", "", "50e5a81a421aa977fa00000b"]}
=> {"layout"=>"layout_04", "zone_ids"=>["", "", "", "50e5a81a421aa977fa00000b"]}
[2] pry(main)> params = ActionController::Parameters.new(raw_params)
=> {"layout"=>"layout_04", "zone_ids"=>["", "", "", "50e5a81a421aa977fa00000b"]}
[3] pry(main)> params.permit(:zone_ids)
=> {}
It seems this works with strong_parameters 0.1.6 but not with 0.2.0.
Any ideas?
The following snippet illustrates this behavior:
params = ActionController::Parameters.new(:user => {})
params.require(:user) # raises exception
# ActionController::ParameterMissing: key not found: user
Granted this is an edge case, but it does make using #require when all parameters underneath :user are optional a bit unwieldy.
Would it be reasonable to turn:
def require(key)
self[key].presence || raise(ActionController::ParameterMissing.new(key))
end
into something like:
def require(key)
found = self[key]
raise(ActionController::ParameterMissing.new(key)) unless found.is_a?(Hash)
found
end
@dhh I already configured it but I think someone with administrative rights have to enable in the Travis application
I feel as if this is probably my own fault and I'm just too stupid to notice, but I can't seem to get Strong Parameters to work in production using Unicorn.
The Unicorn workers won't start, failing with uninitialized constant ActiveModel::ForbiddenAttributesProtection (NameError)
I've attached the full log here.
I've got gem 'strong_parameters'
in my Gemfile,
and I've got include ActiveModel::ForbiddenAttributesProtection
in my model.
Everything works fine locally, and even if I load up the Rails console in Production. It's only when Unicorn tries to spawn that it fails.
Any help would be greatly appreciated.
Hello!
gem 'strong_parameters'
bundle
the_teacher@work:~/rails/rails4/TheApp$ bundle exec rails s
/home/the_teacher/.rvm/gems/ruby-1.9.3-p0@rails4/gems/strong_parameters-0.1.4/lib/action_controller/parameters.rb:6:in `module:ActionController': superclass mismatch for class ParameterMissing (TypeError)
from /home/the_teacher/.rvm/gems/ruby-1.9.3-p0@rails4/gems/strong_parameters-0.1.4/lib/action_controller/parameters.rb:5:in `<top (required)>'
from /home/the_teacher/.rvm/gems/ruby-1.9.3-p0@rails4/gems/strong_parameters-0.1.4/lib/strong_parameters.rb:1:in `require'
from /home/the_teacher/.rvm/gems/ruby-1.9.3-p0@rails4/gems/strong_parameters-0.1.4/lib/strong_parameters.rb:1:in `<top (required)>'
from /home/the_teacher/.rvm/gems/ruby-1.9.3-p0@global/gems/bundler-1.2.3/lib/bundler/runtime.rb:68:in `require'
Somebody can helps me?
Tnx!
Bundler just gave me a newer version of strong_parameter which throws TypeError
with can't convert Symbol into String
when i call params.permit(...)
in my controller.
org/jruby/RubyRegexp.java:749:in `quote'
strong_parameters (0.1.5) lib/action_controller/parameters.rb:47:in `permit'
org/jruby/RubyArray.java:1620:in `each'
strong_parameters (0.1.5) lib/action_controller/parameters.rb:43:in `permit'
app/controllers/user/my_controller.rb:59:in `my_object_params'
...
Besides, how is it that i cannot find v0.1.5 within the github repo?
I'm on JRuby-1.6.8 and Rails-3.2.8.
cheers
-- dpree
Rails Params Parsing is magic. You never know what it can lead to. Nested hash in params[:id], Array full of nils etc.
User.find_by_token(params[:token])
can find a user with empty token if we provide params[:token]=[nil] or [1,nil]. It was possible half a year ago, and then 'reinvented' with JSON/XML params parsers.find_by_username_and_password(params[:username], sha(params[:password))
Thus we need a reliable tool to get exact structure of params we asked for. Some people suggest to stringify it in ActiveRecord and find_by_ should accept only strings - i think it's just killing useful tool for no reason.
Maybe strong_params should control all incoming params(before_filter), not only for mass assignment purposes? e.g.
class PeopleController < ActionController::Base
params.require(:person).permit(:name, :age)
def search
Person.find_by_age(params[:person][:age]) #if we pass ?person[age][]=1&person[age][]=2&person[age][]=3 it will be casted to "[1,2,3]"
If developer needs nested structures he will specify it explicitly in controller. Not so agile, but user input is the last thing that should be agile. will fix rails/rails#8831 and possible future vulnerabilities in params, once and for all.
P.S I might be wrong thinking developer expects static structure - please point out if there are use cases with agile and random structure
I would expect that calling :slice
on a permitted Parameters hash would return another permitted hash, just as :except
does. But no:
> params = ActionController::Parameters.new(:foo => 42, :bar => 1337).permit(:foo, :bar)
=> {"foo"=>42, "bar"=>1337}
> params.except(:bar).permitted?
=> true
> params.slice(:foo).permitted?
=> false
Is this a feature, or is it a bug?
After calling permit with permitted parameters set, exception is not raised even when someone tries to set forbidden attribute. So success message is displayed to user, but attribute actually is unchanged.
Is it expected behaviour or something that should be fixed?
Using current API, it's not really possible to do a sane check for a nested param. Consider the following check:
params.require(:user).require(:id)
If you now supply ?user=test
as a param, the second require call will be sent to a string instance.
This could be solved if require would support nested syntax, i.e.:
params.require("user.id")
The above syntax would make code more readable for deeper nested params: params.require(:user).require(:book).require(:authorization).require(:token)
becomes
params.require('user.book.authorization.token')
Any thoughts?
Controllers should return a bad request or forbidden if someone sends things that are not allowed.
Given the recent chain of parameter-parsing security vulnerabilities in Rails, is it a good idea to allow Symbols as acceptable scalar values?
Is there a way to enable and disable strong_parameters via a flag? If not, do you think it would be a good idea?
For example, in the ActiveAdmin gem, we added a proposed patch that extends the controller when a method is called to extend it that makes the controller call permit appropriately.
However, I don't know of a way to use the strong_parameters gem in some places and not others within the tests without having to do some serious work to stop Rails, uninstall the gem, start Rails, test, stop Rails, install the gem, start Rails, etc.
It would be nice to have a flag that we could just flip in a test such that permit is not required if set to false and is required if set to true, similar to config.active_record.whitelist_attributes was for mass assignment security in Rails 3.
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.