Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
f092f72
Implemented very basic number tainting functionality
May 24, 2016
d3fea97
Tainted Number <-> String conversion
May 29, 2016
b135d59
Merge branch 'master' into primitaint
May 29, 2016
427cb4f
Basic number tainting test
May 29, 2016
f45272b
Bitwise number operations are now taint aware
May 29, 2016
671c15c
The ++ and -- operators now work with tainted numbers
May 29, 2016
b5dbd1c
Implemented tainted element access
May 31, 2016
dec9980
Merge branch 'master' into primitaint
May 31, 2016
6525afb
Improved the number tainting test
May 31, 2016
ab9d405
Fix build under Linux
Jun 1, 2016
794b7ed
Merge branch 'master' into primitaint
Jun 12, 2016
e4c41be
WIP
Jun 14, 2016
8c56dd5
Merge branch 'master' into primitaint
Jun 15, 2016
c6d2369
Tainted element access working
Jun 16, 2016
6ee4b17
Merge branch 'master' into primitaint
Jun 16, 2016
41bf60d
Improved GetElement taint propagation
Jun 28, 2016
cde3aad
Added some documentation
Aug 23, 2016
8f326f1
Merge branch 'master' into primitaint
Aug 23, 2016
a96c790
Merge branch 'master' into primitaint
Aug 28, 2016
cd03768
Merge branch 'master' into primitaint
saelo Oct 25, 2016
0d4dd48
Disabled IonMonkey for now
saelo Oct 25, 2016
1f7e3af
Fixed regression in String.fromCharCode()
saelo Oct 25, 2016
455d361
Merge branch 'master' into primitaint
saelo Jan 25, 2017
f2037f8
Foxhound: Merging Number tainting branch
tmbrbr Aug 31, 2022
ae50685
Foxhound: basic number taint get and set working
tmbrbr Aug 31, 2022
623571c
Foxhound: propagate tainting for subtract operation
tmbrbr Sep 1, 2022
ef6eddc
fix number mul,div,mod,pow and add test for pow
LukasHock Sep 1, 2022
9f242f6
Foxhound: Add taintability to WebIDL files
tmbrbr Sep 2, 2022
1743c74
Fix taint propagation for bitwise operations
LukasHock Sep 6, 2022
a247d5e
Foxound: Add taint propagation for charCodeAt() and fromCharCode()
LukasHock Sep 6, 2022
73eacb4
Foxhound: Cleanup comment
LukasHock Sep 6, 2022
5b62fd4
Foxhound: Improve tests and asserts
LukasHock Sep 6, 2022
feb74b0
Foxhound: Add tests for type conversions
LukasHock Sep 6, 2022
e0956a4
Foxhound: Add taint propagation for num->string conversion
LukasHock Sep 9, 2022
1fa7709
Foxhound: Add taint propagation for explicit str->num conversion
LukasHock Sep 9, 2022
182048f
Foxhound: add test for hashing functions
LukasHock Sep 9, 2022
d7df250
Foxhound: Disable Baseline Interpreter
LukasHock Sep 12, 2022
f14dc47
Foxhound: add two hashing functions to hash test
LukasHock Sep 12, 2022
877a77f
Foxhound: Enhance taint propagation for str.charAt
LukasHock Sep 13, 2022
bba31b0
Foxhound: Fix hashing algorithm in test
LukasHock Sep 13, 2022
6f2deaf
Foxhound: Add number taint propagation in JSON.stringify
LukasHock Sep 14, 2022
2281ead
Foxhound: add more screen attributes as taint source
LukasHock Sep 15, 2022
a4ea399
Foxhound: add capability to mark cashed values as taint sources
LukasHock Sep 19, 2022
df8b8b1
Foxhound: Add multiple numeric APIs as taint source
LukasHock Sep 19, 2022
faaed11
Foxhound: Add capability to use methods and wrapped values as taint s…
LukasHock Sep 20, 2022
88f8e25
Merge branch 'main' into primitaint
LukasHock Oct 19, 2022
4d3a520
Foxhound: Start extending taint data structure
LukasHock Oct 21, 2022
f5ab5fc
Foxhound: Propagate taint from both operands of number operations
LukasHock Oct 25, 2022
04c78ca
Foxhound: Change TaintFlow iterator to only output each node once
LukasHock Oct 26, 2022
34b8078
Foxhound: Refactor data model to not create history
LukasHock Oct 27, 2022
49ac4c1
Foxhound: Remove various TaintNode creators
LukasHock Oct 27, 2022
bcab163
Foxhound: Update TaintFlow expansion to fit new data model
LukasHock Oct 27, 2022
9925b20
Fx error when using add with arrays
LukasHock Nov 14, 2022
b641c33
Foxhound: Update test for features which were broken
LukasHock Nov 16, 2022
2396e75
Merge branch 'main' into primitaint
LukasHock Nov 16, 2022
bd392e8
Merge branch 'primitaint' into primitaint-no-hist
LukasHock Nov 16, 2022
d084ff4
Foxhound: Fix static Number functions for tainted numbers
LukasHock Nov 16, 2022
fccf6a6
Foxhound: Add more taint sources
LukasHock Nov 16, 2022
d630772
Foxhound: disguise tainted numbers in typeof()
LukasHock Nov 17, 2022
3de1744
Foxhound: Add new Taint Sources
LukasHock Nov 18, 2022
4480172
Merge branch 'main' into primitaint-merge
tmbrbr May 2, 2024
2a1a515
Additional tainted value helper functions
tmbrbr May 8, 2024
51373a9
Foxhound: fixing number taint for inc/dec operations
tmbrbr Jun 17, 2024
e474d5a
Foxhound: adding missing taint operations
tmbrbr Jun 17, 2024
807eaf5
Number tainting with maps test case
leeN Jun 26, 2024
a442a54
Added tests for failing playwright issue
leeN Jun 27, 2024
301b663
Foxhound: Adding nursery memory sweep for tainted numbers
tmbrbr Jul 30, 2024
af544cf
Foxhound: unbox tainted numbers used as map keys
tmbrbr Jul 30, 2024
9d2dd31
Adding webIDL sources to preferences
leeN Jul 30, 2024
c1caef1
Foxhound: adding binary taint nodes
tmbrbr Aug 2, 2024
1b66b56
Adding fingerprinting source configuration flags
tmbrbr Aug 2, 2024
64e50a2
fixed optimized switch cases with tainted discriminants
0drai Aug 4, 2024
a8cd65a
Added taint propogation to Math.round
alexbara2000 Aug 1, 2024
cdaaa3d
Added ability to write a primitive value to an object. This is needed…
alexbara2000 Aug 1, 2024
8aee309
Added taint propagation to most of the JSMath library
alexbara2000 Aug 1, 2024
13fa4b7
Finished making JSMath taint aware
alexbara2000 Aug 1, 2024
b0ed402
refactoring
alexbara2000 Aug 1, 2024
15609df
Ensured the result of an operation is stored in a new object
alexbara2000 Aug 1, 2024
289cfd7
Added base tests for JS math library testing
alexbara2000 Aug 1, 2024
8aba400
Added more comprehensive tests
alexbara2000 Aug 1, 2024
ed0e7a2
Fixed min and max logic
alexbara2000 Aug 1, 2024
2ab97aa
simplified if statement with a helper function
alexbara2000 Aug 2, 2024
58b6ef5
refactored math imul and atan2
alexbara2000 Aug 5, 2024
c6599da
Fixes Array.indexOf/includes for tainted numbers
leeN Aug 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 99 additions & 2 deletions dom/bindings/Codegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,40 @@
NEW_ENUMERATE_HOOK_NAME = "_newEnumerate"
ENUM_ENTRY_VARIABLE_NAME = "strings"
INSTANCE_RESERVED_SLOTS = 1
PREFERENCE_PREFIX = "tainting.source."


# This size is arbitrary. It is a power of 2 to make using it as a modulo
# operand cheap, and is usually around 1/3-1/5th of the set size (sometimes
# smaller for very large sets).
GLOBAL_NAMES_PHF_SIZE = 256

def format_preference_entry(taintSource):
return "%s%s" % (PREFERENCE_PREFIX, taintSource)

def format_preference(taintSource):
return (
"pref(\"%s\", true);"
% (format_preference_entry(taintSource))
)

def maybe_add_preference(taintSource):
import pathlib
root = pathlib.Path(__file__).parent.parent.parent.resolve()
prefs = root / 'modules' / 'libpref' / 'init' / 'all.js'
prefs = prefs.resolve()
if(prefs.exists()):
preference_entry = format_preference_entry(taintSource)
with prefs.open(mode='r+') as pf:
if preference_entry in pf.read():
print("%s already defined in %s... Skipping...\n" % (preference_entry, prefs))
else:
pf.write("%s\n" % (format_preference(taintSource)))
print("Added preference '%s' to '%s'..\n" % (preference_entry, prefs))
return True
else:
print("Preference file does not exist: %s!\n"% prefs)
return False

def memberReservedSlot(member, descriptor):
return (
Expand Down Expand Up @@ -7740,6 +7768,7 @@ def getWrapTemplateForType(
exceptionCode,
spiderMonkeyInterfacesAreStructs,
isConstructorRetval=False,
taintSource=None
):
"""
Reflect a C++ value stored in "result", of IDL type "type" into JS. The
Expand Down Expand Up @@ -7819,6 +7848,19 @@ def _setValue(value, wrapAsType=None, setter="set"):
exceptionCode=exceptionCode,
successCode=successCode,
)
# Attach taint metadata to the return value if it is a source
if taintSource is not None:
print("Generating taint source:", taintSource)
maybe_add_preference(taintSource)
taintHandler = dedent(
(
"""
// Add taint source
MarkTaintSource(cx, ${jsvalRef}, "%s");
"""
% (taintSource))
)
tail = taintHandler + tail
return ("${jsvalRef}.%s(%s);\n" % (setter, value)) + tail

def wrapAndSetPtr(wrapCall, failureCode=None):
Expand All @@ -7828,16 +7870,32 @@ def wrapAndSetPtr(wrapCall, failureCode=None):
"""
if failureCode is None:
failureCode = exceptionCode

# TaintFox: create source code for tainting wrapped return value
markTaintSnippet = ""
if taintSource is not None:
print("Generating taint source for wrapped value:", taintSource)
maybe_add_preference(taintSource)
markTaintSnippet = dedent(
f"""
// Add taint source for wrapped value
MarkTaintSource(cx, args.rval(), "{taintSource}");"""
)

return fill(
"""
if (!${wrapCall}) {
$*{failureCode}
}

${markTaintSnippet}

$*{successCode}
""",
wrapCall=wrapCall,
failureCode=failureCode,
successCode=successCode,
markTaintSnippet=markTaintSnippet,
)

if type is None or type.isUndefined():
Expand Down Expand Up @@ -8259,7 +8317,7 @@ def wrapAndSetPtr(wrapCall, failureCode=None):
raise TypeError("Need to learn to wrap primitive: %s" % type)


def wrapForType(type, descriptorProvider, templateValues):
def wrapForType(type, descriptorProvider, templateValues, taintSource = None):
"""
Reflect a C++ value of IDL type "type" into JS. TemplateValues is a dict
that should contain:
Expand Down Expand Up @@ -8302,6 +8360,7 @@ def wrapForType(type, descriptorProvider, templateValues):
templateValues.get("exceptionCode", "return false;\n"),
templateValues.get("spiderMonkeyInterfacesAreStructs", False),
isConstructorRetval=templateValues.get("isConstructorRetval", False),
taintSource=taintSource
)[0]

defaultValues = {"obj": "obj"}
Expand Down Expand Up @@ -9042,6 +9101,10 @@ def __init__(
self.setSlot = (
not dontSetSlot and idlNode.isAttr() and idlNode.slotIndices is not None
)

# Taintfox: create a label for the taint source
self.taintSource = GetLabelForErrorReporting(descriptor, idlNode, isConstructor) if memberIsTaintSource(self.idlNode) else None

cgThings = []

deprecated = idlNode.getExtendedAttribute("Deprecated") or (
Expand Down Expand Up @@ -9542,7 +9605,7 @@ def wrap_return_value(self):
"obj": "conversionScope" if self.setSlot else "obj",
}

wrapCode += wrapForType(self.returnType, self.descriptor, resultTemplateValues)
wrapCode += wrapForType(self.returnType, self.descriptor, resultTemplateValues, self.taintSource)

if self.setSlot:
if self.idlNode.isStatic():
Expand Down Expand Up @@ -11015,6 +11078,11 @@ def __init__(
errorReportingLabel=None,
additionalArg=None,
):

# TaintFox: Check if return value should de marked as taint source and
# get name for taint source if needed
self.taintSource = errorReportingLabel if memberIsTaintSource(attr) else None

self.nativeName = nativeName
self.errorReportingLabel = errorReportingLabel
self.additionalArgs = [] if additionalArg is None else [additionalArg]
Expand Down Expand Up @@ -11147,6 +11215,18 @@ def definition_body(self):
slotIndex=memberReservedSlot(self.attr, self.descriptor),
)

# TaintFox: create source code for tainting cached return value
markTaintSnippet = ""
if self.taintSource is not None:
print("Generating taint source for cached value:", self.taintSource)
maybe_add_preference(self.taintSource)
markTaintSnippet = dedent(
f"""
// Add taint source for cached value
MarkTaintSource(cx, args.rval(), "{self.taintSource}");"""
)


prefix += fill(
"""
MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(JS::GetClass(slotStorage)) > slotIndex);
Expand All @@ -11155,13 +11235,17 @@ def definition_body(self):
JS::Value cachedVal = JS::GetReservedSlot(slotStorage, slotIndex);
if (!cachedVal.isUndefined()) {
args.rval().set(cachedVal);

${markTaintSnippet}

// The cached value is in the compartment of slotStorage,
// so wrap into the caller compartment as needed.
return ${maybeWrap}(cx, args.rval());
}
}

""",
markTaintSnippet=markTaintSnippet,
maybeWrap=getMaybeWrapValueFuncForType(self.attr.type),
)

Expand Down Expand Up @@ -11743,6 +11827,9 @@ def error_reporting_label(self):
def memberReturnsNewObject(member):
return member.getExtendedAttribute("NewObject") is not None

def memberIsTaintSource(member):
# Taintfox: check if this function is marked as a taint source:
return member.getExtendedAttribute("TaintSource") is not None

class CGMemberJITInfo(CGThing):
"""
Expand Down Expand Up @@ -19035,9 +19122,19 @@ def descriptorClearsPropsInSlots(descriptor):
for m in descriptor.interface.members
)

def hasAtLeastOneTaintsource(descriptor):
return any(
(m.isAttr() or m.isMethod()) and m.getExtendedAttribute("TaintSource")
for m in descriptor.interface.members
)

bindingHeaders["nsJSUtils.h"] = any(
descriptorClearsPropsInSlots(d) for d in descriptors
)

bindingHeaders["nsTaintingUtils.h"] = any(
hasAtLeastOneTaintsource(d) for d in descriptors
)

# Make sure we can sanely use binding_detail in generated code.
cgthings = [
Expand Down
2 changes: 2 additions & 0 deletions dom/bindings/parser/WebIDL.py
Original file line number Diff line number Diff line change
Expand Up @@ -5722,6 +5722,7 @@ def handleExtendedAttribute(self, attr):
or identifier == "BinaryName"
or identifier == "NonEnumerable"
or identifier == "BindingTemplate"
or identifier == "TaintSource" # Taintfox added
):
# Known attributes that we don't need to do anything with here
pass
Expand Down Expand Up @@ -6743,6 +6744,7 @@ def handleExtendedAttribute(self, attr):
or identifier == "NonEnumerable"
or identifier == "Unexposed"
or identifier == "WebExtensionStub"
or identifier == "TaintSource" # Taintfox added
):
# Known attributes that we don't need to do anything with here
pass
Expand Down
2 changes: 2 additions & 0 deletions dom/webidl/AudioContext.webidl
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ interface AudioContext : BaseAudioContext {
[Throws]
constructor(optional AudioContextOptions contextOptions = {});

[TaintSource]
readonly attribute double baseLatency;
[TaintSource]
readonly attribute double outputLatency;
AudioTimestamp getOutputTimestamp();

Expand Down
1 change: 1 addition & 0 deletions dom/webidl/AudioDestinationNode.webidl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
Exposed=Window]
interface AudioDestinationNode : AudioNode {

[TaintSource]
readonly attribute unsigned long maxChannelCount;

};
4 changes: 3 additions & 1 deletion dom/webidl/AudioNode.webidl
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,13 @@ interface AudioNode : EventTarget {
undefined disconnect(AudioParam destination, unsigned long output);

readonly attribute BaseAudioContext context;
[TaintSource]
readonly attribute unsigned long numberOfInputs;
[TaintSource]
readonly attribute unsigned long numberOfOutputs;

// Channel up-mixing and down-mixing rules for all inputs.
[SetterThrows]
[SetterThrows, TaintSource]
attribute unsigned long channelCount;
[SetterThrows, BinaryName="channelCountModeValue"]
attribute ChannelCountMode channelCountMode;
Expand Down
2 changes: 2 additions & 0 deletions dom/webidl/BaseAudioContext.webidl
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ enum AudioContextState {
[Exposed=Window]
interface BaseAudioContext : EventTarget {
readonly attribute AudioDestinationNode destination;
[TaintSource]
readonly attribute float sampleRate;
[TaintSource]
readonly attribute double currentTime;
readonly attribute AudioListener listener;
readonly attribute AudioContextState state;
Expand Down
2 changes: 1 addition & 1 deletion dom/webidl/HTMLCanvasElement.webidl
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ interface HTMLCanvasElement : HTMLElement {
[Throws]
nsISupports? getContext(DOMString contextId, optional any contextOptions = null);

[Throws, NeedsSubjectPrincipal]
[Throws, NeedsSubjectPrincipal, TaintSource]
DOMString toDataURL(optional DOMString type = "",
optional any encoderOptions);
[Throws, NeedsSubjectPrincipal]
Expand Down
2 changes: 2 additions & 0 deletions dom/webidl/HTMLElement.webidl
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,9 @@ partial interface HTMLElement {
readonly attribute Element? offsetParent;
readonly attribute long offsetTop;
readonly attribute long offsetLeft;
[TaintSource]
readonly attribute long offsetWidth;
[TaintSource]
readonly attribute long offsetHeight;
};

Expand Down
2 changes: 1 addition & 1 deletion dom/webidl/History.webidl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ enum ScrollRestoration { "auto", "manual" };

[Exposed=Window]
interface History {
[Throws]
[Throws, TaintSource]
readonly attribute unsigned long length;
[Throws]
attribute ScrollRestoration scrollRestoration;
Expand Down
4 changes: 4 additions & 0 deletions dom/webidl/MediaDeviceInfo.webidl
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,13 @@ enum MediaDeviceKind {
[Func="Navigator::HasUserMediaSupport",
Exposed=Window]
interface MediaDeviceInfo {
[TaintSource]
readonly attribute DOMString deviceId;
[TaintSource]
readonly attribute MediaDeviceKind kind;
[TaintSource]
readonly attribute DOMString label;
[TaintSource]
readonly attribute DOMString groupId;

[Default] object toJSON();
Expand Down
3 changes: 3 additions & 0 deletions dom/webidl/MimeType.webidl
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@

[Exposed=Window]
interface MimeType {
[TaintSource]
readonly attribute DOMString type;
[TaintSource]
readonly attribute DOMString description;
[TaintSource]
readonly attribute DOMString suffixes;
readonly attribute Plugin enabledPlugin;
};
Loading