SlideShare a Scribd company logo
10 RULES
FOR
SAFER
CODEOlivier Dony
@odony
Yet another
security issue?!
RULE #1
EVAL is EVIL
Don’t trust strings supposed to contain expressions or code
(even your own!)
“eval” breaks the barrier between
code and data
Is this safe?
Maybe… it depends.
Is it a good idea?
No, because eval() is not necessary!
There are safer and smarter ways
to parse data in PYTHON
“42” int(x)
float(x)
Parse it
like this
“[1,2,3,true]”
json.loads(x)
‘{“widget”: “monetary”}’
“[1,2,3,True]” ast.literal_eval(x)
”{‘widget’: ‘monetary’}”
Given this
string
There are safer and smarter ways
to parse data in JAVASCRIPT
“42” parseInt(x)
parseFloat(x)
Given this
string Parse it
like this
“[1,2,3,true]”
JSON.parse(x)
‘{“widget”: “monetary”}’
If you must eval parameters
use a safe eval method
# YES
from odoo.tools import safe_eval
res = safe_eval(’foo’, {’foo’: 42});
# NO
from odoo.tools import safe_eval as eval
res = eval(’foo’, {’foo’: 42});
PYTHON
Alias built-in eval as ”unsafe_eval”
Show your meaning!
# YES
unsafe_eval = eval
res = unsafe_eval(trusted_code);
# NO!
res = eval(trusted_code);
Import as ”safe_eval”, not as ”eval”!
If you must eval parameters
use a safe eval method
JAVASCRIPT
// py.js is included by default
py.eval(’foo’, {’foo’: 42});
// require(”web.pyeval”) for
// domains/contexts/groupby evaluation
pyeval.eval(’domains’, my_domain);
Do not use the built-in JS eval!
50%of vulnerabilities found every year include
remote code execution injected via
unsafe eval
RULE #2
YOU SHALL NOT
PICKLE
Don’t use it. Ever. Use JSON.
“Warning: The pickle module is not intended 
to be secure against erroneous or maliciously 
constructed data. Never unpickle data 
received from an untrusted or 
unauthenticated source.
Python’s pickle serialization is:
+unsafe +not portable
+human-unreadable
pickle.dumps({“widget”:“monetary”}) == "(dp0nS'widget'np1nS'monetary'np2ns."
Actually a
stack-based
language!
Pickle is unsafe
Seriously.
>>> yummy = "cosnsystemn(S'cat /etc/shadow | head -n 5'ntR.'ntR."
>>> pickle.loads(yummy)
root:$6$m7ndoM3p$JRVXomVQFn/KH81DEePpX98usSoESUnml3e6Nlf.:14951:0:99999:7:::
daemon:x:14592:0:99999:7:::
(…)
>>>
Use JSON instead!
json.dumps({“widget”:“monetary”}) == '{"widget": "monetary"}'
+safe +portable
+human-readable
RULE #3
USE THE CURSOR
WISELY
Use the ORM API. And when you can’t, use query parameters.
SQL injection is a classical privilege
escalation vector
self.search(domain)The ORM is here to help you build safe
queries:
Psycopg can also help you do that , if you tell
it what is code and what is data:
query = ”””SELECT * FROM res_partner
WHERE id IN %s”””
self._cr.execute(query, (tuple(ids),))
SQL code
SQL data parameters
Learn the API to avoid hurting
yourself
and
other people!
This method is vulnerable
to SQL injection
def compute_balance_by_category(self, categ=’in’):
query = ”””SELECT sum(debit-credit)
FROM account_invoice_line l
JOIN account_invoice i ON (l.invoice_id = i.id)
WHERE i.categ = ’%s_invoice’
GROUP BY i.partner_id ”””
self._cr.execute(query % categ)
return self._cr.fetchall()
What if someone calls it with
categ = ”””in_invoice’; UPDATE res_users
SET password = ’god’ WHERE id=1; SELECT
sum(debit-credit) FROM account_invoice_line
WHERE name = ’”””
This method is still vulnerable
to SQL injection
def _compute_balance_by_category(self, categ=’in’):
query = ”””SELECT sum(debit-credit)
FROM account_invoice_line l
JOIN account_invoice i ON (l.invoice_id = i.id)
WHERE i.categ = ’%s_invoice’
GROUP BY i.partner_id ”””
self._cr.execute(query % categ)
return self._cr.fetchall()
Better, but it could still be called
indirectly!
Now
private!
This method is safe against
SQL injection
def _compute_balance_by_category(self, categ=’in’):
categ = ’%s_invoice’ % categ
query = ”””SELECT sum(debit-credit)
FROM account_invoice_line l
JOIN account_invoice i ON (l.invoice_id = i.id)
WHERE i.categ = %s
GROUP BY i.partner_id ”””
self._cr.execute(query, (categ,))
return self._cr.fetchall()
Separates code
and parameters!
RULE #4
Fight XSS
So many XSS vectors – gotta watch ’em all
Browsers blur the distinction between
code and data!
Most XSS errors are trivial:
QWeb templates
t-raw vs t-esc / t-field
Only use it to insert HTML code
that has been prepared and
escaped by the framework.
Never use it to insert text.
For everything else, use:
• t-esc: variables, URL parameters, …
• t-field: record data
Most XSS errors are trivial:
DOM manipulations (JQuery)
$elem.html(value) vs $elem.text(value)
Only use it to insert HTML code
that has been prepared and
escaped by the framework.
Never use it to insert text.
For everything else, use:
• t-esc: variables, URL parameters, …
• t-field: record data
    @http.route('/web/binary/upload', type='http', auth="user")
    @serialize_exception
    def upload(self, callback, ufile):
        out = """<script language="javascript" type="text/javascript">
                    var win = window.top.window;
                    win.jQuery(win).trigger(%s, %s);
                </script>"""
  # (...)      
        return out % (json.dumps(callback), json.dumps(args))
Some XSS are less obvious: callbacks
JSON escaping is not sufficient to prevent XSS,
because of the way browsers parse documents!
/web/binary/upload?callback=</script><script>alert(’This works!');//
Users can often upload arbitrary files : contact forms, email
gateway, etc.
Upon download, browsers will happily detect the file type and
execute anything that remotely looks like HTML, even if
you return it with an image mime-type !
Some XSS are less obvious: uploads
<svg xmlns="http://www.w3.org/2000/svg">
<script type="text/javascript">alert(’XSS!!’);</script>
</svg>A valid
SVG image
file!
RULE #5
GUARD PASSWORDS
& tokens fiercely
Secure all user and API tokens, and don’t leak them
Where should we store precious tokens for
external APIs?
On the res.users record of the user!
On the res.company record!
On the record representing the API
endpoint, like the acquirer record!
In the ir.config_parameter
table!
Wherever it makes the most sense, as long as it’s
not readable by anyone!
(field-level group, ACLs, ICP groups, etc.)
Avoid leaking
user cookies
and Session ID
Do not over-Sudo IT
RULE #6
Review 2x your sudo() usage, particularly controllers/public methods
Do you think this form is safe?
Not if it blindly takes the form POST
parameters and calls write() in
sudo mode!
RULE #7
CSRF tokens FOR
website forms
HTTP Posts require CSRF tokens since v9.0
Do you think this form is safe
from CSRF attacks?
As of Odoo 9, HTTP POST controllers
are CSRF-protected
Do not bypass it with GET controllers
that act like POST!
RULE #8
MASTER thE RULES
Odoo ACL and Rules are not trivial, be sure to understand them
Odoo ACLs are not always trivial
user

group B

group A
data
 C
 R
 U
 D
 C
 R
 U
 D
 C
 R
 U
 D
Group
Access Rights
(ir.model.access)
Group
Access Rule
(ir.rule)
Global
Access Rule
(ir.rule)
  123
Per-modelPer-record
ACCESS
DENIED
Odoo ACLs are not always trivial
user

group B

group A
data  C
 R
 U
 D
 C
 R
 U
 D
 C
 R
 U
 D
Group
Access Rule
(ir.rule)
Global
Access Rule
(ir.rule)
  123
Per-modelPer-record
ACCESS
GRANTED
Group
Access Rights
(ir.model.access)
Odoo ACLs are not always trivial
user

group B

group A
data
 C
 R
 U
 D
 C
 R
 U
 D
Group
Access Rule
(ir.rule)
Global
Access Rule
(ir.rule)
  123
Per-modelPer-record
ACCESS
GRANTED
Group
Access Rights
(ir.model.access)
Odoo ACLs are not always trivial
user

group B

group A
data
 C
 R
 U
 D
 C
 R
 U
 D
Group
Access Rule
(ir.rule)
Global
Access Rule
(ir.rule)
  123
Per-modelPer-record
 C
 R
 U
 D
ACCESS
DENIED
Group
Access Rights
(ir.model.access)
Odoo ACLs are not always trivial
user

group B

group A
data
 C
 R
 U
 D
Group
Access Rule
(ir.rule)
Global
Access Rule
(ir.rule)
  123
Per-modelPer-record
ACCESS
GRANTED
Group
Access Rights
(ir.model.access)
RULE #9
There are better and safer alternatives
Getattr is NOT
YOUR FRIEND
Do NOT do this:
def _get_it(self, field=’partner_id’):
return getattr(record, field)
Try this instead:
def _get_it(self, field=’partner_id’):
return record[field]
By passing arbitrary field values, an
attacker could gain access to dangerous
methods!
This will only work with valid field values
RULE #10
Do NOT open(), urlopen(), requests.post(), … an arbitrary URL/Path!
OPEN WITH CARE
Summary
1. Eval is evil
2. You shall not pickle
3. Use the cursor wisely
4.Fight XSS
5. Guard passwords & tokens fiercely
6.Do not over-sudo it
7.CSRF tokens for weBsite forms
8.master THE rules
9.Getattr is not your friend
10.OPEN WITH care
security@odoo.com

More Related Content

PPT
Php Security By Mugdha And Anish
PDF
SQL Injection: complete walkthrough (not only) for PHP developers
PDF
SQL Injection Tutorial
PDF
ORM Injection
PPT
Advanced Topics On Sql Injection Protection
PDF
ORM2Pwn: Exploiting injections in Hibernate ORM
PDF
Not so blind SQL Injection
PDF
Advanced SQL Injection: Attacks
Php Security By Mugdha And Anish
SQL Injection: complete walkthrough (not only) for PHP developers
SQL Injection Tutorial
ORM Injection
Advanced Topics On Sql Injection Protection
ORM2Pwn: Exploiting injections in Hibernate ORM
Not so blind SQL Injection
Advanced SQL Injection: Attacks

What's hot (20)

PPTX
SQL Injections - 2016 - Huntington Beach
PPTX
Time-Based Blind SQL Injection
PPT
Time-Based Blind SQL Injection using Heavy Queries
PDF
What is advanced SQL Injection? Infographic
PDF
New methods for exploiting ORM injections in Java applications
PPTX
03. sql and other injection module v17
PDF
Sql Injection - Vulnerability and Security
DOCX
Types of sql injection attacks
PDF
Defcon 17-joseph mccray-adv-sql_injection
PDF
Rabin Shrestha: Data Validation and Sanitization in WordPress
PDF
SQL Injection
PDF
JSMVCOMFG - To sternly look at JavaScript MVC and Templating Frameworks
PDF
Sql Injection and XSS
KEY
PHP security audits
PPTX
Sql Injection V.2
PDF
Php Security
PPTX
JSON SQL Injection and the Lessons Learned
PPT
PHP Security
PDF
Practical Approach towards SQLi ppt
PDF
SQL Injections - 2016 - Huntington Beach
Time-Based Blind SQL Injection
Time-Based Blind SQL Injection using Heavy Queries
What is advanced SQL Injection? Infographic
New methods for exploiting ORM injections in Java applications
03. sql and other injection module v17
Sql Injection - Vulnerability and Security
Types of sql injection attacks
Defcon 17-joseph mccray-adv-sql_injection
Rabin Shrestha: Data Validation and Sanitization in WordPress
SQL Injection
JSMVCOMFG - To sternly look at JavaScript MVC and Templating Frameworks
Sql Injection and XSS
PHP security audits
Sql Injection V.2
Php Security
JSON SQL Injection and the Lessons Learned
PHP Security
Practical Approach towards SQLi ppt
Ad

Similar to 10 Rules for Safer Code (20)

PDF
Web Security 101
PPTX
Security: Odoo Code Hardening
PDF
Slides
 
PPTX
Sql injection
PDF
Rails and security
PPTX
DevBeat 2013 - Developer-first Security
PDF
PHP Secure Programming
PPT
Eight simple rules to writing secure PHP programs
PPT
PHPUG Presentation
PDF
OWASP Top 10 - DrupalCon Amsterdam 2019
PPTX
Web Security - Hands-on
PDF
Rails Security
PDF
Security in Node.JS and Express:
PDF
Whatever it takes - Fixing SQLIA and XSS in the process
PPTX
Let's write secure Drupal code! - DrupalCamp London 2019
PPTX
07 application security fundamentals - part 2 - security mechanisms - data ...
PPTX
Becoming a SOC2 Ruby Shop - Montreal.rb November, 5, 2022 Ruby Meetup
PDF
The top 10 security issues in web applications
PPT
Application Security
Web Security 101
Security: Odoo Code Hardening
Slides
 
Sql injection
Rails and security
DevBeat 2013 - Developer-first Security
PHP Secure Programming
Eight simple rules to writing secure PHP programs
PHPUG Presentation
OWASP Top 10 - DrupalCon Amsterdam 2019
Web Security - Hands-on
Rails Security
Security in Node.JS and Express:
Whatever it takes - Fixing SQLIA and XSS in the process
Let's write secure Drupal code! - DrupalCamp London 2019
07 application security fundamentals - part 2 - security mechanisms - data ...
Becoming a SOC2 Ruby Shop - Montreal.rb November, 5, 2022 Ruby Meetup
The top 10 security issues in web applications
Application Security
Ad

More from Quang Ngoc (20)

PDF
Bản Đồ Thành Công
PDF
Odoo Implementation Methodology
PDF
The Agile BA (Business Analyst)
PDF
Hướng dẫn sử dụng hệ điều hành Ubuntu
PDF
Hướng dẫn sử dụng Outlook 2010
PDF
Hướng dẫn sử dụng Power Point 2010
PDF
Hướng dẫn sử dụng Excel 2010
PDF
Hướng dẫn sử dụng Word 2010
PPTX
Tính giá thành sản phẩm
PDF
Manage IT as a Business
PDF
Tóm tắt lệnh Ubuntu
PDF
Hạt Giống Tâm Hồn - Tập 11 - Những trải nghiệm cuộc sống
PDF
Hạt Giống Tâm Hồn - Tập 10 - Theo dòng thời gian
PDF
Hạt Giống Tâm Hồn - Tập 9 - Vượt qua thử thách
PDF
Hạt Giống Tâm Hồn - Tập 8 - Những câu chuyện cuộc sống
PDF
Hạt Giống Tâm Hồn - Tập 7 - Những câu chuyện cuộc sống
PDF
Hạt Giống Tâm Hồn - Tập 6 - Ý nghĩa cuộc sống
PDF
Hạt Giống Tâm Hồn - Tập 5 - Ý nghĩa cuộc sống
PDF
Hạt Giống Tâm Hồn - Tập 4 - Từ Những Điều Bình Dị
PDF
Hạt Giống Tâm Hồn - Tập 3 - Từ những điều bình dị
Bản Đồ Thành Công
Odoo Implementation Methodology
The Agile BA (Business Analyst)
Hướng dẫn sử dụng hệ điều hành Ubuntu
Hướng dẫn sử dụng Outlook 2010
Hướng dẫn sử dụng Power Point 2010
Hướng dẫn sử dụng Excel 2010
Hướng dẫn sử dụng Word 2010
Tính giá thành sản phẩm
Manage IT as a Business
Tóm tắt lệnh Ubuntu
Hạt Giống Tâm Hồn - Tập 11 - Những trải nghiệm cuộc sống
Hạt Giống Tâm Hồn - Tập 10 - Theo dòng thời gian
Hạt Giống Tâm Hồn - Tập 9 - Vượt qua thử thách
Hạt Giống Tâm Hồn - Tập 8 - Những câu chuyện cuộc sống
Hạt Giống Tâm Hồn - Tập 7 - Những câu chuyện cuộc sống
Hạt Giống Tâm Hồn - Tập 6 - Ý nghĩa cuộc sống
Hạt Giống Tâm Hồn - Tập 5 - Ý nghĩa cuộc sống
Hạt Giống Tâm Hồn - Tập 4 - Từ Những Điều Bình Dị
Hạt Giống Tâm Hồn - Tập 3 - Từ những điều bình dị

Recently uploaded (20)

PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PDF
Digital Strategies for Manufacturing Companies
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PDF
Which alternative to Crystal Reports is best for small or large businesses.pdf
PPTX
ManageIQ - Sprint 268 Review - Slide Deck
PDF
medical staffing services at VALiNTRY
PDF
System and Network Administraation Chapter 3
PDF
System and Network Administration Chapter 2
PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PDF
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PDF
Nekopoi APK 2025 free lastest update
PPTX
history of c programming in notes for students .pptx
PDF
Softaken Excel to vCard Converter Software.pdf
PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PPTX
Introduction to Artificial Intelligence
PPTX
CHAPTER 2 - PM Management and IT Context
PDF
AI in Product Development-omnex systems
PDF
How Creative Agencies Leverage Project Management Software.pdf
PDF
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
Internet Downloader Manager (IDM) Crack 6.42 Build 41
Digital Strategies for Manufacturing Companies
How to Choose the Right IT Partner for Your Business in Malaysia
Which alternative to Crystal Reports is best for small or large businesses.pdf
ManageIQ - Sprint 268 Review - Slide Deck
medical staffing services at VALiNTRY
System and Network Administraation Chapter 3
System and Network Administration Chapter 2
How to Migrate SBCGlobal Email to Yahoo Easily
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
Nekopoi APK 2025 free lastest update
history of c programming in notes for students .pptx
Softaken Excel to vCard Converter Software.pdf
Adobe Illustrator 28.6 Crack My Vision of Vector Design
Introduction to Artificial Intelligence
CHAPTER 2 - PM Management and IT Context
AI in Product Development-omnex systems
How Creative Agencies Leverage Project Management Software.pdf
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf

10 Rules for Safer Code

  • 3. RULE #1 EVAL is EVIL Don’t trust strings supposed to contain expressions or code (even your own!)
  • 4. “eval” breaks the barrier between code and data Is this safe? Maybe… it depends. Is it a good idea? No, because eval() is not necessary!
  • 5. There are safer and smarter ways to parse data in PYTHON “42” int(x) float(x) Parse it like this “[1,2,3,true]” json.loads(x) ‘{“widget”: “monetary”}’ “[1,2,3,True]” ast.literal_eval(x) ”{‘widget’: ‘monetary’}” Given this string
  • 6. There are safer and smarter ways to parse data in JAVASCRIPT “42” parseInt(x) parseFloat(x) Given this string Parse it like this “[1,2,3,true]” JSON.parse(x) ‘{“widget”: “monetary”}’
  • 7. If you must eval parameters use a safe eval method # YES from odoo.tools import safe_eval res = safe_eval(’foo’, {’foo’: 42}); # NO from odoo.tools import safe_eval as eval res = eval(’foo’, {’foo’: 42}); PYTHON Alias built-in eval as ”unsafe_eval” Show your meaning! # YES unsafe_eval = eval res = unsafe_eval(trusted_code); # NO! res = eval(trusted_code); Import as ”safe_eval”, not as ”eval”!
  • 8. If you must eval parameters use a safe eval method JAVASCRIPT // py.js is included by default py.eval(’foo’, {’foo’: 42}); // require(”web.pyeval”) for // domains/contexts/groupby evaluation pyeval.eval(’domains’, my_domain); Do not use the built-in JS eval!
  • 9. 50%of vulnerabilities found every year include remote code execution injected via unsafe eval
  • 10. RULE #2 YOU SHALL NOT PICKLE Don’t use it. Ever. Use JSON.
  • 12. Python’s pickle serialization is: +unsafe +not portable +human-unreadable pickle.dumps({“widget”:“monetary”}) == "(dp0nS'widget'np1nS'monetary'np2ns." Actually a stack-based language!
  • 13. Pickle is unsafe Seriously. >>> yummy = "cosnsystemn(S'cat /etc/shadow | head -n 5'ntR.'ntR." >>> pickle.loads(yummy) root:$6$m7ndoM3p$JRVXomVQFn/KH81DEePpX98usSoESUnml3e6Nlf.:14951:0:99999:7::: daemon:x:14592:0:99999:7::: (…) >>>
  • 14. Use JSON instead! json.dumps({“widget”:“monetary”}) == '{"widget": "monetary"}' +safe +portable +human-readable
  • 15. RULE #3 USE THE CURSOR WISELY Use the ORM API. And when you can’t, use query parameters.
  • 16. SQL injection is a classical privilege escalation vector self.search(domain)The ORM is here to help you build safe queries: Psycopg can also help you do that , if you tell it what is code and what is data: query = ”””SELECT * FROM res_partner WHERE id IN %s””” self._cr.execute(query, (tuple(ids),)) SQL code SQL data parameters
  • 17. Learn the API to avoid hurting yourself and other people!
  • 18. This method is vulnerable to SQL injection def compute_balance_by_category(self, categ=’in’): query = ”””SELECT sum(debit-credit) FROM account_invoice_line l JOIN account_invoice i ON (l.invoice_id = i.id) WHERE i.categ = ’%s_invoice’ GROUP BY i.partner_id ””” self._cr.execute(query % categ) return self._cr.fetchall() What if someone calls it with categ = ”””in_invoice’; UPDATE res_users SET password = ’god’ WHERE id=1; SELECT sum(debit-credit) FROM account_invoice_line WHERE name = ’”””
  • 19. This method is still vulnerable to SQL injection def _compute_balance_by_category(self, categ=’in’): query = ”””SELECT sum(debit-credit) FROM account_invoice_line l JOIN account_invoice i ON (l.invoice_id = i.id) WHERE i.categ = ’%s_invoice’ GROUP BY i.partner_id ””” self._cr.execute(query % categ) return self._cr.fetchall() Better, but it could still be called indirectly! Now private!
  • 20. This method is safe against SQL injection def _compute_balance_by_category(self, categ=’in’): categ = ’%s_invoice’ % categ query = ”””SELECT sum(debit-credit) FROM account_invoice_line l JOIN account_invoice i ON (l.invoice_id = i.id) WHERE i.categ = %s GROUP BY i.partner_id ””” self._cr.execute(query, (categ,)) return self._cr.fetchall() Separates code and parameters!
  • 21. RULE #4 Fight XSS So many XSS vectors – gotta watch ’em all
  • 22. Browsers blur the distinction between code and data!
  • 23. Most XSS errors are trivial: QWeb templates t-raw vs t-esc / t-field Only use it to insert HTML code that has been prepared and escaped by the framework. Never use it to insert text. For everything else, use: • t-esc: variables, URL parameters, … • t-field: record data
  • 24. Most XSS errors are trivial: DOM manipulations (JQuery) $elem.html(value) vs $elem.text(value) Only use it to insert HTML code that has been prepared and escaped by the framework. Never use it to insert text. For everything else, use: • t-esc: variables, URL parameters, … • t-field: record data
  • 25.     @http.route('/web/binary/upload', type='http', auth="user")     @serialize_exception     def upload(self, callback, ufile):         out = """<script language="javascript" type="text/javascript">                     var win = window.top.window;                     win.jQuery(win).trigger(%s, %s);                 </script>"""   # (...)               return out % (json.dumps(callback), json.dumps(args)) Some XSS are less obvious: callbacks JSON escaping is not sufficient to prevent XSS, because of the way browsers parse documents! /web/binary/upload?callback=</script><script>alert(’This works!');//
  • 26. Users can often upload arbitrary files : contact forms, email gateway, etc. Upon download, browsers will happily detect the file type and execute anything that remotely looks like HTML, even if you return it with an image mime-type ! Some XSS are less obvious: uploads <svg xmlns="http://www.w3.org/2000/svg"> <script type="text/javascript">alert(’XSS!!’);</script> </svg>A valid SVG image file!
  • 27. RULE #5 GUARD PASSWORDS & tokens fiercely Secure all user and API tokens, and don’t leak them
  • 28. Where should we store precious tokens for external APIs? On the res.users record of the user! On the res.company record! On the record representing the API endpoint, like the acquirer record! In the ir.config_parameter table! Wherever it makes the most sense, as long as it’s not readable by anyone! (field-level group, ACLs, ICP groups, etc.)
  • 30. Do not over-Sudo IT RULE #6 Review 2x your sudo() usage, particularly controllers/public methods
  • 31. Do you think this form is safe? Not if it blindly takes the form POST parameters and calls write() in sudo mode!
  • 32. RULE #7 CSRF tokens FOR website forms HTTP Posts require CSRF tokens since v9.0
  • 33. Do you think this form is safe from CSRF attacks? As of Odoo 9, HTTP POST controllers are CSRF-protected Do not bypass it with GET controllers that act like POST!
  • 34. RULE #8 MASTER thE RULES Odoo ACL and Rules are not trivial, be sure to understand them
  • 35. Odoo ACLs are not always trivial user  group B  group A data  C  R  U  D  C  R  U  D  C  R  U  D Group Access Rights (ir.model.access) Group Access Rule (ir.rule) Global Access Rule (ir.rule)   123 Per-modelPer-record ACCESS DENIED
  • 36. Odoo ACLs are not always trivial user  group B  group A data  C  R  U  D  C  R  U  D  C  R  U  D Group Access Rule (ir.rule) Global Access Rule (ir.rule)   123 Per-modelPer-record ACCESS GRANTED Group Access Rights (ir.model.access)
  • 37. Odoo ACLs are not always trivial user  group B  group A data  C  R  U  D  C  R  U  D Group Access Rule (ir.rule) Global Access Rule (ir.rule)   123 Per-modelPer-record ACCESS GRANTED Group Access Rights (ir.model.access)
  • 38. Odoo ACLs are not always trivial user  group B  group A data  C  R  U  D  C  R  U  D Group Access Rule (ir.rule) Global Access Rule (ir.rule)   123 Per-modelPer-record  C  R  U  D ACCESS DENIED Group Access Rights (ir.model.access)
  • 39. Odoo ACLs are not always trivial user  group B  group A data  C  R  U  D Group Access Rule (ir.rule) Global Access Rule (ir.rule)   123 Per-modelPer-record ACCESS GRANTED Group Access Rights (ir.model.access)
  • 40. RULE #9 There are better and safer alternatives Getattr is NOT YOUR FRIEND
  • 41. Do NOT do this: def _get_it(self, field=’partner_id’): return getattr(record, field) Try this instead: def _get_it(self, field=’partner_id’): return record[field] By passing arbitrary field values, an attacker could gain access to dangerous methods! This will only work with valid field values
  • 42. RULE #10 Do NOT open(), urlopen(), requests.post(), … an arbitrary URL/Path! OPEN WITH CARE
  • 43. Summary 1. Eval is evil 2. You shall not pickle 3. Use the cursor wisely 4.Fight XSS 5. Guard passwords & tokens fiercely 6.Do not over-sudo it 7.CSRF tokens for weBsite forms 8.master THE rules 9.Getattr is not your friend 10.OPEN WITH care