Skip to content

Commit

Permalink
ArcsJs/Raksha - Relations for tracking parameterized tags for non-agg…
Browse files Browse the repository at this point in the history
…regation

PiperOrigin-RevId: 501728056
  • Loading branch information
arcs-c3po committed Jan 20, 2023
1 parent 17f1f36 commit 80ad0d0
Show file tree
Hide file tree
Showing 14 changed files with 356 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/analysis/souffle/arcsjs_input_and_output.dl
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,4 @@ violatesPolicy(result, ARCSJS_CONSTRUCTION_POLICY, cat("Malformed output operati
#undef ARCSJS_CONNECT_OUTPUT_STORE_ARGUMENT_INDEX
#undef ARCSJS_NAME_ATTRIBUTE

#endif // SRC_ANALYSIS_SOUFFLE_ARCSJS_INPUT_AND_OUTPUT_DL_
#endif // SRC_ANALYSIS_SOUFFLE_ARCSJS_INPUT_AND_OUTPUT_DL_
75 changes: 75 additions & 0 deletions src/analysis/souffle/arcsjs_restrict_aggregation.dl
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
//-----------------------------------------------------------------------------
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//-----------------------------------------------------------------------------
#ifndef SRC_ANALYSIS_SOUFFLE_ARCSJS_RESTRICT_AGGREGATION_DL_
#define SRC_ANALYSIS_SOUFFLE_ARCSJS_RESTRICT_AGGREGATION_DL_

#include "src/analysis/souffle/arcsjs_core.dl"
#define ARCSJS_RESTRICT_AGGREGATION "arcsjs.restrict_aggregation"
#define ARCSJS_RESTRICT_AGGREGATION_HIDDEN_TAG_ATTR "tag"

.decl arcsJsIsRestrictAggregationOperation(op: Operation)
arcsJsIsRestrictAggregationOperation(op) :-
isOperation(op),
operationHasOperator(op, ARCSJS_RESTRICT_AGGREGATION).

.decl arcsJsHasRestrictAggregationConfiguration(tag: Tag, new_tag: Tag, source: AccessPath)

isTag(as(tag, Tag)),
arcsJsHasRestrictAggregationConfiguration(
as(tag, Tag),
as(cat(cat("restrict_aggregation_", as(tag, symbol)), cat("_", as(source, symbol))), Tag),
source
) :-
arcsJsIsRestrictAggregationOperation(op),
operationHasOperandAtIndex(op, source, _),
operationHasAttribute(
op,
[ARCSJS_RESTRICT_AGGREGATION_HIDDEN_TAG_ATTR, $StringAttributePayload(tag)]
).

isConditionalTag(new_tag),
isTag(new_tag) :-
arcsJsHasRestrictAggregationConfiguration(_, new_tag, _).

mayHaveTag(result, DEFAULT_ARCSJS_OWNER, new_tag) :-
arcsJsIsRestrictAggregationOperation(op),
operationHasOperandAtIndex(op, source, _),
arcsJsHasRestrictAggregationConfiguration(_, new_tag, source),
operationHasResult(op, result).

mayHaveTag(result, DEFAULT_ARCSJS_OWNER, tag) :-
arcsJsHasRestrictAggregationConfiguration(tag, new_tag, _),
mayHaveTag(source1, _, new_tag),
resolvedEdge(_, source1, result),
resolvedEdge(_, source2, result),
source1 != source2,
mayHaveTag(source2, _, new_tag).

.decl policyArcsJsConformingRestrictAggregation(op: Operation)
policyArcsJsConformingRestrictAggregation(op) :-
arcsJsIsRestrictAggregationOperation(op),
operationHasAttribute(op, [ARCSJS_RESTRICT_AGGREGATION_HIDDEN_TAG_ATTR, tag]),
count : { operationHasOperandAtIndex(op, _, _) } = 1.

violatesPolicy(
result,
ARCSJS_CONSTRUCTION_POLICY,
cat("Malformed restrict_aggregation operation at ", result)) :-
arcsJsIsRestrictAggregationOperation(op),
!policyArcsJsConformingRestrictAggregation(op),
operationHasResult(op, result).

#endif // SRC_ANALYSIS_SOUFFLE_ARCSJS_RESTRICT_AGGREGATION_DL_
1 change: 1 addition & 0 deletions src/analysis/souffle/dl_file_lists.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ arcsjs_dl_files_local = [
"arcsjs_input_and_output.dl",
"arcsjs_make_public.dl",
"arcsjs_opaque.dl",
"arcsjs_restrict_aggregation.dl",
"arcsjs_user_consent_to_downgrade.dl",
]

Expand Down
1 change: 1 addition & 0 deletions src/analysis/souffle/policy_verifier_interface.dl
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "src/analysis/souffle/arcsjs_input_and_output.dl"
#include "src/analysis/souffle/arcsjs_make_public.dl"
#include "src/analysis/souffle/arcsjs_opaque.dl"
#include "src/analysis/souffle/arcsjs_restrict_aggregation.dl"
#include "src/analysis/souffle/arcsjs_user_consent_to_downgrade.dl"
#include "src/analysis/souffle/tag_transforms.dl"
#include "src/analysis/souffle/epsilon_analysis.dl"
Expand Down
1 change: 1 addition & 0 deletions src/analysis/souffle/tests/arcs_fact_tests/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ exports_files([
"//src/analysis/souffle:arcsjs_input_and_output.dl",
"//src/analysis/souffle:arcsjs_make_public.dl",
"//src/analysis/souffle:arcsjs_opaque.dl",
"//src/analysis/souffle:arcsjs_restrict_aggregation.dl",
"//src/analysis/souffle:arcsjs_user_consent_to_downgrade.dl",
"//src/analysis/souffle:attributes.dl",
"//src/analysis/souffle:authorization_logic.dl",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//-----------------------------------------------------------------------------
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//-----------------------------------------------------------------------------

#include "src/analysis/souffle/arcsjs_test_helper.dl"
#include "src/analysis/souffle/arcsjs_restrict_aggregation.dl"

.output arcsJsHasRestrictAggregationConfiguration(IO=stdout, delimiter=";")
.output hasTag(IO=stdout, delimiter=";")
.output mayHaveTag(IO=stdout, delimiter=";")
.output arcsJsIsRestrictAggregationOperation(IO=stdout, delimiter=";")

#define RESTRICT_AGGREGATION_CREATE_AND_TEST_OPERATOR_INNER(n_tags, test_name, owner, operation, tag, source, hidden_tag) \
isOperation(operation). \
TEST_CASE(cat(test_name, "_arcsJsIsRestrictAggregationOperation")) :- \
arcsJsIsRestrictAggregationOperation(operation). \
TEST_CASE(cat(test_name, "_isConditionalTag")) :- \
isConditionalTag(tag). \
TEST_CASE(cat(test_name, "_arcsJsHasRestrictAggregationConfiguration")) :- \
count : { arcsJsHasRestrictAggregationConfiguration(hidden_tag, tag, source) } = n_tags, \
count : { arcsJsHasRestrictAggregationConfiguration(_, tag, source) } = n_tags

#define RESTRICT_AGGREGATION_CREATE_AND_TEST_OPERATION(n_tags, test_name, owner, operator, result, operandList, attrList, tag, source, hidden_tag) \
RESTRICT_AGGREGATION_CREATE_AND_TEST_OPERATOR_INNER(n_tags, test_name, owner, ([owner, operator, ([result, nil]), (operandList), (attrList)]), tag, source, hidden_tag)

#define RESTRICT_AGGREGATION_CREATE_AND_TEST_OPERATOR_INNER_VIOLATES(test_name, owner, operation) \
isOperation(operation). \
TEST_N_RESULT2_FOR_OPERATION(1, test_name, (operation), violatesPolicy, "arcsjs.construction", _)

#define RESTRICT_AGGREGATION_CREATE_AND_TEST_OPERATION_VIOLATES(test_name, owner, operator, result, operandList, attrList) \
RESTRICT_AGGREGATION_CREATE_AND_TEST_OPERATOR_INNER_VIOLATES(test_name, owner, ([owner, operator, ([result, nil]), (operandList), (attrList)]))

#define ATTR_LIST1 [["tag", $StringAttributePayload("private")], nil]
#define OPERAND_LIST1 ["operand1", nil]

RESTRICT_AGGREGATION_CREATE_AND_TEST_OPERATION(1, "test1_restrict_aggregation", "somePrincipal", "arcsjs.restrict_aggregation", "ap1", (OPERAND_LIST1), (ATTR_LIST1), "restrict_aggregation_private_operand1", "operand1", "private").

#define ATTR_LIST2 [["tag", $StringAttributePayload("hello1")], [["wrong_tag", $NumberAttributePayload(2)], nil]]
#define OPERAND_LIST2 ["input1", nil]

RESTRICT_AGGREGATION_CREATE_AND_TEST_OPERATION(1, "test2_restrict_aggregation_ignores_extra_attrs", "prin", "arcsjs.restrict_aggregation", "ap3", (OPERAND_LIST2), (ATTR_LIST2), "restrict_aggregation_hello1_input1", "input1", "hello1").

#define ATTR_LIST3 [["tag", $StringAttributePayload("private")], [["wrong_tag", $NumberAttributePayload(2)], nil]]
#define OPERAND_LIST3 ["input2", ["input2", nil]]
RESTRICT_AGGREGATION_CREATE_AND_TEST_OPERATION_VIOLATES("test3_restrict_aggregation_errors_on_extra_args", "prin", "arcsjs.restrict_aggregation", "ap5", (OPERAND_LIST3), (ATTR_LIST3)).

#define ATTR_LIST4 [["tag", $StringAttributePayload("private")], [["wrong_tag", $NumberAttributePayload(2)], nil]]
RESTRICT_AGGREGATION_CREATE_AND_TEST_OPERATION_VIOLATES("test4_restrict_aggregation_requires_arg", "prin", "arcsjs.restrict_aggregation", "ap9", nil, (ATTR_LIST4)).

#define ATTR_LIST6 [["tag", $StringAttributePayload("private1")], [["tag", $StringAttributePayload("private2")], nil]]
#define OPERAND_LIST6 ["input3", nil]

RESTRICT_AGGREGATION_CREATE_AND_TEST_OPERATION(2, "test5_restrict_aggregation_maps_over_tags", "prin", "arcsjs.restrict_aggregation", "ap11", (OPERAND_LIST6), (ATTR_LIST6), _, "input3", _).
7 changes: 7 additions & 0 deletions src/backends/policy_engine/souffle/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,13 @@ cc_binary(
("opaque_wrap_failing_arcsjs_two_arguments", "fail"),
("opaque_wrap_and_unwrap_passing_arcsjs", "pass"),
("opaque_wrap_taint_and_unwrap_failing_arcsjs_taint_not_discharged", "fail"),
("restrict_aggregation_and_never_use_passing_arcsjs", "pass"),
("restrict_aggregation_and_use_once_passing_arcsjs", "pass"),
("restrict_aggregation_failing_arcsjs_no_tag", "fail"),
("restrict_aggregation_failing_arcsjs_no_argument", "fail"),
("restrict_aggregation_failing_arcsjs_two_arguments", "fail"),
("restrict_aggregation_failing_arcsjs_merge_disallowed_same_source", "fail"),
("restrict_aggregation_failing_arcsjs_merge_disallowed_different_sources", "fail"),
("check_not_failing_arcsjs_has_tag", "fail"),
("user_action_passing_arcsjs", "pass"),
("large_sample_passing_arcsjs", "pass"),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//-----------------------------------------------------------------------------
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//-----------------------------------------------------------------------------

module m0 {
block b0 {
%0 = arcsjs.create_store[name: "SimpleRecipe.fingerprintable_texts", type: "List_Text"]()
%1 = arcsjs.create_store[name: "SimpleRecipe.output", type: "List_Text"]()
%2 = arcsjs.restrict_aggregation[tag: "private"](%0)

%3 = arcsjs.particle[name: "SimpleRecipe.exfil_particle"]()
%6 = arcsjs.connect_output[name: "baz"](%3, %1)
// Policy check passes because we are not publicizing private data.
%7 = arcjs.make_public[](%1)
} // block b0
} // module m0
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//-----------------------------------------------------------------------------
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//-----------------------------------------------------------------------------

module m0 {
block b0 {
%0 = arcsjs.create_store[name: "SimpleRecipe.fingerprintable_texts", type: "List_Text"]()
%1 = arcsjs.restrict_aggregation[tag: "private"](%0)
%2 = arcsjs.create_store[name: "SimpleRecipe.output", type: "List_Text"]()

%3 = arcsjs.particle[name: "SimpleRecipe.exfil_particle"]()
%4 = arcsjs.connect_input[name: "bar"](%3, %1)
%6 = arcsjs.connect_output[name: "baz"](%3, %2)
// Policy check passes because we are not publicizing private data.
%7 = arcjs.make_public[](%2)
} // block b0
} // module m0
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//-----------------------------------------------------------------------------
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//-----------------------------------------------------------------------------

module m0 {
block b0 {
%0 = arcsjs.create_store[name: "SimpleRecipe.fingerprintable_texts", type: "List_Text"]()
%1 = arcsjs.create_store[name: "SimpleRecipe.output", type: "List_Text"]()
%2 = arcsjs.restrict_aggregation[tag: "private"](%0)
%3 = copy[](%2) // Some unknown copy operation.

%4 = arcsjs.particle[name: "SimpleRecipe.exfil_particle"]()
%5 = arcsjs.connect_input[name: "foo"](%4, %2)
%6 = arcsjs.connect_input[name: "bar"](%4, %3)
%7 = arcsjs.connect_output[name: "baz"](%4, %1)
// Policy check passes because we are not publicizing private data.
%8 = arcsjs.make_public[](%1)
} // block b0
} // module m0
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//-----------------------------------------------------------------------------
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//-----------------------------------------------------------------------------

module m0 {
block b0 {
%0 = arcsjs.create_store[name: "SimpleRecipe.fingerprintable_texts", type: "List_Text"]()
%1 = arcsjs.create_store[name: "SimpleRecipe.output", type: "List_Text"]()
%2 = arcsjs.restrict_aggregation[tag: "private"](%0)

%4 = arcsjs.particle[name: "SimpleRecipe.exfil_particle"]()
%5 = arcsjs.connect_input[name: "foo"](%4, %2)
%6 = arcsjs.connect_input[name: "bar"](%4, %2)
%7 = arcsjs.connect_output[name: "baz"](%4, %1)
// Policy check passes because we are not publicizing private data.
%8 = arcsjs.make_public[](%1)
} // block b0
} // module m0
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//-----------------------------------------------------------------------------
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//-----------------------------------------------------------------------------

module m0 {
block b0 {
%0 = arcsjs.create_store[name: "SimpleRecipe.fingerprintable_texts", type: "List_Text"]()
%1 = arcsjs.create_store[name: "SimpleRecipe.output", type: "List_Text"]()
%2 = arcsjs.restrict_aggregation[tag: "private"]()

%3 = arcsjs.particle[name: "SimpleRecipe.exfil_particle"]()
%4 = arcsjs.connect_input[name: "foo"](%3, %2)
%6 = arcsjs.connect_output[name: "baz"](%3, %1)
// Policy check passes because we are not publicizing private data.
%7 = arcjs.make_public[](%1)
} // block b0
} // module m0
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//-----------------------------------------------------------------------------
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//-----------------------------------------------------------------------------

module m0 {
block b0 {
%0 = arcsjs.create_store[name: "SimpleRecipe.fingerprintable_texts", type: "List_Text"]()
%1 = arcsjs.create_store[name: "SimpleRecipe.output", type: "List_Text"]()
%2 = arcsjs.restrict_aggregation[](%0)

%3 = arcsjs.particle[name: "SimpleRecipe.exfil_particle"]()
%4 = arcsjs.connect_input[name: "foo"](%3, %2)
%6 = arcsjs.connect_output[name: "baz"](%3, %1)
// Policy check passes because we are not publicizing private data.
%7 = arcjs.make_public[](%1)
} // block b0
} // module m0
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//-----------------------------------------------------------------------------
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//-----------------------------------------------------------------------------

module m0 {
block b0 {
%0 = arcsjs.create_store[name: "SimpleRecipe.fingerprintable_texts", type: "List_Text"]()
%1 = arcsjs.create_store[name: "SimpleRecipe.output", type: "List_Text"]()
%2 = arcsjs.restrict_aggregation[tag: "private"](%0, %2)

%3 = arcsjs.particle[name: "SimpleRecipe.exfil_particle"]()
%4 = arcsjs.connect_input[name: "foo"](%3, %2)
%6 = arcsjs.connect_output[name: "baz"](%3, %1)
// Policy check passes because we are not publicizing private data.
%7 = arcjs.make_public[](%1)
} // block b0
} // module m0

0 comments on commit 80ad0d0

Please sign in to comment.