SlideShare ist ein Scribd-Unternehmen logo
1 von 35
JSON SQL Injection 
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 
and 
the Lessons Learned 
DeNA Co., Ltd. 
Kazuho Oku 
1
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 
Who am I? 
 Field: 
⁃ network and web-related architecture 
 Works: 
⁃ Palmscape / Xiino (web browser for Palm OS) 
⁃ Author of various Perl modules 
• Class::Accessor::Lite, HTTP::Parser::XS, 
Parallel::Prefork, Server::Starter, Starlet, 
Test::Mysqld, ... 
⁃ Author of various MySQL extensions 
• Q4M, mycached, ... 
⁃ Also the author of: 
• JSX, picojson, ... 
2
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 
Agenda 
 What is an SQL Query Builder? 
 JSON SQL Injection 
 SQL::QueryMaker and strict mode of SQL::Maker 
 The Lessons Learned 
3
What is an SQL Query Builder? 
4 
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 
What is an SQL Query Builder? 
 is a library for building SQL queries 
⁃ exists below or as a part of an object-relational 
mapping library (ORM) 
• ORM understands the semantics of the database 
schema / query builder does not 
5 
Application 
ORM Library 
SQL Query Builder 
Database API (DBI) 
Database Driver (DBD)
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 
Popular Implementations 
 SQL::Abstract 
 SQL::Interp 
 SQL::Maker 
⁃ used by Teng 
⁃ is today's main focus 
6 
Application 
ORM Library 
SQL Query Builder 
Database API (DBI) 
Database Driver (DBD)
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 
Query Builders are Great! 
 Easy to build query conditions 
⁃ by using hashrefs and arrayrefs 
⁃ arrayref is considered as IN queries 
• e.g. foo => [1,2,3] becomes `foo` IN (1,2,3) 
⁃ hashref is considered as (operator, value) pair 
• e.g. foo => { '<', 30 } becomes `foo`<30 
⁃ the API is common to the aforementioned query 
builders 
7
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 
Examples 
use SQL::Maker; 
... 
$maker->select('user', '*', { name => 'tokuhirom' }); 
# => SELECT * FROM `user` WHERE `name`='tokuhirom'; 
$maker->select('user', '*', { name => [ 'tokuhirom', 'yappo' ] }); 
# => SELECT * FROM `user` WHERE `name` IN ('tokuhirom','yappo'); 
$maker->select('user', '*', { age => { '>' => 30 } }); 
# => SELECT * FROM `user` WHERE `age`>30; 
$maker->delete('user', { name => 'sugyan' }); 
# => DELETE FROM `user` WHERE `name`='sugyan'; 
8
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 
Examples (cont’d) 
use SQL::Maker; 
... 
$maker->select('user', '*', { name => [ 'tokuhirom', 'yappo' ] }); 
# => SELECT * FROM `user` WHERE `name` IN ('tokuhirom','yappo'); 
$maker->select('user', '*', { name => [] }); 
# => SELECT * FROM `user` WHERE 1=0; 
$maker->select('user', '*', { 
age => 30, 
sex => 0, # male 
}); 
# => SELECT * FROM `user` WHERE `age`=30 AND `sex`=0; 
9
So What is JSON SQL Injection? 
10 
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 
The Problem 
 User-supplied input might not be the expected type 
# this API returns the entries of a blog (specified by $json->{blog_id}) 
my $json = decode_json($input); 
my ($sql, @binds) = $maker->select( 
'blog_entries', '*', { id => $json->{blog_id} }); 
my $rows = $dbi->selectall_arrayref($sql, { Slice => {} }, @binds); 
send_output_as_json([ map { +{ 
entry_id => $_->{id}, 
entry_title => $_->{title}, 
} } @$rows ]); 
11 
What if $json->{name} was not a scalar?
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 
The Problem (cont’d) 
 Will return a list of all blog entries if the supplied 
JSON was: { "blog_id": { "!=": -1 } } 
# this API returns the entries of a blog (specified by $json->{blog_id}) 
my $json = decode_json($input); 
# generated query: SELECT * FROM `blog_entries` WHERE `id`!=-1 
my ($sql, @binds) = $maker->select( 
'blog_entries', '*', { id => $json->{blog_id} }); 
my $rows = $dbi->selectall_arrayref($sql, { Slice => {} }, @binds); 
send_output_as_json([ map { +{ 
entry_id => $_->{id}, 
entry_title => $_->{title}, 
} } @$rows ]); 
12
Can it be used as an attack vector? 
13 
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 
Yes 
14
Information Leakage in a Twitter-like App. 
# this API returns the tweets of a user specified by $json->{user_id}, who is following the authenticating user 
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 
if (! is_following($session->{user_id}, $json->{user_id})) { 
return "cannot return the tweets of an user who is not following you"; 
} 
my ($sql, @binds) = $maker->select('tweet', '*', { user => $json->{user_id} }); 
My $rows = $dbi->selectall_arrayref($sql, { Slice => {} }, @binds); 
send_output_as_json([ map { ... } @$rows ]); 
sub is_following { 
my ($user, $following) = @_; 
# builds query: SELECT * FROM following WHERE user=$user AND following=$following 
my ($sql, @binds) = $maker->select( 
'following', '*', { user => $user, following => $following }); 
my $rows = $dbi->selectall_arrayref($sql, @binds); 
return @$rows != 0; 
} 
15
Information Leakage in a Twitter-like App. 
(cont'd) 
# in case the JSON is: { user_id: { "!=": -1 } } 
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 
if (! is_following($session->{user_id}, $json->{user_id})) { 
return "cannot return the tweets of an user who is not following you"; 
} 
# generated query is SELECT * FROM `tweet` WHERE `user`!=-1, returns tweets of all users 
my ($sql, @binds) = $maker->select('tweet', '*', { user => $json->{user_id} }); 
My $rows = $dbi->selectall_arrayref($sql, { Slice => {} }, @binds); 
send_output_as_json([ map { ... } @$rows ]); 
sub is_following { 
my ($user, $following) = @_; 
# the generated query becomes like bellow and the function likely returns TRUE: 
# SELECT * FROM `following` WHERE `user`=$user AND `following`!=-1 
my ($sql, @binds) = $maker->select( 
'following', '*', { user => $user, following => $following }); 
my $rows = $dbi->selectall_arrayref($sql, @binds); 
return @$rows != 0; 
} 
16
Is the problem in the SQL query builders 
using hash for injecting arbitrary operators? 
17 
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 
No 
18
Handling of Array is problematic as well 
# in case the JSON is: { user_id: [ 12, 34 ] }, returns tweets of both users if either is following the authenticating 
user 
if (! is_following($session->{user_id}, $json->{user_id})) { 
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 
return "cannot return the tweets of an user who is not following you"; 
} 
# generates: SELECT * FROM `tweet` WHERE `user` IN (12,34) 
my ($sql, @binds) = $maker->select('tweet', '*', { user => $json->{user_id} }); 
My $rows = $dbi->selectall_arrayref($sql, { Slice => {} }, @binds); 
send_output_as_json([ map { ... } @$rows ]); 
sub is_following { 
my ($user, $following) = @_; 
# generates: SELECT * FROM `following` WHERE `user`=$user AND `following` IN (12,34) 
my ($sql, @binds) = $maker->select( 
'following', '*', { user => $user, following => $following }); 
my $rows = $dbi->selectall_arrayref($sql, @binds); 
return @$rows != 0; 
} 
19
Does the same problem exist in web 
application frameworks written in 
programming languages other than Perl? 
20 
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 
Yes. 
Many web application frameworks (e.g. Ruby 
on Rails) automatically convert condition 
specified by an array into an IN query. 
21
Is the problem only related to the handling 
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 
of JSON? 
22
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 
Yes & No 
23
Query decoders may return nested data 
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 
 in case of PHP and Ruby on Rails 
query?id=1 => { id: 1 } 
query?id[]=1&id[]=2 => { id: [1, 2] } 
query?user[name]=yappo => { user: { name: "yappo" } } 
⁃ also when using Data::NestedParams in Perl 
 Catalyst switches from scalars to using arrayrefs 
when the property is defined more than once 
query?id=1 => { id => 1 } 
query?id=1&id=2 => { id => [1, 2] } 
 not the case for CGI.pm and Plack 
24
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 
SQL::QueryMaker 
and 
the strict mode of SQL::Maker 
25
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 
Overview of SQL::QueryMaker 
 Provides a fail-safe API 
⁃ provides functions to specify the SQL operators; 
that return blessed refs to represent them 
(instead of using arrayrefs / hashrefs) 
sql_eq(name => 'yappo') # `name`='yappo' 
sql_in(id => [ 123, 456 ]) # `id` IN (123,456) 
sql_and([ # `sex`=1 AND `age`<=30 
sex => 1, # female 
age => sql_ge(30), 
]) 
 Added strict mode to SQL::Maker 
⁃ raises error when arrayref / hashref is given as a 
condition 
26
The snippet becomes safe in strict mode 
# this API returns the tweets of a user specified by $json->{user_id}, who is following the authenticating user 
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 
my $maker = SQL::Maker->new(..., strict => 1); 
if (! is_following($session->{user_id}, $json->{user_id})) { 
return "cannot return the tweets of an user who is not following you"; 
} 
# in strict mode, SQL::Maker raises an error if $json->{user_id} is not a scalar 
my ($sql, @binds) = $maker->select('tweet', '*', { user => $json->{user_id} }); 
My $rows = $dbi->selectall_arrayref($sql, { Slice => {} }, @binds); 
send_output_as_json([ map { ... } @$rows ]); 
sub is_following { 
my ($user, $following) = @_; 
# ditto as above 
my ($sql, @binds) = $maker->select( 
'following', '*', { user => $user, following => $following }); 
my $rows = $dbi->selectall_arrayref($sql, @binds); 
return @$rows != 0; 
} 
27
Existing code may not work under strict mode 
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 
my $maker = SQL::Maker->new(..., strict => 1); 
# equality comparison works as is 
$maker->select(..., { foo => 123 }); 
# non-equality comparison needs to be rewritten 
$maker->select(..., { foo => [ 123, 456 ]); 
=> $maker->select(..., { foo => sql_in([ 123, 456 ]) }); 
$maker->select(..., { foo => { '<' => 30 } }); 
=> $maker->select(..., { foo => sql_lt(30) }); 
28
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 
Supported in Teng >= 0.24 
my $teng = My::DB->new({ 
..., 
sql_builder_args => { 
strict => 1, 
} 
,}); 
29
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 
The Lessons Learned 
30
Always validate the type of the input 
 do not forget to validate the type of the input 
⁃ even if you do not need to check the value of 
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 
the input 
 checks can be done either within the Controller or 
within the Model (in case of SQL::Maker) 
⁃ validation in the Controller is preferable 
31
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 
Write fail-safe code 
 do not change the behavior based on the type of 
the input 
⁃ instead, provide different method for each type 
of the input 
⁃ e.g. sql_eq vs. sql_in 
32
Use blessed refs for dynamic behavior 
 use blessed refs in case you need to change the 
behavior based on the type of the input 
⁃ this is a common idiom; many template engines 
use blessed refs to determine whether if a string 
is already HTML-escaped 
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 
# in case of Text::MicroTemplate 
sub escape_html { 
my $str = shift; 
return '' 
unless defined $str; 
return $str->as_string 
if ref $str eq 'Text::MicroTemplate::EncodedString'; 
$str =~ s/([&><"'])/$_escape_table{$1}/ge; 
return $str; 
} 
33
Use blessed refs for dynamic behavior (cont'd) 
 do not use serialization libraries with support for 
blessed objects (e.g. YAML or Storable) for user 
input 
⁃ such use may lead to XSS or other code 
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 
injection vulnerability 
⁃ always only accept scalars / arrays / hashes and 
validate their type and value 
34
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 
Thanks to 
 Toshiharu Sugiyama 
⁃ original reporter of the issue 
⁃ http://developers.mobage.jp/blog/2014/7/3/jsonsql-injection 
 @tokuhirom, @cho45 
⁃ for coordinating / working on the fix 
 @miyagawa 
⁃ for the behavior of Catalyst, Ruby, etc. 
 @ockeghem 
⁃ for looking into other impl. sharing the problem 
⁃ http://blog.tokumaru.org/2014/07/json-sql-injectionphpjson. 
html 
35

Weitere ähnliche Inhalte

Was ist angesagt?

Was ist angesagt? (20)

Katalon Studio - Successful Test Automation for both Testers and Developers
Katalon Studio - Successful Test Automation for both Testers and DevelopersKatalon Studio - Successful Test Automation for both Testers and Developers
Katalon Studio - Successful Test Automation for both Testers and Developers
 
Cron
CronCron
Cron
 
Postman: An Introduction for Developers
Postman: An Introduction for DevelopersPostman: An Introduction for Developers
Postman: An Introduction for Developers
 
Daniel Putz & Maksim Puzykov [Volvo Cars] | History of Monitoring at Volvo Ca...
Daniel Putz & Maksim Puzykov [Volvo Cars] | History of Monitoring at Volvo Ca...Daniel Putz & Maksim Puzykov [Volvo Cars] | History of Monitoring at Volvo Ca...
Daniel Putz & Maksim Puzykov [Volvo Cars] | History of Monitoring at Volvo Ca...
 
Making Sense of Streaming Sensor Data: How Uber Detects on Trip Car Crashes -...
Making Sense of Streaming Sensor Data: How Uber Detects on Trip Car Crashes -...Making Sense of Streaming Sensor Data: How Uber Detects on Trip Car Crashes -...
Making Sense of Streaming Sensor Data: How Uber Detects on Trip Car Crashes -...
 
Metaflow: The ML Infrastructure at Netflix
Metaflow: The ML Infrastructure at NetflixMetaflow: The ML Infrastructure at Netflix
Metaflow: The ML Infrastructure at Netflix
 
Using Postman to Automate API On-Boarding
Using Postman to Automate API On-BoardingUsing Postman to Automate API On-Boarding
Using Postman to Automate API On-Boarding
 
SonarQube - Should I Stay or Should I Go ?
SonarQube - Should I Stay or Should I Go ? SonarQube - Should I Stay or Should I Go ?
SonarQube - Should I Stay or Should I Go ?
 
Polyspace CETIC presentation
Polyspace CETIC presentationPolyspace CETIC presentation
Polyspace CETIC presentation
 
Write microservice in golang
Write microservice in golangWrite microservice in golang
Write microservice in golang
 
ATDD Using Robot Framework
ATDD Using Robot FrameworkATDD Using Robot Framework
ATDD Using Robot Framework
 
Introduction to shell scripting
Introduction to shell scriptingIntroduction to shell scripting
Introduction to shell scripting
 
Python programming
Python  programmingPython  programming
Python programming
 
Prometheus: What is is, what is new, what is coming
Prometheus: What is is, what is new, what is comingPrometheus: What is is, what is new, what is coming
Prometheus: What is is, what is new, what is coming
 
Frida Android run time hooking - Bhargav Gajera & Vitthal Shinde
Frida  Android run time hooking - Bhargav Gajera & Vitthal ShindeFrida  Android run time hooking - Bhargav Gajera & Vitthal Shinde
Frida Android run time hooking - Bhargav Gajera & Vitthal Shinde
 
Performance testing locust
Performance testing   locustPerformance testing   locust
Performance testing locust
 
TestNG Framework
TestNG Framework TestNG Framework
TestNG Framework
 
Java Source Code Analysis using SonarQube
Java Source Code Analysis using SonarQubeJava Source Code Analysis using SonarQube
Java Source Code Analysis using SonarQube
 
Introduction To Power Shell
Introduction To Power ShellIntroduction To Power Shell
Introduction To Power Shell
 
A Threat Hunter Himself
A Threat Hunter HimselfA Threat Hunter Himself
A Threat Hunter Himself
 

Ähnlich wie JSON SQL Injection and the Lessons Learned

Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Tatsuhiko Miyagawa
 

Ähnlich wie JSON SQL Injection and the Lessons Learned (20)

Create a res tful services api in php.
Create a res tful services api in php.Create a res tful services api in php.
Create a res tful services api in php.
 
Going crazy with Node.JS and CakePHP
Going crazy with Node.JS and CakePHPGoing crazy with Node.JS and CakePHP
Going crazy with Node.JS and CakePHP
 
Introduction to Active Record at MySQL Conference 2007
Introduction to Active Record at MySQL Conference 2007Introduction to Active Record at MySQL Conference 2007
Introduction to Active Record at MySQL Conference 2007
 
Building Web-API without Rails, Registration or SMS
Building Web-API without Rails, Registration or SMSBuilding Web-API without Rails, Registration or SMS
Building Web-API without Rails, Registration or SMS
 
SproutCore and the Future of Web Apps
SproutCore and the Future of Web AppsSproutCore and the Future of Web Apps
SproutCore and the Future of Web Apps
 
Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2
 
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
 
Web Security - Hands-on
Web Security - Hands-onWeb Security - Hands-on
Web Security - Hands-on
 
Charla EHU Noviembre 2014 - Desarrollo Web
Charla EHU Noviembre 2014 - Desarrollo WebCharla EHU Noviembre 2014 - Desarrollo Web
Charla EHU Noviembre 2014 - Desarrollo Web
 
Data models in Angular 1 & 2
Data models in Angular 1 & 2Data models in Angular 1 & 2
Data models in Angular 1 & 2
 
Introduction to Active Record - Silicon Valley Ruby Conference 2007
Introduction to Active Record - Silicon Valley Ruby Conference 2007Introduction to Active Record - Silicon Valley Ruby Conference 2007
Introduction to Active Record - Silicon Valley Ruby Conference 2007
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From Iusethis
 
Using Sinatra to Build REST APIs in Ruby
Using Sinatra to Build REST APIs in RubyUsing Sinatra to Build REST APIs in Ruby
Using Sinatra to Build REST APIs in Ruby
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
Top 10 Web Security Vulnerabilities
Top 10 Web Security VulnerabilitiesTop 10 Web Security Vulnerabilities
Top 10 Web Security Vulnerabilities
 
Android networking-2
Android networking-2Android networking-2
Android networking-2
 
RESTful web services
RESTful web servicesRESTful web services
RESTful web services
 
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
 
Laravel Security Standards
Laravel Security Standards Laravel Security Standards
Laravel Security Standards
 

Mehr von Kazuho Oku

Programming TCP for responsiveness
Programming TCP for responsivenessProgramming TCP for responsiveness
Programming TCP for responsiveness
Kazuho Oku
 
ウェブを速くするためにDeNAがやっていること - HTTP/2と、さらにその先
ウェブを速くするためにDeNAがやっていること - HTTP/2と、さらにその先ウェブを速くするためにDeNAがやっていること - HTTP/2と、さらにその先
ウェブを速くするためにDeNAがやっていること - HTTP/2と、さらにその先
Kazuho Oku
 

Mehr von Kazuho Oku (20)

HTTP/2で 速くなるとき ならないとき
HTTP/2で 速くなるとき ならないときHTTP/2で 速くなるとき ならないとき
HTTP/2で 速くなるとき ならないとき
 
QUIC標準化動向 〜2017/7
QUIC標準化動向 〜2017/7QUIC標準化動向 〜2017/7
QUIC標準化動向 〜2017/7
 
HTTP/2の課題と将来
HTTP/2の課題と将来HTTP/2の課題と将来
HTTP/2の課題と将来
 
TLS 1.3 と 0-RTT のこわ〜い話
TLS 1.3 と 0-RTT のこわ〜い話TLS 1.3 と 0-RTT のこわ〜い話
TLS 1.3 と 0-RTT のこわ〜い話
 
Reorganizing Website Architecture for HTTP/2 and Beyond
Reorganizing Website Architecture for HTTP/2 and BeyondReorganizing Website Architecture for HTTP/2 and Beyond
Reorganizing Website Architecture for HTTP/2 and Beyond
 
Recent Advances in HTTP, controlling them using ruby
Recent Advances in HTTP, controlling them using rubyRecent Advances in HTTP, controlling them using ruby
Recent Advances in HTTP, controlling them using ruby
 
Programming TCP for responsiveness
Programming TCP for responsivenessProgramming TCP for responsiveness
Programming TCP for responsiveness
 
Programming TCP for responsiveness
Programming TCP for responsivenessProgramming TCP for responsiveness
Programming TCP for responsiveness
 
Developing the fastest HTTP/2 server
Developing the fastest HTTP/2 serverDeveloping the fastest HTTP/2 server
Developing the fastest HTTP/2 server
 
TLS & LURK @ IETF 95
TLS & LURK @ IETF 95TLS & LURK @ IETF 95
TLS & LURK @ IETF 95
 
HTTPとサーバ技術の最新動向
HTTPとサーバ技術の最新動向HTTPとサーバ技術の最新動向
HTTPとサーバ技術の最新動向
 
ウェブを速くするためにDeNAがやっていること - HTTP/2と、さらにその先
ウェブを速くするためにDeNAがやっていること - HTTP/2と、さらにその先ウェブを速くするためにDeNAがやっていること - HTTP/2と、さらにその先
ウェブを速くするためにDeNAがやっていること - HTTP/2と、さらにその先
 
Cache aware-server-push in H2O version 1.5
Cache aware-server-push in H2O version 1.5Cache aware-server-push in H2O version 1.5
Cache aware-server-push in H2O version 1.5
 
HTTP/2時代のウェブサイト設計
HTTP/2時代のウェブサイト設計HTTP/2時代のウェブサイト設計
HTTP/2時代のウェブサイト設計
 
H2O - making the Web faster
H2O - making the Web fasterH2O - making the Web faster
H2O - making the Web faster
 
H2O - making HTTP better
H2O - making HTTP betterH2O - making HTTP better
H2O - making HTTP better
 
H2O - the optimized HTTP server
H2O - the optimized HTTP serverH2O - the optimized HTTP server
H2O - the optimized HTTP server
 
JSX 速さの秘密 - 高速なJavaScriptを書く方法
JSX 速さの秘密 - 高速なJavaScriptを書く方法JSX 速さの秘密 - 高速なJavaScriptを書く方法
JSX 速さの秘密 - 高速なJavaScriptを書く方法
 
JSX の現在と未来 - Oct 26 2013
JSX の現在と未来 - Oct 26 2013JSX の現在と未来 - Oct 26 2013
JSX の現在と未来 - Oct 26 2013
 
Using the Power to Prove
Using the Power to ProveUsing the Power to Prove
Using the Power to Prove
 

Kürzlich hochgeladen

Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 

Kürzlich hochgeladen (20)

Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 

JSON SQL Injection and the Lessons Learned

  • 1. JSON SQL Injection Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. and the Lessons Learned DeNA Co., Ltd. Kazuho Oku 1
  • 2. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. Who am I?  Field: ⁃ network and web-related architecture  Works: ⁃ Palmscape / Xiino (web browser for Palm OS) ⁃ Author of various Perl modules • Class::Accessor::Lite, HTTP::Parser::XS, Parallel::Prefork, Server::Starter, Starlet, Test::Mysqld, ... ⁃ Author of various MySQL extensions • Q4M, mycached, ... ⁃ Also the author of: • JSX, picojson, ... 2
  • 3. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. Agenda  What is an SQL Query Builder?  JSON SQL Injection  SQL::QueryMaker and strict mode of SQL::Maker  The Lessons Learned 3
  • 4. What is an SQL Query Builder? 4 Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
  • 5. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. What is an SQL Query Builder?  is a library for building SQL queries ⁃ exists below or as a part of an object-relational mapping library (ORM) • ORM understands the semantics of the database schema / query builder does not 5 Application ORM Library SQL Query Builder Database API (DBI) Database Driver (DBD)
  • 6. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. Popular Implementations  SQL::Abstract  SQL::Interp  SQL::Maker ⁃ used by Teng ⁃ is today's main focus 6 Application ORM Library SQL Query Builder Database API (DBI) Database Driver (DBD)
  • 7. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. Query Builders are Great!  Easy to build query conditions ⁃ by using hashrefs and arrayrefs ⁃ arrayref is considered as IN queries • e.g. foo => [1,2,3] becomes `foo` IN (1,2,3) ⁃ hashref is considered as (operator, value) pair • e.g. foo => { '<', 30 } becomes `foo`<30 ⁃ the API is common to the aforementioned query builders 7
  • 8. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. Examples use SQL::Maker; ... $maker->select('user', '*', { name => 'tokuhirom' }); # => SELECT * FROM `user` WHERE `name`='tokuhirom'; $maker->select('user', '*', { name => [ 'tokuhirom', 'yappo' ] }); # => SELECT * FROM `user` WHERE `name` IN ('tokuhirom','yappo'); $maker->select('user', '*', { age => { '>' => 30 } }); # => SELECT * FROM `user` WHERE `age`>30; $maker->delete('user', { name => 'sugyan' }); # => DELETE FROM `user` WHERE `name`='sugyan'; 8
  • 9. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. Examples (cont’d) use SQL::Maker; ... $maker->select('user', '*', { name => [ 'tokuhirom', 'yappo' ] }); # => SELECT * FROM `user` WHERE `name` IN ('tokuhirom','yappo'); $maker->select('user', '*', { name => [] }); # => SELECT * FROM `user` WHERE 1=0; $maker->select('user', '*', { age => 30, sex => 0, # male }); # => SELECT * FROM `user` WHERE `age`=30 AND `sex`=0; 9
  • 10. So What is JSON SQL Injection? 10 Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
  • 11. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. The Problem  User-supplied input might not be the expected type # this API returns the entries of a blog (specified by $json->{blog_id}) my $json = decode_json($input); my ($sql, @binds) = $maker->select( 'blog_entries', '*', { id => $json->{blog_id} }); my $rows = $dbi->selectall_arrayref($sql, { Slice => {} }, @binds); send_output_as_json([ map { +{ entry_id => $_->{id}, entry_title => $_->{title}, } } @$rows ]); 11 What if $json->{name} was not a scalar?
  • 12. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. The Problem (cont’d)  Will return a list of all blog entries if the supplied JSON was: { "blog_id": { "!=": -1 } } # this API returns the entries of a blog (specified by $json->{blog_id}) my $json = decode_json($input); # generated query: SELECT * FROM `blog_entries` WHERE `id`!=-1 my ($sql, @binds) = $maker->select( 'blog_entries', '*', { id => $json->{blog_id} }); my $rows = $dbi->selectall_arrayref($sql, { Slice => {} }, @binds); send_output_as_json([ map { +{ entry_id => $_->{id}, entry_title => $_->{title}, } } @$rows ]); 12
  • 13. Can it be used as an attack vector? 13 Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
  • 14. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. Yes 14
  • 15. Information Leakage in a Twitter-like App. # this API returns the tweets of a user specified by $json->{user_id}, who is following the authenticating user Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. if (! is_following($session->{user_id}, $json->{user_id})) { return "cannot return the tweets of an user who is not following you"; } my ($sql, @binds) = $maker->select('tweet', '*', { user => $json->{user_id} }); My $rows = $dbi->selectall_arrayref($sql, { Slice => {} }, @binds); send_output_as_json([ map { ... } @$rows ]); sub is_following { my ($user, $following) = @_; # builds query: SELECT * FROM following WHERE user=$user AND following=$following my ($sql, @binds) = $maker->select( 'following', '*', { user => $user, following => $following }); my $rows = $dbi->selectall_arrayref($sql, @binds); return @$rows != 0; } 15
  • 16. Information Leakage in a Twitter-like App. (cont'd) # in case the JSON is: { user_id: { "!=": -1 } } Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. if (! is_following($session->{user_id}, $json->{user_id})) { return "cannot return the tweets of an user who is not following you"; } # generated query is SELECT * FROM `tweet` WHERE `user`!=-1, returns tweets of all users my ($sql, @binds) = $maker->select('tweet', '*', { user => $json->{user_id} }); My $rows = $dbi->selectall_arrayref($sql, { Slice => {} }, @binds); send_output_as_json([ map { ... } @$rows ]); sub is_following { my ($user, $following) = @_; # the generated query becomes like bellow and the function likely returns TRUE: # SELECT * FROM `following` WHERE `user`=$user AND `following`!=-1 my ($sql, @binds) = $maker->select( 'following', '*', { user => $user, following => $following }); my $rows = $dbi->selectall_arrayref($sql, @binds); return @$rows != 0; } 16
  • 17. Is the problem in the SQL query builders using hash for injecting arbitrary operators? 17 Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
  • 18. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. No 18
  • 19. Handling of Array is problematic as well # in case the JSON is: { user_id: [ 12, 34 ] }, returns tweets of both users if either is following the authenticating user if (! is_following($session->{user_id}, $json->{user_id})) { Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. return "cannot return the tweets of an user who is not following you"; } # generates: SELECT * FROM `tweet` WHERE `user` IN (12,34) my ($sql, @binds) = $maker->select('tweet', '*', { user => $json->{user_id} }); My $rows = $dbi->selectall_arrayref($sql, { Slice => {} }, @binds); send_output_as_json([ map { ... } @$rows ]); sub is_following { my ($user, $following) = @_; # generates: SELECT * FROM `following` WHERE `user`=$user AND `following` IN (12,34) my ($sql, @binds) = $maker->select( 'following', '*', { user => $user, following => $following }); my $rows = $dbi->selectall_arrayref($sql, @binds); return @$rows != 0; } 19
  • 20. Does the same problem exist in web application frameworks written in programming languages other than Perl? 20 Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
  • 21. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. Yes. Many web application frameworks (e.g. Ruby on Rails) automatically convert condition specified by an array into an IN query. 21
  • 22. Is the problem only related to the handling Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. of JSON? 22
  • 23. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. Yes & No 23
  • 24. Query decoders may return nested data Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.  in case of PHP and Ruby on Rails query?id=1 => { id: 1 } query?id[]=1&id[]=2 => { id: [1, 2] } query?user[name]=yappo => { user: { name: "yappo" } } ⁃ also when using Data::NestedParams in Perl  Catalyst switches from scalars to using arrayrefs when the property is defined more than once query?id=1 => { id => 1 } query?id=1&id=2 => { id => [1, 2] }  not the case for CGI.pm and Plack 24
  • 25. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. SQL::QueryMaker and the strict mode of SQL::Maker 25
  • 26. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. Overview of SQL::QueryMaker  Provides a fail-safe API ⁃ provides functions to specify the SQL operators; that return blessed refs to represent them (instead of using arrayrefs / hashrefs) sql_eq(name => 'yappo') # `name`='yappo' sql_in(id => [ 123, 456 ]) # `id` IN (123,456) sql_and([ # `sex`=1 AND `age`<=30 sex => 1, # female age => sql_ge(30), ])  Added strict mode to SQL::Maker ⁃ raises error when arrayref / hashref is given as a condition 26
  • 27. The snippet becomes safe in strict mode # this API returns the tweets of a user specified by $json->{user_id}, who is following the authenticating user Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. my $maker = SQL::Maker->new(..., strict => 1); if (! is_following($session->{user_id}, $json->{user_id})) { return "cannot return the tweets of an user who is not following you"; } # in strict mode, SQL::Maker raises an error if $json->{user_id} is not a scalar my ($sql, @binds) = $maker->select('tweet', '*', { user => $json->{user_id} }); My $rows = $dbi->selectall_arrayref($sql, { Slice => {} }, @binds); send_output_as_json([ map { ... } @$rows ]); sub is_following { my ($user, $following) = @_; # ditto as above my ($sql, @binds) = $maker->select( 'following', '*', { user => $user, following => $following }); my $rows = $dbi->selectall_arrayref($sql, @binds); return @$rows != 0; } 27
  • 28. Existing code may not work under strict mode Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. my $maker = SQL::Maker->new(..., strict => 1); # equality comparison works as is $maker->select(..., { foo => 123 }); # non-equality comparison needs to be rewritten $maker->select(..., { foo => [ 123, 456 ]); => $maker->select(..., { foo => sql_in([ 123, 456 ]) }); $maker->select(..., { foo => { '<' => 30 } }); => $maker->select(..., { foo => sql_lt(30) }); 28
  • 29. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. Supported in Teng >= 0.24 my $teng = My::DB->new({ ..., sql_builder_args => { strict => 1, } ,}); 29
  • 30. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. The Lessons Learned 30
  • 31. Always validate the type of the input  do not forget to validate the type of the input ⁃ even if you do not need to check the value of Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. the input  checks can be done either within the Controller or within the Model (in case of SQL::Maker) ⁃ validation in the Controller is preferable 31
  • 32. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. Write fail-safe code  do not change the behavior based on the type of the input ⁃ instead, provide different method for each type of the input ⁃ e.g. sql_eq vs. sql_in 32
  • 33. Use blessed refs for dynamic behavior  use blessed refs in case you need to change the behavior based on the type of the input ⁃ this is a common idiom; many template engines use blessed refs to determine whether if a string is already HTML-escaped Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. # in case of Text::MicroTemplate sub escape_html { my $str = shift; return '' unless defined $str; return $str->as_string if ref $str eq 'Text::MicroTemplate::EncodedString'; $str =~ s/([&><"'])/$_escape_table{$1}/ge; return $str; } 33
  • 34. Use blessed refs for dynamic behavior (cont'd)  do not use serialization libraries with support for blessed objects (e.g. YAML or Storable) for user input ⁃ such use may lead to XSS or other code Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. injection vulnerability ⁃ always only accept scalars / arrays / hashes and validate their type and value 34
  • 35. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. Thanks to  Toshiharu Sugiyama ⁃ original reporter of the issue ⁃ http://developers.mobage.jp/blog/2014/7/3/jsonsql-injection  @tokuhirom, @cho45 ⁃ for coordinating / working on the fix  @miyagawa ⁃ for the behavior of Catalyst, Ruby, etc.  @ockeghem ⁃ for looking into other impl. sharing the problem ⁃ http://blog.tokumaru.org/2014/07/json-sql-injectionphpjson. html 35