Source: python-rply
Version: 0.7.0-1
Severity: grave
Tags: security
Justification: user security hole

rply stores its cache files in /tmp. This is insecure, because /tmp is world-writable, and the filenames rply uses are of course predicatable.

Proof of concept is attached. If you put the rply-*.json file in /tmp and make it world-readable, then the tiny calculator's math will start to be slightly off (even when run by a different user than the owner of the cache file):

$ ls -l /tmp/rply-*.json
-rw-r--r-- 1 eve users 730 Jan 13 22:20 
/tmp/rply-1-tinycalc-72306a09ee3b3fe5697e2d0114eb3ee132a6ff7a.json

$ whoami
jwilk

$ echo 69 - 37 - 10 | python3 tinycalc.py
69 - 37 - 10 = 42

--
Jakub Wilk

Attachment: rply-1-tinycalc-72306a09ee3b3fe5697e2d0114eb3ee132a6ff7a.json
Description: application/json

#!/usr/bin/python3

import sys

import rply

lg = rply.LexerGenerator()
lg.add('PLUS', r'\+')
lg.add('MINUS', r'-')
lg.add('NUMBER', r'\d+')

lg.ignore(r'\s+')

pg = rply.ParserGenerator(
    ['NUMBER', 'PLUS', 'MINUS'],
    precedence=[('left', ['PLUS', 'MINUS'])],
    cache_id='tinycalc'
)

@pg.production('main : exp')
def main(p):
    [exp] = p
    return exp

@pg.production('exp : exp PLUS exp')
@pg.production('exp : exp MINUS exp')
def exp_op(p):
    [lhs, op, rhs] = p
    rhs = p[2]
    if op.getstr() == '+':
        return lhs + rhs
    else:
        return lhs - rhs

@pg.production('exp : NUMBER')
def exp_num(p):
    [tok] = p
    return int(tok.getstr())

lexer = lg.build()
parser = pg.build()

for line in sys.stdin:
    line = line.strip()
    n = parser.parse(lexer.lex(line))
    print(line, '=', n)

# vim:ts=4 sw=4 et
_______________________________________________
Python-modules-team mailing list
[email protected]
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/python-modules-team

Reply via email to