Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 4 additions & 4 deletions cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,15 @@ def security_scan_with_justifications(

# Call the individual scan functions from SaferPickle to sets of results.
# Picklemagic Scan
picklemagic_results = safer_pickle.picklemagic_scan(pickle_bytes)
picklemagic_results = saferpickle.picklemagic_scan(pickle_bytes)

safe_results.update(picklemagic_results.safe_results)
unsafe_results.update(picklemagic_results.unsafe_results)
suspicious_results.update(picklemagic_results.suspicious_results)
unknown_results.update(picklemagic_results.unknown_results)

# Genops Scan
genops_results = safer_pickle.genops_scan(
genops_results = saferpickle.genops_scan(
pickle_bytes, pickle_file_path=file_path
)
safe_results.update(genops_results.safe_results)
Expand All @@ -97,15 +97,15 @@ def security_scan_with_justifications(
num_unsafe,
num_suspicious,
_, # The unknown_score is not used for classification, only reporting
) = safer_pickle.score_results(
) = saferpickle.score_results(
final_safe_results,
final_unsafe_results,
final_suspicious_results,
final_unknown_results,
)

# Check for safety and return the results with justifications.
if safer_pickle.is_unsafe(num_safe, num_unsafe, num_suspicious):
if saferpickle.is_unsafe(num_safe, num_unsafe, num_suspicious):
if num_unsafe > num_suspicious:
classification = "unsafe"
all_results = []
Expand Down
8 changes: 7 additions & 1 deletion lib/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@
"cProfile",
"cloudpickle.load",
"cloudpickle.loads",
"code.interact",
"code.InteractiveConsole",
"code.InteractiveInterpreter",
"codecs.decode",
"codeop.compile_command",
Expand All @@ -101,6 +103,7 @@
"eval",
"exec",
"execfile",
"fileinput",
"get_type_hints",
"gzip",
"hashlib",
Expand Down Expand Up @@ -134,7 +137,9 @@
"read",
"requests",
"runpy",
"safer_pickle_hook",
"safer_pickle",
"saferpickle",
"shutil",
"socket",
"ssl",
"stdin",
Expand Down Expand Up @@ -184,6 +189,7 @@
"reconstruct",
"scipy",
"set",
"shutil.disk_usage",
"sklearn",
"spacy",
"str",
Expand Down
2 changes: 1 addition & 1 deletion lib/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

"""Utility functions for safer_pickle."""
"""Utility functions for saferpickle."""

import ast
import bz2
Expand Down
58 changes: 21 additions & 37 deletions saferpickle.py
Original file line number Diff line number Diff line change
Expand Up @@ -626,41 +626,25 @@ def strict_security_scan(pickle_bytes: bytes) -> bool:


def is_unsafe(
number_of_safe_results: int,
number_of_unsafe_results: int,
number_of_suspicious_results: int,
safe_score: int,
unsafe_score: int,
suspicious_score: int,
) -> bool:
"""Conditional check for safeness.

Args:
number_of_safe_results: Number of safe results from the security scan.
number_of_unsafe_results: Number of unsafe results from the security scan.
number_of_suspicious_results: Number of suspicious results from the security
scan.
safe_score: Safe score from the security scan.
unsafe_score: Unsafe score from the security scan.
suspicious_score: Suspicious score from the security scan.

Returns:
True if the pickle file is dangerous, False otherwise.
"""
if number_of_unsafe_results == 0 and number_of_suspicious_results == 0:
if unsafe_score == 0 and suspicious_score == 0:
return False

# We halve the weight of suspicious results to lower false positives
# caused by greedy matches of unknown method-like strings (Ex. "google.com")
if (
number_of_suspicious_results + number_of_unsafe_results
>= number_of_safe_results
):
return True

sum_of_unsafe_and_suspicious_results = (
number_of_unsafe_results + 0.5 * number_of_suspicious_results
)

unsafe = (sum_of_unsafe_and_suspicious_results > number_of_safe_results) or (
number_of_safe_results == 0 and sum_of_unsafe_and_suspicious_results >= 1
)

return unsafe
sum_of_unsafe_and_suspicious_scores = unsafe_score + 0.5 * suspicious_score
return sum_of_unsafe_and_suspicious_scores >= safe_score


def picklemagic_scan(
Expand Down Expand Up @@ -741,8 +725,8 @@ def score_results(
number_of_unknown_results = len(unknown_results)

safe_score = math.log(number_of_safe_results + 1) * 2
unsafe_score = math.log(number_of_unsafe_results + 1) * 4
suspicious_score = math.log(number_of_suspicious_results + 1) * 3
unsafe_score = math.log(number_of_unsafe_results + 1) * 10
suspicious_score = math.log(number_of_suspicious_results + 1) * 5
unknown_score = math.log(number_of_unknown_results + 1) * 1

return (
Expand Down Expand Up @@ -785,25 +769,25 @@ def apply_approach(
logging.info(" Unknown results: %s\n", results.unknown_results)

(
number_of_safe_results,
number_of_unsafe_results,
number_of_suspicious_results,
number_of_unknown_results,
safe_score,
unsafe_score,
suspicious_score,
unknown_score,
) = score_results(
results.safe_results,
results.unsafe_results,
results.suspicious_results,
results.unknown_results,
)
scores = {
"unsafe": number_of_unsafe_results,
"suspicious": number_of_suspicious_results,
"unknown": number_of_unknown_results,
"unsafe": unsafe_score,
"suspicious": suspicious_score,
"unknown": unknown_score,
}
if results.is_denylisted or is_unsafe(
number_of_safe_results,
number_of_unsafe_results,
number_of_suspicious_results,
safe_score,
unsafe_score,
suspicious_score,
):
return scores

Expand Down