To whom it may concern:
A rather informal advisory on Fat Free CRM (http://fatfreecrm.com/):
Timeline:
Aug 27th 2013 Initial email containing the findings listed below
including a note that there more vulnerabilities
which just need to be verified. (Send to
mike@fatfreecrm.com and security@fatfreecrm.com)
Sep 16th 2013 No response so far (not even a bounce of the initial
mail), re-send email of Aug. 27th.
Dec 20th 2013 Still no response.
Dec 24th 2013 Public Disclosure.
Hint: Actually the codebase is full of Ruby on Rails worst practices.
You might want to use it as a sample "Hack Me" application.
---
1. Known Session Secret
In config/initialiers/secret_token.rb a static secret token is defined,
with the knowledge of this token an attacker is able to execute
arbitrary Ruby code server side.
2. Lack of CSRF Protection
In app/controllers/application_controller.rb the protect_from_forgery
statement is missing, therefore Fat Free CRM is vulnerable to CSRF
attacks.
3. Default to_json for models
The users controller renders JSON requests with a full JSON object:
For instance when being logged in to the demo app and requesting
http://demo.fatfreecrm.com/users/1.json, the response would be
{
"user": {
"admin": true,
"aim": "",
"alt_email": "",
"company": "example",
"created_at": "2012-02-12T02:00:00+02:00",
"current_login_at": "2013-08-26T22:12:05+03:00",
"current_login_ip": "61.143.60.146",
"deleted_at": null,
"email": "aaron@example.com",
"first_name": "Aaron",
"google": "",
"id": 1,
"last_login_at": "2013-08-24T22:20:06+03:00",
"last_login_ip": "122.173.185.99",
"last_name": "Assembler",
"last_request_at": "2013-08-26T22:13:35+03:00",
"login_count": 481,
"mobile": "(800)555-1211",
"password_hash": "56d91c9f1a9c549304768982fd4e2d8bc2700b403b4524c0f14136dbbe2ce4cd923156ad69f9acce8305dba4e63faa884e61fb7a256cf8f5fc7c2ce176e68e8f",
"password_salt": "ce6e0200c96f4dd326b91f3967115a31421a0e7dcddc9ffb63a77f598a9fcb5326fe532dbd9836a2446e46840d398fa32c81f8f4da1a0fcfe931989e9639a013",
"perishable_token": "NE0n6wUCumVNdQ24ahRu",
"persistence_token": "d7cdeffd3625f7cb265b21126b85da7c930d47c4a708365c20eb857560055a6b57c9775becb8a957dfdb46df8aee17eb120a011b380e9cc0882f9dfaa2b7ba26",
"phone": "(800)555-1210",
"single_access_token": "TarXlrOPfaokNOzls2U8",
"skype": "ranzitreddy",
"suspended_at": null,
"title": "VP of Sales",
"updated_at": "2013-08-26T22:13:35+03:00",
"username": "aaron",
"yahoo": ""
}
}
A custom to_json method which sanitizes the output should be created.
4. Multiple SQL Injections
In app/controllers/home_controller.rb:
def timeline
unless params[:type].empty?
model = params[:type].camelize.constantize
item = model.find(params[:id])
item.update_attribute(:state, params[:state])
else
comments, emails = params[:id].split("+")
Comment.update_all("state = '#{params[:state]}'", "id IN
(#{comments})") unless comments.blank?
Email.update_all("state = '#{params[:state]}'", "id IN
(#{emails})") unless emails.blank?
end
render :nothing => true
end
Here params[:state], comments and emails are attacker controlled values
which go directly into SQL statements. Therefore this piece of code
exposes a SQL Injection vulnerability.
---
Static URL of this text:
http://www.phenoelit.org/stuff/ffcrm.txt
Happy Holidays,
joernchen
--
joernchen ~ Phenoelit
<joernchen@phenoelit.de> ~ C776 3F67 7B95 03BF 5344
http://www.phenoelit.de ~ A46A 7199 8B7B 756A F5AC