This commit is contained in:
Matt Basta 2011-04-06 04:46:38 +00:00
Родитель b6c800a8d4
Коммит 509ef8872d
7 изменённых файлов: 105 добавлений и 90 удалений

Просмотреть файл

@ -287,12 +287,14 @@ def _call_expression(traverser, node):
result = dangerous(a=args, t=t)
if result:
# Generate a string representation of the params
params = ", ".join([str(t(p).get_literal_value()) for p in args])
params = ", ".join([unicode(t(p).get_literal_value()) for
p in args])
traverser.err.warning(("testcases_javascript_actions",
"_call_expression",
"called_dangerous_global"),
"Global called in dangerous manner",
result if isinstance(result, str) else
result if isinstance(result,
types.StringTypes) else
"A global function was called using a set "
"of dangerous parameters. These parameters "
"have been disallowed.",
@ -414,10 +416,10 @@ def _expr_assignment(traverser, node):
if lit_right is None:
lit_right = 0
if isinstance(lit_left, (str, unicode)) or \
isinstance(lit_right, (str, unicode)):
lit_left = str(lit_left)
lit_right = str(lit_right)
if isinstance(lit_left, types.StringTypes) or \
isinstance(lit_right, types.StringTypes):
lit_left = unicode(lit_left)
lit_right = unicode(lit_right)
gleft = _get_as_num(left)
gright = _get_as_num(right)
@ -442,8 +444,8 @@ def _expr_assignment(traverser, node):
traverser.debug_level -= 1
return left
traverser._debug("ASSIGNMENT::LEFT>>%s" % str(left.is_global))
traverser._debug("ASSIGNMENT::RIGHT>>%s" % str(operators[token]()))
traverser._debug("ASSIGNMENT::LEFT>>%s" % unicode(left.is_global))
traverser._debug("ASSIGNMENT::RIGHT>>%s" % unicode(operators[token]()))
left.set_value(operators[token](), traverser=traverser)
traverser.debug_level -= 1
return left
@ -465,7 +467,7 @@ def _expr_binary(traverser, node):
left = traverser._traverse_node(node["left"])
if not isinstance(left, JSWrapper):
left = JSWrapper(left, traverser=traverser)
traverser._debug(str(left.dirty))
traverser._debug(unicode(left.dirty))
traverser.debug_level -= 1
@ -475,7 +477,7 @@ def _expr_binary(traverser, node):
right = traverser._traverse_node(node["right"])
if not isinstance(right, JSWrapper):
right = JSWrapper(right, traverser=traverser)
traverser._debug(str(right.dirty))
traverser._debug(unicode(right.dirty))
if left.dirty:
return left
@ -585,7 +587,7 @@ def _get_as_num(value):
return False
try:
if isinstance(value, str):
if isinstance(value, types.StringTypes):
return float(value)
elif isinstance(value, int) or isinstance(value, float):
return value

Просмотреть файл

@ -9,7 +9,7 @@ traverser
node
the current node being evaluated
"""
import types
from jstypes import *
@ -21,10 +21,11 @@ def createElement(args, traverser, node):
simple_args = [traverser._traverse_node(a) for a in args]
if str(simple_args[0].get_literal_value()).lower() == "script":
if unicode(simple_args[0].get_literal_value()).lower() == u"script":
_create_script_tag(traverser)
elif not (simple_args[0].is_literal() or
isinstance(simple_args[0].get_literal_value(), str)):
isinstance(simple_args[0].get_literal_value(),
types.StringTypes)):
_create_variable_element(traverser)
@ -36,10 +37,11 @@ def createElementNS(args, traverser, node):
simple_args = [traverser._traverse_node(a) for a in args]
if "script" in str(simple_args[1].get_literal_value()).lower():
if "script" in unicode(simple_args[1].get_literal_value()).lower():
_create_script_tag(traverser)
elif not (simple_args[1].is_literal() or
isinstance(simple_args[1].get_literal_value(), str)):
isinstance(simple_args[1].get_literal_value(),
types.StringTypes)):
_create_variable_element(traverser)
@ -85,7 +87,7 @@ def setAttribute(args, traverser, node):
simple_args = [traverser._traverse_node(a) for a in args]
if str(simple_args[0].get_literal_value()).lower().startswith("on"):
if unicode(simple_args[0].get_literal_value()).lower().startswith("on"):
traverser.err.notice(
err_id=("testcases_javascript_instanceactions", "setAttribute",
"setting_on*"),

Просмотреть файл

@ -1,10 +1,13 @@
import re
import types
import jstypes
def set_innerHTML(new_value, traverser):
"Tests that values being assigned to innerHTML are not dangerous"
if not isinstance(new_value, jstypes.JSWrapper):
new_value = jstypes.JSWrapper(new_value, traverser=traverser)
literal_value = new_value.get_literal_value()
if isinstance(literal_value, types.StringTypes):
# Static string assignments
@ -16,9 +19,11 @@ def set_innerHTML(new_value, traverser):
err_id=("testcases_javascript_instancetypes", "set_innerHTML",
"event_assignment"),
warning="Event handler assignment via innerHTML",
description="When assigning event handlers, innerHTML "
"should never be used. Rather, use a "
"proper technique, like addEventListener.",
description=["When assigning event handlers, innerHTML "
"should never be used. Rather, use a "
"proper technique, like addEventListener.",
"Event handler code: %s" %
literal_value.encode("ascii", "replace")],
filename=traverser.filename,
line=traverser.line,
column=traverser.position,

Просмотреть файл

@ -19,7 +19,7 @@ class JSObject(object):
def get(self, name):
"Returns the value associated with a property name"
name = str(name)
name = unicode(name)
return self.data[name] if name in self.data else None
def get_literal_value(self):
@ -36,11 +36,11 @@ class JSObject(object):
self.data[name] = value
def has_var(self, name):
name = str(name)
name = unicode(name)
return name in self.data
def output(self):
return str(self.data)
return unicode(self.data)
class JSContext(JSObject):
@ -56,7 +56,7 @@ class JSContext(JSObject):
def output(self):
output = {}
for (name, item) in self.data.items():
output[name] = str(item)
output[name] = unicode(item)
return json.dumps(output)
@ -273,7 +273,7 @@ class JSWrapper(object):
def __str__(self):
"""Returns a textual version of the object."""
return str(self.get_literal_value())
return unicode(self.get_literal_value())
class JSLiteral(JSObject):
@ -309,7 +309,7 @@ class JSPrototype(JSObject):
def get(self, name):
"Enables static analysis of `with` statements"
name = str(name)
name = unicode(name)
output = None
if name in self.data:
output = self.data[name]
@ -351,7 +351,7 @@ class JSArray(JSObject):
# Interestingly enough, this allows for things like:
# x = [4]
# y = x * 3 // y = 12 since x equals "4"
return ",".join([str(w.get_literal_value()) for w in self.elements])
return ",".join([unicode(w.get_literal_value()) for w in self.elements])
def set(self, index, value, traverser=None):
"""Follow the rules of JS for creating an array"""

Просмотреть файл

@ -16,92 +16,92 @@ BANNED_IDENTIFIERS = ("newThread", )
# GLOBAL_ENTITIES is also representative of the `window` object.
GLOBAL_ENTITIES = {
"window": {"value": lambda: GLOBAL_ENTITIES},
"document":
{"value": {"createElement":
u"window": {"value": lambda: GLOBAL_ENTITIES},
u"document":
{"value": {u"createElement":
{"dangerous":
lambda a, t: t(a[0]).get_literal_value()
.lower() == "script"},
"createElementNS":
u"createElementNS":
{"dangerous":
lambda a, t: t(a[0]).get_literal_value()
.lower() == "script"}}},
# The nefariuos timeout brothers!
"setTimeout": {"dangerous": actions._call_settimeout},
"setInterval": {"dangerous": actions._call_settimeout},
u"setTimeout": {"dangerous": actions._call_settimeout},
u"setInterval": {"dangerous": actions._call_settimeout},
"encodeURI": {"readonly": True},
"decodeURI": {"readonly": True},
"encodeURIComponent": {"readonly": True},
"decodeURIComponent": {"readonly": True},
"escape": {"readonly": True},
"unescape": {"readonly": True},
"isFinite": {"readonly": True},
"isNaN": {"readonly": True},
"parseFloat": {"readonly": True},
"parseInt": {"readonly": True},
u"encodeURI": {"readonly": True},
u"decodeURI": {"readonly": True},
u"encodeURIComponent": {"readonly": True},
u"decodeURIComponent": {"readonly": True},
u"escape": {"readonly": True},
u"unescape": {"readonly": True},
u"isFinite": {"readonly": True},
u"isNaN": {"readonly": True},
u"parseFloat": {"readonly": True},
u"parseInt": {"readonly": True},
"eval": {"dangerous": True},
"Function": {"dangerous": True},
"Object": {"value": {"prototype": {"dangerous": True},
"constructor": # Just an experiment for now
{"value": lambda: GLOBAL_ENTITIES["Function"]}}},
"String": {"value": {"prototype": {"dangerous": True}}},
"Array": {"value": {"prototype": {"dangerous": True}}},
"Number": {"value": {"prototype": {"dangerous": True}}},
"Boolean": {"value": {"prototype": {"dangerous": True}}},
"RegExp": {"value": {"prototype": {"dangerous": True}}},
"Date": {"value": {"prototype": {"dangerous": True}}},
u"eval": {"dangerous": True},
u"Function": {"dangerous": True},
u"Object": {"value": {"prototype": {"dangerous": True},
"constructor": # Just an experiment for now
{"value": lambda: GLOBAL_ENTITIES["Function"]}}},
u"String": {"value": {"prototype": {"dangerous": True}}},
u"Array": {"value": {"prototype": {"dangerous": True}}},
u"Number": {"value": {"prototype": {"dangerous": True}}},
u"Boolean": {"value": {"prototype": {"dangerous": True}}},
u"RegExp": {"value": {"prototype": {"dangerous": True}}},
u"Date": {"value": {"prototype": {"dangerous": True}}},
"Math": {"readonly": True},
u"Math": {"readonly": True},
"netscape":
{"value": {"security":
{"value": {"PrivilegeManager":
{"value": {"enablePrivilege":
u"netscape":
{"value": {u"security":
{"value": {u"PrivilegeManager":
{"value": {u"enablePrivilege":
{"dangerous": True}}}}}}},
"navigator":
{"value": {"wifi": {"dangerous": True},
"geolocation": {"dangerous": True}}},
u"navigator":
{"value": {u"wifi": {"dangerous": True},
u"geolocation": {"dangerous": True}}},
"Components":
u"Components":
{"readonly": True,
"value":
{"classes":
{"xpcom_wildcard": True,
{u"classes":
{u"xpcom_wildcard": True,
"value":
{"createInstance":
{u"createInstance":
{"return": call_definitions.xpcom_createInstance}}},
"utils":
{"value": {"evalInSandbox":
u"utils":
{"value": {u"evalInSandbox":
{"dangerous": True},
"import":
u"import":
{"dangerous":
lambda a, t:
a and \
str(t(a[0]).get_literal_value())
.count("ctypes.jsm")}}},
"interfaces":
{"value": {"nsIXMLHttpRequest":
unicode(t(a[0]).get_literal_value())
.count("ctypes.jsm")}}},
u"interfaces":
{"value": {u"nsIXMLHttpRequest":
{"xpcom_map":
lambda:
GLOBAL_ENTITIES["XMLHttpRequest"]},
"nsIProcess":
u"nsIProcess":
{"dangerous": True},
"nsIDOMGeoGeolocation":
u"nsIDOMGeoGeolocation":
{"dangerous": True},
"nsIX509CertDB":
u"nsIX509CertDB":
{"dangerous": True},
"mozIJSSubScriptLoader":
u"mozIJSSubScriptLoader":
{"dangerous": True}}}}},
"extensions": {"dangerous": True},
"xpcnativewrappers": {"dangerous": True},
u"extensions": {"dangerous": True},
u"xpcnativewrappers": {"dangerous": True},
"XMLHttpRequest":
u"XMLHttpRequest":
{"value":
{"open": {"dangerous":
{u"open": {"dangerous":
# Ban syncrhonous XHR by making sure the third arg
# is absent and false.
lambda a, t:
@ -114,7 +114,7 @@ GLOBAL_ENTITIES = {
"connections."}}},
# Global properties are inherently read-only, though this formalizes it.
"Infinity": {"readonly": True},
"NaN": {"readonly": True},
"undefined": {"readonly": True},
u"Infinity": {"readonly": True},
u"NaN": {"readonly": True},
u"undefined": {"readonly": True},
}

Просмотреть файл

@ -29,6 +29,7 @@ def get_tree(code, err=None, filename=None, shell=None):
str_exc = str(exc).strip("'\"")
if ("SyntaxError" in str_exc or
"ReferenceError" in str_exc):
open("testfiles/foo.js", mode="w+b").write(code)
err.warning(("testcases_scripting",
"test_js_file",
"syntax_error"),

Просмотреть файл

@ -42,10 +42,12 @@ class MockBundler:
self.ids.append(id)
error = unicode(error)
print "-" * 30
print error
print error.encode("ascii", "replace")
print "~" * len(error)
if isinstance(description, str):
if isinstance(description, types.StringTypes):
print description
else:
# Errors can have multiple lines
@ -105,12 +107,14 @@ class Traverser:
output = data
if isinstance(data, JSObject) or isinstance(data, JSContext):
output = data.output()
print ". " * self.debug_level + output
output = unicode(output)
print ". " * self.debug_level + output.encode("ascii", "replace")
def run(self, data):
if DEBUG:
x = open("/tmp/output.js", "w")
x.write(str(data))
x.write(unicode(data))
x.close()
if "type" not in data or not self._can_handle_node(data["type"]):
@ -189,7 +193,7 @@ class Traverser:
if action is not None:
action_result = action(self, node)
self._debug("ACTION>>%s (%s)" %
("halt>>%s" % str(action_result) if
("halt>>%s" % unicode(action_result) if
action_result else
"continue",
node["type"]))
@ -350,7 +354,8 @@ class Traverser:
"_build_global",
"dangerous_global"),
"Dangerous Global Object",
[dang if isinstance(dang, str) else
[dang if
isinstance(dang, types.StringTypes) else
"A dangerous or banned global object was "
"accessed by some JavaScript code.",
"Accessed object: %s" % name],