$30 off During Our Annual Pro Sale. View Details »

ACIDRain: Concurrency-Related Attacks on Database-Backed Web Applications

ACIDRain: Concurrency-Related Attacks on Database-Backed Web Applications

More Decks by Stanford Future Data Systems

Other Decks in Technology

Transcript

  1. 1
    ACIDRain: Concurrency-Related
    Attacks on Database-Backed Web
    Applications
    Todd Warszawski, Peter Bailis
    Stanford University

    View Slide

  2. 2
    Explore Real World Transaction
    Usage

    Do programmers use transactions correctly?

    This paper: 22 new critical vulnerabilities due to
    incorrect transaction usage
    – Corrupt store inventory, overspend giftcards, steal
    items

    50% of eCommerce sites (2M+) at risk

    View Slide

  3. 3
    Analyzed Popular Sites

    View Slide

  4. 5
    Analyzed Popular Sites
    Plus 9
    more!

    View Slide

  5. 6
    Companies Using These
    Applications

    View Slide

  6. 7

    View Slide

  7. 8

    View Slide

  8. 9

    View Slide

  9. 10
    What do these
    vulnerabilities look like?

    View Slide

  10. 11
    LIVE DEMO HERE
    Invite Todd to talk at your
    organization!

    View Slide

  11. 12

    View Slide

  12. 13

    View Slide

  13. 14
    “By sending thousands of simultaneous
    requests, the attacker was able to ‘move’
    coins from one user account to another
    until the sending account was
    overdrawn, before balances were
    updated.”

    View Slide

  14. 15
    What's Happening?

    Race condition – application exhibits behavior
    under concurrent execution not possible
    under serial execution

    Can we exploit these behaviors?

    Yes! We call this exploitation of non-
    serializable API behavior an ACIDRain attack

    View Slide

  15. 16
    Overview

    Problem setup

    New method for detecting latent potential for
    non-serializable behavior

    Evaluation – analysis of 12 eCommerce
    platforms

    View Slide

  16. 17
    Problem Setup: Attacking Websites
    http POST request
    SELECT ...
    UPDATE ...
    SELECT ...
    http GET request
    Application
    Server
    Database

    View Slide

  17. 18
    Problem Setup: Attacking Websites
    http POST request
    SELECT ...
    UPDATE ...
    SELECT ...
    http GET request
    Application
    Server
    Database

    View Slide

  18. 19
    Problem Setup: Attacking Websites
    http POST request
    SELECT ...
    UPDATE ...
    SELECT ...
    http GET request
    Application
    Server
    Database

    View Slide

  19. 20
    Problem Setup: Attacking Websites
    http POST request
    SELECT ...
    UPDATE ...
    SELECT ...
    http GET request
    Application
    Server
    Database

    View Slide

  20. 21
    Problem Setup: Attacking Websites
    http POST request
    SELECT ...
    UPDATE ...
    SELECT ...
    http GET request
    Application
    Server
    Application
    Server
    Database

    View Slide

  21. 22
    Problem Setup: Attacking Websites
    http POST request
    SELECT ...
    UPDATE ...
    SELECT ...
    http GET request
    Database
    Application
    Server

    View Slide

  22. 23
    Problem Setup: Attacking Websites
    http POST request
    SELECT ...
    UPDATE ...
    SELECT ...
    http GET request
    Serializability of
    API Requests
    Serializability of
    Database Transactions
    Application
    Server
    Database

    View Slide

  23. 24
    Non-Transactional Implementation
    def checkVoucher(code):
    usage = readUsage(code)
    if (usage == 0):
    markUsed(code)
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY

    View Slide

  24. 25
    Non-Transactional Implementation
    def checkVoucher(code):
    usage = readUsage(code)
    if (usage == 0):
    markUsed(code)
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    Alice Checkout
    SELECT
    0
    UPDATE
    SELECT
    1
    Bob Checkout
    usage = 0
    Application
    Server
    Database

    View Slide

  25. 26
    Non-Transactional Implementation
    def checkVoucher(code):
    usage = readUsage(code)
    if (usage == 0):
    markUsed(code)
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    Alice Checkout
    SELECT
    0
    UPDATE
    SELECT
    1
    Bob Checkout
    usage = 0
    Application
    Server
    Database

    View Slide

  26. 27
    Non-Transactional Implementation
    def checkVoucher(code):
    usage = readUsage(code)
    if (usage == 0):
    markUsed(code)
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    Alice Checkout
    SELECT
    0
    UPDATE
    SELECT
    1
    Bob Checkout
    usage = 0
    Application
    Server
    Database

    View Slide

  27. 28
    Non-Transactional Implementation
    def checkVoucher(code):
    usage = readUsage(code)
    if (usage == 0):
    markUsed(code)
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    Alice Checkout
    SELECT
    0
    UPDATE
    SELECT
    1
    Bob Checkout
    usage = 1
    Application
    Server
    Database

    View Slide

  28. 29
    Non-Transactional Implementation
    def checkVoucher(code):
    usage = readUsage(code)
    if (usage == 0):
    markUsed(code)
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    Alice Checkout
    SELECT
    0
    UPDATE
    SELECT
    1
    Bob Checkout
    usage = 1
    Application
    Server
    Database

    View Slide

  29. 30
    Non-Transactional Implementation
    def checkVoucher(code):
    usage = readUsage(code)
    if (usage == 0):
    markUsed(code)
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    Alice Checkout
    SELECT
    0
    UPDATE
    SELECT
    1
    Bob Checkout
    usage = 1
    Application
    Server
    Database

    View Slide

  30. 31
    Non-Transactional Implementation
    def checkVoucher(code):
    usage = readUsage(code)
    if (usage == 0):
    markUsed(code)
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    Alice Checkout
    SELECT
    0
    UPDATE
    SELECT
    0
    Bob Checkout
    UPDATE
    usage = 0
    Application
    Server
    Database

    View Slide

  31. 32
    Non-Transactional Implementation
    def checkVoucher(code):
    usage = readUsage(code)
    if (usage == 0):
    markUsed(code)
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    Alice Checkout
    SELECT
    0
    UPDATE
    SELECT
    0
    Bob Checkout
    UPDATE
    usage = 0
    Application
    Server
    Database

    View Slide

  32. 33
    Non-Transactional Implementation
    def checkVoucher(code):
    usage = readUsage(code)
    if (usage == 0):
    markUsed(code)
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    Alice Checkout
    SELECT
    0
    UPDATE
    SELECT
    0
    Bob Checkout
    UPDATE
    usage = 0
    Application
    Server
    Database

    View Slide

  33. 34
    Non-Transactional Implementation
    def checkVoucher(code):
    usage = readUsage(code)
    if (usage == 0):
    markUsed(code)
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    Alice Checkout
    SELECT
    0
    UPDATE
    SELECT
    0
    Bob Checkout
    UPDATE
    usage = 0
    Application
    Server
    Database

    View Slide

  34. 35
    Non-Transactional Implementation
    def checkVoucher(code):
    usage = readUsage(code)
    if (usage == 0):
    markUsed(code)
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    Alice Checkout
    SELECT
    0
    UPDATE
    SELECT
    0
    Bob Checkout
    UPDATE
    usage = 1
    Application
    Server
    Database

    View Slide

  35. 36
    Non-Transactional Implementation
    def checkVoucher(code):
    usage = readUsage(code)
    if (usage == 0):
    markUsed(code)
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    Alice Checkout
    SELECT
    0
    UPDATE
    SELECT
    0
    Bob Checkout
    UPDATE
    usage = 1
    Application
    Server
    Database

    View Slide

  36. 37
    Transactional Implementation
    def checkVoucher(code):
    beginTxn()
    usage = readUsage(code)
    if (usage == 0):
    markUsed(code)
    commit()
    BEGIN TRANSACTION
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    COMMIT

    View Slide

  37. 38
    Transactional Implementation
    def checkVoucher(code):
    beginTxn()
    usage = readUsage(code)
    if (usage == 0):
    markUsed(code)
    commit()
    BEGIN TRANSACTION
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    COMMIT
    Alice Checkout
    SELECT
    0
    UPDATE
    SELECT
    0
    Bob Checkout
    UPDATE
    BEGIN
    BEGIN
    COMMIT
    COMMIT
    usage = 0
    Database
    Application
    Server

    View Slide

  38. 39
    Transactional Implementation
    def checkVoucher(code):
    beginTxn()
    usage = readUsage(code)
    if (usage == 0):
    markUsed(code)
    commit()
    BEGIN TRANSACTION
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    COMMIT
    Alice Checkout
    SELECT
    0
    UPDATE
    SELECT
    0
    Bob Checkout
    UPDATE
    BEGIN
    BEGIN
    COMMIT
    COMMIT
    usage = 0
    Database
    Application
    Server

    View Slide

  39. 40
    Transactional Implementation
    def checkVoucher(code):
    beginTxn()
    usage = readUsage(code)
    if (usage == 0):
    markUsed(code)
    commit()
    BEGIN TRANSACTION
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    COMMIT
    Alice Checkout
    SELECT
    0
    UPDATE
    SELECT
    0
    Bob Checkout
    UPDATE
    BEGIN
    BEGIN
    COMMIT
    COMMIT
    usage = 0
    Database
    Application
    Server

    View Slide

  40. 41
    Transactional Implementation
    def checkVoucher(code):
    beginTxn()
    usage = readUsage(code)
    if (usage == 0):
    markUsed(code)
    commit()
    BEGIN TRANSACTION
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    COMMIT
    Alice Checkout
    SELECT
    0
    UPDATE
    SELECT
    0
    Bob Checkout
    UPDATE
    BEGIN
    BEGIN
    COMMIT
    COMMIT
    usage = 0
    Database
    Application
    Server

    View Slide

  41. 42
    Transactional Implementation
    def checkVoucher(code):
    beginTxn()
    usage = readUsage(code)
    if (usage == 0):
    markUsed(code)
    commit()
    BEGIN TRANSACTION
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    COMMIT
    Alice Checkout
    SELECT
    0
    UPDATE
    SELECT
    0
    Bob Checkout
    UPDATE
    BEGIN
    BEGIN
    COMMIT
    COMMIT
    usage = 0
    Database
    Application
    Server

    View Slide

  42. 43
    Transactional Implementation
    def checkVoucher(code):
    beginTxn()
    usage = readUsage(code)
    if (usage == 0):
    markUsed(code)
    commit()
    BEGIN TRANSACTION
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    COMMIT
    Alice Checkout
    SELECT
    0
    UPDATE
    SELECT
    0
    Bob Checkout
    UPDATE
    BEGIN
    BEGIN
    COMMIT
    COMMIT
    usage = 0
    Database
    Application
    Server

    View Slide

  43. 44
    Transactional Implementation
    def checkVoucher(code):
    beginTxn()
    usage = readUsage(code)
    if (usage == 0):
    markUsed(code)
    commit()
    BEGIN TRANSACTION
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    COMMIT
    Alice Checkout
    SELECT
    0
    UPDATE
    SELECT
    0
    Bob Checkout
    UPDATE
    BEGIN
    BEGIN
    COMMIT
    COMMIT
    usage = 1
    Database
    Application
    Server

    View Slide

  44. 45
    Transactional Implementation
    def checkVoucher(code):
    beginTxn()
    usage = readUsage(code)
    if (usage == 0):
    markUsed(code)
    commit()
    BEGIN TRANSACTION
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    COMMIT
    Alice Checkout
    SELECT
    0
    UPDATE
    SELECT
    0
    Bob Checkout
    UPDATE
    BEGIN
    BEGIN
    COMMIT
    COMMIT
    usage = 1
    Database
    Application
    Server

    View Slide

  45. 46
    Transactional Implementation
    def checkVoucher(code):
    beginTxn()
    usage = readUsage(code)
    if (usage == 0):
    markUsed(code)
    commit()
    BEGIN TRANSACTION
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    COMMIT
    Alice Checkout
    SELECT
    0
    UPDATE
    SELECT
    0
    Bob Checkout
    UPDATE
    BEGIN
    BEGIN
    COMMIT
    COMMIT
    usage = 1
    Database
    Application
    Server

    View Slide

  46. 47
    Transactional Implementation
    def checkVoucher(code):
    beginTxn()
    usage = readUsage(code)
    if (usage == 0):
    markUsed(code)
    commit()
    BEGIN TRANSACTION
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    COMMIT
    Alice Checkout
    SELECT
    0
    UPDATE
    SELECT
    0
    Bob Checkout
    UPDATE
    BEGIN
    BEGIN
    COMMIT
    COMMIT
    usage = 1
    Database
    Application
    Server

    View Slide

  47. 48
    Transactional Implementation
    def checkVoucher(code):
    beginTxn()
    usage = readUsage(code)
    if (usage == 0):
    markUsed(code)
    commit()
    BEGIN TRANSACTION
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    COMMIT
    Alice Checkout
    SELECT
    0
    UPDATE
    SELECT
    0
    Bob Checkout
    UPDATE
    BEGIN
    BEGIN
    COMMIT
    COMMIT
    usage = 1
    Database
    Application
    Server
    Will one of the
    transactions fail?
    It depends

    View Slide

  48. 49
    = prevents anomaly
    = exhibits anomaly
    Many Databases Allow This Anomaly
    Database Default Isolation Maximum Isolation
    Actian Ingres 10.0/10S
    Aerospike
    Akiban Persistit
    Clustrix CLX 4100
    Greenplum 4.1
    IBM DB2 10 for z/OS
    MySQL 5.6
    MemSQL 1b
    MS SQL Server 2012
    NuoDB
    Oracle 11g
    Oracle Berkeley DB
    Oracle Berkeley DB JE
    Postgres 9.2.2
    SAP HANA
    ScaleDB 1.02
    VoltDB

    View Slide

  49. 50
    Two Sources of Vulnerabilities

    Databases providing weak isolation may exhibit
    non-serializable behavior
    def checkVoucher(code):
    beginTxn()
    usage = readUsage(code)
    if (usage == 0):
    markUsed(code)
    commit()
    def checkVoucher(code):
    usage = readUsage(code)
    if (usage == 0):
    markUsed(code)

    Programmers may code transactions
    incorrectly

    View Slide

  50. 51
    Overview

    Problem setup

    New method for detecting latent potential for
    non-serializable behavior

    Evaluation – analysis of 12 eCommerce
    platforms

    View Slide

  51. 52
    Analysis Challenges

    Want to analyze web applications written in
    multiple languages and frameworks

    Anomalies only occur under concurrent
    execution, but website activity is often serial

    View Slide

  52. 53
    Approach: Abstract Anomaly
    Detection (2AD)
    Collect (possibly serial) logs from database
    Build compact representation of history (abstract
    history graph)
    Search abstract history for cycles to generate
    possible anomalous API calls
    1.
    2.
    a
    3.

    View Slide

  53. Approach: Abstract Anomaly
    Detection (2AD)

    View Slide

  54. Approach: Abstract Anomaly
    Detection (2AD)

    View Slide

  55. Approach: Abstract Anomaly
    Detection (2AD)

    View Slide

  56. Approach: Abstract Anomaly
    Detection (2AD)

    View Slide

  57. Approach: Abstract Anomaly
    Detection (2AD)

    View Slide

  58. 59
    Approach: Abstract Anomaly
    Detection (2AD)

    View Slide

  59. 60
    Approach: Abstract Anomaly
    Detection (2AD)
    Collect (possibly serial) logs from database
    Build compact representation of history (abstract
    history graph)
    Search abstract history for cycles to generate
    possible anomalous API calls
    1.
    2.
    a
    3.

    View Slide

  60. 61
    Abstract History Graph
    def checkVoucher(code):
    beginTxn()
    usage = readUsage(code)
    if (usage == 0):
    markUsed(code)
    commit()
    BEGIN TRANSACTION
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    COMMIT
    BEGIN TRANSACTION
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    COMMIT

    View Slide

  61. 62
    Abstract History Graph
    BEGIN TRANSACTION
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    COMMIT
    BEGIN TRANSACTION
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    COMMIT

    View Slide

  62. 63
    Abstract History Graph
    r(voucher) w(voucher)
    r(voucher) w(voucher)
    BEGIN TRANSACTION
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    COMMIT
    BEGIN TRANSACTION
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    COMMIT
    = Operation
    Add node for each operation
    1.

    View Slide

  63. 64
    Abstract History Graph
    r(voucher) w(voucher)
    r(voucher) w(voucher)
    BEGIN TRANSACTION
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    COMMIT
    BEGIN TRANSACTION
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    COMMIT
    = Operation
    = Transaction
    Add node for each operation
    Add supernode for each
    transaction
    1.
    2.

    View Slide

  64. 65
    Abstract History Graph
    r(voucher) w(voucher)
    r(voucher) w(voucher)
    BEGIN TRANSACTION
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    COMMIT
    BEGIN TRANSACTION
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    COMMIT
    = Operation
    = Transaction
    = API Call
    Add node for each operation
    Add supernode for each
    transaction
    Add super-supernode for each
    API call
    1.
    2.
    3.

    View Slide

  65. 66
    Abstract History Graph
    r(voucher) w(voucher)
    r(voucher) w(voucher)
    BEGIN TRANSACTION
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    COMMIT
    BEGIN TRANSACTION
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    COMMIT
    = Operation
    = Transaction
    = API Call
    = Conflict
    Add node for each operation
    Add supernode for each
    transaction
    Add super-supernode for each
    API call
    Add edge for each conflict
    1.
    2.
    3.
    4.

    View Slide

  66. 67
    Abstract History Graph
    r(voucher) w(voucher)
    r(voucher) w(voucher)
    BEGIN TRANSACTION
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    COMMIT
    BEGIN TRANSACTION
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    COMMIT
    = Operation
    = Transaction
    = API Call
    = Conflict
    Add node for each operation
    Add supernode for each
    transaction
    Add super-supernode for each
    API call
    Add edge for each conflict
    1.
    2.
    3.
    4.

    View Slide

  67. 68
    Abstract History Graph
    r(voucher) w(voucher)
    r(voucher) w(voucher)
    BEGIN TRANSACTION
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    COMMIT
    BEGIN TRANSACTION
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    COMMIT
    = Operation
    = Transaction
    = API Call
    = Conflict
    Add node for each operation
    Add supernode for each
    transaction
    Add super-supernode for each
    API call
    Add edge for each conflict
    1.
    2.
    3.
    4.

    View Slide

  68. 69
    Abstract History Graph
    r(voucher) w(voucher)
    r(voucher) w(voucher)
    BEGIN TRANSACTION
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    COMMIT
    BEGIN TRANSACTION
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    COMMIT
    = Operation
    = Transaction
    = API Call
    = Conflict
    Add node for each operation
    Add supernode for each
    transaction
    Add super-supernode for each
    API call
    Add edge for each conflict
    Search for cycles in the graph
    1.
    2.
    3.
    4.
    5.

    View Slide

  69. 70
    Abstract History Graph
    r(voucher) w(voucher)
    = Operation
    = Transaction
    = API Call
    = Conflict
    BEGIN TRANSACTION
    SELECT usage FROM voucher WHERE code = HNUHY
    BEGIN TRANSACTION
    SELECT usage FROM voucher WHERE code = HNUHY
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    COMMIT
    UPDATE voucher SET usage = 1 WHERE code = HNUHY
    COMMIT
    Add node for each operation
    Add supernode for each
    transaction
    Add super-supernode for each
    API call
    Add edge for each conflict
    Search for cycles in the graph
    1.
    2.
    3.
    4.
    5.
    r(voucher) w(voucher)

    View Slide

  70. 71
    Completeness Guarantees

    Completeness: if there is a potential anomalous
    execution, this approach will find it

    Soundness: discussion in paper
    Thm: Given a set of API calls, there exists an
    anomalous execution of the API calls if and only
    if there is a cycle in the abstract history.

    View Slide

  71. 72
    Limitations

    Does not take into account user level (i.e.,
    "feral" [Bailis et al. 2015]) concurrency control
    def checkVoucher(code):
    beginTxn()
    usage = readUsage(code)
    if (usage == 0):
    markUsed(code)
    commit()

    View Slide

  72. 73
    Limitations

    Does not take into account user level (i.e.,
    "feral" [Bailis et al. 2015]) concurrency control
    def checkVoucher(code):
    beginTxn()
    usage = readUsage(code)
    if (usage == 0):
    markUsed(code)
    commit()
    def checkVoucher(code):
    appLock.lock()
    usage = readUsage(code)
    if (usage == 0):
    markUsed(code)
    appLock.release()

    View Slide

  73. 74
    Overview

    Problem setup

    New method for detecting latent potential for
    non-serializable behavior

    Evaluation – analysis of 12 eCommerce
    platforms

    View Slide

  74. 75
    Ecommerce Platforms

    View Slide

  75. 76
    Ecommerce Platforms
    Interested in 3
    key invariants:
    1. Inventory
    2. Voucher
    3. Cart

    View Slide

  76. 77
    Inventory Invariant
    Stock should not go below 0 and should reflect all orders placed

    View Slide

  77. 78
    Inventory Invariant
    Stock should not go below 0 and should reflect all orders placed

    View Slide

  78. 79
    Inventory Invariant
    Stock should not go below 0 and should reflect all orders placed

    View Slide

  79. 80
    Voucher Invariant
    Vouchers should not be spent past their intended limit

    View Slide

  80. 81
    Voucher Invariant
    Vouchers should not be spent past their intended limit

    View Slide

  81. 82
    Voucher Invariant
    Vouchers should not be spent past their intended limit

    View Slide

  82. 83
    Cart Invariant
    Total charged for an order should be equal to the value
    of items associated with the order

    View Slide

  83. 84
    Cart Invariant
    Total charged for an order should be equal to the value
    of items associated with the order

    View Slide

  84. 85
    Cart Invariant
    Total charged for an order should be equal to the value
    of items associated with the order

    View Slide

  85. 86
    Analysis Results
    Application Language Inventory Voucher Cart
    Opencart PHP ✗ ✗ ✔
    Prestashop PHP ✗ ✗ ✔
    Magento PHP ✗ ✗ ✔
    WooCommerce PHP ✗ ✗ ✔
    Spree Ruby on Rails ✔ ✔ ✔
    Ror_ecommerce Ruby on Rails ✗ N/A ✗
    Shoppe Ruby on Rails ✗ N/A ✗
    Oscar Python (Django) ✗ ✗ ✔
    LFS Python (Django) ✗ ✗ ✗
    Saleor Python (Django) ✗ ✗ N/A
    Broadleaf Java (Spring) N/A ✗ ✗
    Shopizer Java (Spring) N/A N/A ✗
    ✗ = vulnerable, ✔ = not vulnerable
    22 new vulnerabilities!

    View Slide

  86. 87
    Analysis Results
    Application Language Inventory Voucher Cart
    Opencart PHP ✗ ✗ ✔
    Prestashop PHP ✗ ✗ ✔
    Magento PHP ✗ ✗ ✔
    WooCommerce PHP ✗ ✗ ✔
    Spree Ruby on Rails ✔ ✔ ✔
    Ror_ecommerce Ruby on Rails ✗ N/A ✗
    Shoppe Ruby on Rails ✗ N/A ✗
    Oscar Python (Django) ✗ ✗ ✔
    LFS Python (Django) ✗ ✗ ✗
    Saleor Python (Django) ✗ ✗ N/A
    Broadleaf Java (Spring) N/A ✗ ✗
    Shopizer Java (Spring) N/A N/A ✗
    ✗ = vulnerable, ✔ = not vulnerable
    22 new vulnerabilities!
    2M+ sites
    at risk

    View Slide

  87. 88
    Analysis Results
    Application Language Inventory Voucher Cart
    Opencart PHP ✗ ✗ ✔
    Prestashop PHP ✗ ✗ ✔
    Magento PHP ✗ ✗ ✔
    WooCommerce PHP ✗ ✗ ✔
    Spree Ruby on Rails ✔ ✔ ✔
    Ror_ecommerce Ruby on Rails ✗ N/A ✗
    Shoppe Ruby on Rails ✗ N/A ✗
    Oscar Python (Django) ✗ ✗ ✔
    LFS Python (Django) ✗ ✗ ✗
    Saleor Python (Django) ✗ ✗ N/A
    Broadleaf Java (Spring) N/A ✗ ✗
    Shopizer Java (Spring) N/A N/A ✗
    ✗ = vulnerable, ✔ = not vulnerable
    22 new vulnerabilities!
    2M+ sites
    at risk
    4 different
    languages

    View Slide

  88. 89
    Analysis Results
    Application Language Inventory Voucher Cart
    Opencart PHP ✗ ✗ ✔
    Prestashop PHP ✗ ✗ ✔
    Magento PHP ✗ ✗ ✔
    WooCommerce PHP ✗ ✗ ✔
    Spree Ruby on Rails ✔ ✔ ✔
    Ror_ecommerce Ruby on Rails ✗ N/A ✗
    Shoppe Ruby on Rails ✗ N/A ✗
    Oscar Python (Django) ✗ ✗ ✔
    LFS Python (Django) ✗ ✗ ✗
    Saleor Python (Django) ✗ ✗ N/A
    Broadleaf Java (Spring) N/A ✗ ✗
    Shopizer Java (Spring) N/A N/A ✗
    ✗ = vulnerable, ✔ = not vulnerable
    22 new vulnerabilities!
    2M+ sites
    at risk
    4 different
    languages
    5 errors due
    to DB default
    isolation

    View Slide

  89. 90
    Analysis Results
    Application Language Inventory Voucher Cart
    Opencart PHP ✗ ✗ ✔
    Prestashop PHP ✗ ✗ ✔
    Magento PHP ✗ ✗ ✔
    WooCommerce PHP ✗ ✗ ✔
    Spree Ruby on Rails ✔ ✔ ✔
    Ror_ecommerce Ruby on Rails ✗ N/A ✗
    Shoppe Ruby on Rails ✗ N/A ✗
    Oscar Python (Django) ✗ ✗ ✔
    LFS Python (Django) ✗ ✗ ✗
    Saleor Python (Django) ✗ ✗ N/A
    Broadleaf Java (Spring) N/A ✗ ✗
    Shopizer Java (Spring) N/A N/A ✗
    ✗ = vulnerable, ✔ = not vulnerable
    22 new vulnerabilities!
    2M+ sites
    at risk
    4 different
    languages
    5 errors due
    to DB default
    isolation
    17 errors due
    to improper
    transaction
    usage

    View Slide

  90. 91
    Developer Response
    8 confirmed

    View Slide

  91. 92
    Developer Response
    8 confirmed

    View Slide

  92. 93
    Developer Response
    8 confirmed

    View Slide

  93. 94
    Developer Response
    8 confirmed

    View Slide

  94. 95
    Developer Response
    8 confirmed

    View Slide

  95. 96
    Developer Response
    8 confirmed

    View Slide

  96. 97

    View Slide

  97. 98

    View Slide

  98. 99
    Developer Response

    View Slide

  99. 100
    Developer Response

    View Slide

  100. 101
    Related Work

    [Bailis et al. 2015] Study user level (Feral)
    invariants in Ruby on Rails applications

    [Jorwekar et al. 2007] Provide analysis methods for
    detecting potential anomalies in transaction
    programs for Snapshot Isolation

    [Fekete et al. 2009] Quantify Read Committed and
    Snapshot Isolation anomalies

    Our focus is on any non-serializable behavior in
    API based web applications as observed in practice

    View Slide

  101. 102
    Conclusions

    Many popular eCommerce applications do not
    use transactions correctly

    2AD: a new, cross-language analysis tool to
    check for potential anomalies

    Using 2AD, we find 22 new vulnerabilities due
    to incorrect transaction usage affecting up to
    2M+ eCommerce sites

    View Slide

  102. 103
    Conclusions

    Many popular eCommerce applications do not
    use transactions correctly

    2AD: a new, cross-language analysis tool to
    check for potential anomalies

    Using 2AD, we find 22 new vulnerabilities due
    to incorrect transaction usage affecting up to
    2M+ eCommerce sites
    Thanks!
    [email protected]
    https://github.com/stanford-futuredata/acidrain

    View Slide