Skip to content

Commit 0585333

Browse files
authored
Add support for secure marks (#72)
* Add support for secure marks * Fixes from PR comments * Change int to secure_marks_t * Add secureMarks property to taintedRange definition
1 parent d0f45a5 commit 0585333

19 files changed

+341
-24
lines changed

index.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ declare module 'datadog-iast-taint-tracking' {
1616
start: number;
1717
end: number;
1818
iinfo: NativeInputInfo;
19+
secureMarks: number;
1920
readonly ref?: string;
2021
}
2122

@@ -26,6 +27,7 @@ declare module 'datadog-iast-taint-tracking' {
2627
export interface TaintedUtils {
2728
createTransaction(transactionId: string): string;
2829
newTaintedString(transactionId: string, original: string, paramName: string, type: string): string;
30+
addSecureMarksToTaintedString(transactionId: string, taintedString: string, secureMarks: number): string;
2931
isTainted(transactionId: string, ...args: string[]): boolean;
3032
getMetrics(transactionId: string, telemetryVerbosity: number): Metrics;
3133
getRanges(transactionId: string, original: string): NativeTaintedRange[];

index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ try {
1616
newTaintedString (transactionId, original) {
1717
return original
1818
},
19+
addSecureMarksToTaintedString (transactionId, original) {
20+
return original
21+
},
1922
isTainted () {
2023
return false
2124
},
@@ -55,6 +58,7 @@ try {
5558

5659
const iastNativeMethods = {
5760
newTaintedString: addon.newTaintedString,
61+
addSecureMarksToTaintedString: addon.addSecureMarksToTaintedString,
5862
isTainted: addon.isTainted,
5963
getMetrics: addon.getMetrics,
6064
getRanges: addon.getRanges,

src/api/concat.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ void TaintConcatOperator(const FunctionCallbackInfo<Value>& args) {
7070
auto argRange = *it;
7171
auto newRange = transaction->GetRange(offset + argRange->start
7272
, offset + argRange->end,
73-
argRange->inputInfo);
73+
argRange->inputInfo, argRange->secureMarks);
7474
ranges->PushBack(newRange);
7575
}
7676
} else {

src/api/replace.cc

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ inline void addReplacerRanges(Transaction* transaction,
5858
for (auto replacerIt = replacerRanges->begin(); replacerItEnd != replacerIt; replacerIt++) {
5959
auto range = (*replacerIt);
6060
newRanges->PushBack(transaction->GetRange(range->start + toReplaceStart,
61-
range->end + toReplaceStart, range->inputInfo));
61+
range->end + toReplaceStart, range->inputInfo, range->secureMarks));
6262
}
6363
}
6464
}
@@ -86,7 +86,8 @@ inline SharedRanges* adjustReplacementRanges(Transaction* transaction,
8686
if (range->end <= toReplaceStart) {
8787
newRanges->PushBack(range);
8888
} else if (range->end > toReplaceStart) {
89-
newRanges->PushBack(transaction->GetRange(range->start, toReplaceStart, range->inputInfo));
89+
newRanges->PushBack(transaction->GetRange(range->start, toReplaceStart,
90+
range->inputInfo, range->secureMarks));
9091
break;
9192
}
9293
++subjectIt;
@@ -102,13 +103,13 @@ inline SharedRanges* adjustReplacementRanges(Transaction* transaction,
102103
if (range->start <= toReplaceEnd) {
103104
newRanges->PushBack(transaction->GetRange(toReplaceEnd + offset,
104105
range->end + offset,
105-
range->inputInfo));
106+
range->inputInfo, range->secureMarks));
106107
} else if (offset == 0) {
107108
newRanges->PushBack(range);
108109
} else {
109110
newRanges->PushBack(transaction->GetRange(range->start + offset,
110111
range->end + offset,
111-
range->inputInfo));
112+
range->inputInfo, range->secureMarks));
112113
}
113114
}
114115
subjectIt++;
@@ -161,7 +162,7 @@ inline SharedRanges* adjustRegexReplacementRanges(Transaction* transaction,
161162
if (start == range->start && end == range->end) {
162163
newRanges->PushBack(range);
163164
} else {
164-
newRanges->PushBack(transaction->GetRange(start, end, range->inputInfo));
165+
newRanges->PushBack(transaction->GetRange(start, end, range->inputInfo, range->secureMarks));
165166
}
166167
}
167168
if (breakLoop) {
@@ -183,13 +184,13 @@ inline SharedRanges* adjustRegexReplacementRanges(Transaction* transaction,
183184
if (lastEnd < range->end) {
184185
if (lastEnd > range->start) {
185186
newRanges->PushBack(transaction->GetRange(lastEnd + offset, range->end + offset,
186-
range->inputInfo));
187+
range->inputInfo, range->secureMarks));
187188
} else if (offset == 0) {
188189
newRanges->PushBack(range);
189190
} else {
190191
newRanges->PushBack(
191192
transaction->GetRange(range->start + offset, range->end + offset,
192-
range->inputInfo));
193+
range->inputInfo, range->secureMarks));
193194
}
194195
}
195196
++subjectIt;

src/api/string_methods.cc

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "../gc/gc.h"
2222
#include "../iast.h"
2323
#include "v8.h"
24+
#include "../utils/string_utils.h"
2425

2526
using v8::Exception;
2627
using v8::FunctionCallbackInfo;
@@ -33,6 +34,7 @@ using v8::Value;
3334
using v8::Array;
3435

3536
using iast::tainted::InputInfo;
37+
using iast::tainted::secure_marks_t;
3638

3739
namespace iast {
3840
namespace api {
@@ -98,7 +100,7 @@ void NewTaintedString(const FunctionCallbackInfo<Value>& args) {
98100

99101
auto range = transaction->GetRange(0,
100102
utils::GetLength(args.GetIsolate(), parameterValue),
101-
inputInfo);
103+
inputInfo, 0);
102104
auto ranges = transaction->GetSharedVectorRange();
103105
ranges->PushBack(range);
104106
auto stringPointer = utils::GetLocalStringPointer(parameterValue);
@@ -112,6 +114,71 @@ void NewTaintedString(const FunctionCallbackInfo<Value>& args) {
112114
}
113115
}
114116

117+
void AddSecureMarksToTaintedString(const FunctionCallbackInfo<Value>& args) {
118+
auto isolate = args.GetIsolate();
119+
if (args.Length() < 3) {
120+
isolate->ThrowException(v8::Exception::TypeError(
121+
v8::String::NewFromUtf8(isolate,
122+
"Wrong number of arguments",
123+
v8::NewStringType::kNormal).ToLocalChecked()));
124+
return;
125+
}
126+
127+
if (!(args[0]->IsString()) || !Local<String>::Cast(args[0])->Length()) {
128+
// invalid transaction id, return taintedString
129+
args.GetReturnValue().Set(args[1]);
130+
return;
131+
}
132+
133+
if (!(args[1]->IsString())) {
134+
// invalid taintedString, return it
135+
args.GetReturnValue().Set(args[1]);
136+
return;
137+
}
138+
139+
auto context = isolate->GetCurrentContext();
140+
141+
auto transactionIdArgument = args[0];
142+
auto taintedString = args[1];
143+
auto secureMarksArgument = args[2];
144+
145+
args.GetReturnValue().Set(taintedString);
146+
147+
secure_marks_t secureMarks = secureMarksArgument->IntegerValue(context).FromJust();
148+
if (secureMarks == 0) {
149+
// not secure marks to add
150+
return;
151+
}
152+
153+
uintptr_t transactionId = utils::GetLocalStringPointer(transactionIdArgument);
154+
auto transaction = NewTransaction(transactionId);
155+
if (transaction == nullptr) {
156+
return;
157+
}
158+
auto taintedObj = transaction->FindTaintedObject(utils::GetLocalStringPointer(taintedString));
159+
if (!taintedObj) {
160+
// It is not a tainted object, do nothing
161+
return;
162+
}
163+
try {
164+
auto newRanges = transaction->GetSharedVectorRange();
165+
auto oRanges = taintedObj->getRanges();
166+
taintedString = tainted::NewStringInstanceForNewTaintedObject
167+
(isolate, v8::Local<v8::String>::Cast(taintedString));
168+
for (auto it = oRanges->begin(); it != oRanges->end(); ++it) {
169+
auto oRange = *it;
170+
auto start = oRange->start;
171+
auto end = oRange->end;
172+
auto oSecureMarks = oRange->secureMarks;
173+
newRanges->PushBack(transaction->GetRange(start, end, oRange->inputInfo, oSecureMarks | secureMarks));
174+
}
175+
transaction->AddTainted(utils::GetLocalStringPointer(taintedString), newRanges, taintedString);
176+
args.GetReturnValue().Set(taintedString);
177+
} catch (const std::bad_alloc& err) {
178+
} catch (const container::QueuedPoolBadAlloc& err) {
179+
} catch (const container::PoolBadAlloc& err) {
180+
}
181+
}
115182
void IsTainted(const FunctionCallbackInfo<Value>& args) {
116183
auto argsLength = args.Length();
117184
if (argsLength < 2) {
@@ -149,7 +216,6 @@ void GetRanges(const FunctionCallbackInfo<Value>& args) {
149216
NewStringType::kNormal).ToLocalChecked()));
150217
return;
151218
}
152-
153219
uintptr_t transactionId = utils::GetLocalStringPointer(args[0]);
154220
auto transaction = GetTransaction(transactionId);
155221
if (transaction != nullptr) {
@@ -206,6 +272,7 @@ void SetMaxTransactions(const FunctionCallbackInfo<Value>& args) {
206272
void StringMethods::Init(Local<Object> exports) {
207273
NODE_SET_METHOD(exports, "createTransaction", CreateTransaction);
208274
NODE_SET_METHOD(exports, "newTaintedString", NewTaintedString);
275+
NODE_SET_METHOD(exports, "addSecureMarksToTaintedString", AddSecureMarksToTaintedString);
209276
NODE_SET_METHOD(exports, "isTainted", IsTainted); // TODO(julio): support several objects.
210277
NODE_SET_METHOD(exports, "getRanges", GetRanges);
211278
NODE_SET_METHOD(exports, "removeTransaction", DeleteTransaction);

src/api/trim.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ void TaintTrimOperator(const FunctionCallbackInfo<Value>& args) {
8585
}
8686

8787
if (newRangeEnd > newRangeStart) {
88-
auto newRange = transaction->GetRange(newRangeStart, newRangeEnd, range->inputInfo);
88+
auto newRange = transaction->GetRange(newRangeStart, newRangeEnd, range->inputInfo, range->secureMarks);
8989
resultRanges->PushBack(newRange);
9090
}
9191
}
@@ -150,7 +150,7 @@ void TaintTrimEndOperator(const FunctionCallbackInfo<Value>& args) {
150150
}
151151

152152
if (newRangeEnd > newRangeStart) {
153-
auto newRange = transaction->GetRange(newRangeStart, newRangeEnd, range->inputInfo);
153+
auto newRange = transaction->GetRange(newRangeStart, newRangeEnd, range->inputInfo, range->secureMarks);
154154
resultRanges->PushBack(newRange);
155155
}
156156
}

src/tainted/range.cc

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,20 @@ bool labelsDefined = false;
1919
v8::Persistent<v8::Value> startLabel;
2020
v8::Persistent<v8::Value> endLabel;
2121
v8::Persistent<v8::Value> iinfoLabel;
22-
Range::Range(int start, int end, InputInfo *inputInfo) {
22+
v8::Persistent<v8::Value> secureMarksLabel;
23+
24+
Range::Range(int start, int end, InputInfo *inputInfo, secure_marks_t secureMarks) {
2325
this->start = start;
2426
this->end = end;
2527
this->inputInfo = inputInfo;
28+
this->secureMarks = secureMarks;
2629
}
2730

2831
Range::Range(const Range& range) {
2932
this->start = range.start;
3033
this->end = range.end;
3134
this->inputInfo = range.inputInfo;
35+
this->secureMarks = range.secureMarks;
3236
}
3337

3438
Range::~Range() {}
@@ -39,25 +43,30 @@ v8::Local<v8::Object> Range::toJSObject(v8::Isolate* isolate) {
3943
v8::Local<v8::Value> startLabelLocal;
4044
v8::Local<v8::Value> endLabelLocal;
4145
v8::Local<v8::Value> iinfoLabelLocal;
46+
v8::Local<v8::Value> secureMarksLabelLocal;
4247
if (!labelsDefined) {
4348
startLabelLocal = utils::NewV8String(isolate, "start");
4449
endLabelLocal = utils::NewV8String(isolate, "end");
4550
iinfoLabelLocal = utils::NewV8String(isolate, "iinfo");
51+
secureMarksLabelLocal = utils::NewV8String(isolate, "secureMarks");
4652
startLabel.Reset(isolate, startLabelLocal);
4753
endLabel.Reset(isolate, endLabelLocal);
4854
iinfoLabel.Reset(isolate, iinfoLabelLocal);
55+
secureMarksLabel.Reset(isolate, secureMarksLabelLocal);
4956
labelsDefined = true;
5057
} else {
5158
startLabelLocal = v8::Local<v8::Value>::New(isolate, startLabel);
5259
endLabelLocal = v8::Local<v8::Value>::New(isolate, endLabel);
5360
iinfoLabelLocal = v8::Local<v8::Value>::New(isolate, iinfoLabel);
61+
secureMarksLabelLocal = v8::Local<v8::Value>::New(isolate, secureMarksLabel);
5462
}
5563

5664
taintedRangev8Obj->Set(context, startLabelLocal, v8::Number::New(isolate, this->start)).Check();
5765
taintedRangev8Obj->Set(context, endLabelLocal, v8::Number::New(isolate, this->end)).Check();
5866
taintedRangev8Obj->Set(context,
5967
iinfoLabelLocal,
6068
GetJsObjectFromInputInfo(isolate, context, this->inputInfo)).Check();
69+
taintedRangev8Obj->Set(context, secureMarksLabelLocal, v8::Number::New(isolate, this->secureMarks)).Check();
6170

6271
return taintedRangev8Obj;
6372
}

src/tainted/range.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,17 @@
1111

1212
namespace iast {
1313
namespace tainted {
14+
using secure_marks_t = uint16_t;
1415
class Range {
1516
public:
16-
explicit Range(int start, int end, InputInfo *inputInfo);
17+
explicit Range(int start, int end, InputInfo *inputInfo, secure_marks_t secureMarks);
1718
Range(const Range& taintedRange);
1819
~Range();
1920
v8::Local<v8::Object> toJSObject(v8::Isolate* isolate);
2021
int start;
2122
int end;
2223
InputInfo* inputInfo;
24+
secure_marks_t secureMarks;
2325
};
2426
} // namespace tainted
2527
} // namespace iast

src/tainted/string_resource.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#ifndef SRC_TAINTED_STRING_RESOURCE_H_
66
#define SRC_TAINTED_STRING_RESOURCE_H_
77
#include <node.h>
8+
#include <string>
89

910
namespace iast {
1011
namespace tainted {
@@ -27,6 +28,16 @@ class StringResource : public v8::String::ExternalStringResource {
2728
};
2829

2930
v8::Local<v8::String> NewExternalString(v8::Isolate* isolate, v8::Local<v8::Value> obj);
31+
inline v8::Local<v8::String> NewStringInstanceForNewTaintedObject(v8::Isolate* isolate, v8::Local<v8::String> obj) {
32+
int len = obj->Length();
33+
if (len == 1) {
34+
return tainted::NewExternalString(isolate, obj);
35+
} else {
36+
v8::String::Utf8Value param1(isolate, obj);
37+
std::string cppStr(*param1);
38+
return v8::String::NewFromUtf8(isolate, cppStr.c_str(), v8::NewStringType::kNormal).ToLocalChecked();
39+
}
40+
}
3041
} // namespace tainted
3142
} // namespace iast
3243
#endif // SRC_TAINTED_STRING_RESOURCE_H_

src/tainted/transaction.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ class Transaction {
3939
v8::Local<v8::Value> parameterValue,
4040
v8::Local<v8::Value> type);
4141

42-
Range* GetRange(int start, int end, InputInfo *inputInfo) {
43-
return _rangesPool.Pop(start, end, inputInfo);
42+
Range* GetRange(int start, int end, InputInfo *inputInfo, secure_marks_t secureMarks) {
43+
return _rangesPool.Pop(start, end, inputInfo, secureMarks);
4444
}
4545

4646
SharedRanges* GetSharedVectorRange(void) {

0 commit comments

Comments
 (0)