security: E2EE and transport correctness (issue #147) #173
Open
jabber.developer2
wants to merge 1 commits from
fix/e2ee-transport-147 into master
pull from: fix/e2ee-transport-147
merge into: devs:master
devs:master
devs:fix/disco-info-null-from
devs:fix/editor-terminal-size
devs:fix/data-at-rest-hardening
devs:fix/omemo-prosody-bootstrap
devs:feat/ai-api-type
devs:ci/docker-hub-publishing
devs:feat/disco-ac
devs:feat/privacy-enhancements
devs:fix/clientid-regression
devs:fix/ai-chat-completions-followup
devs:feat/ai-custom
devs:fix/unencrypted-send
devs:rollback/pre-upstream-merge
devs:fix/autoping-warning-null-domain
devs:fix/pad-dead-space-reclaim
devs:feat/autoping-warning
devs:chore/untrack-gitversion
devs:fix/multiline-pad-clip
devs:fix/issue-112-followups
devs:fix/issue-128-migrate-v3-dedup
devs:fix/delay-timestamp-validation
devs:ref/light-cleanup
devs:fix/history-scroll-pad-redraw-storm
devs:fix/plugin-post-display-incoming-only
devs:merge/upstream-full
devs:merge-improve
devs:chore/remove-chatlog-stage-1
devs:fix/ai-json-encoding
devs:feat/no-db-backlog-114
devs:fix/scroll-non-chat-windows
devs:fix/paged-non-chat-windows
devs:fix/ai-leaks
devs:feat/ai
devs:fix/ai-followups
devs:test/ai-coverage-unit-only
devs:test/ai-coverage
devs:refactor/scroll-mechanism
devs:fix/verify-per-contact-context
devs:feat/no-db-mode
devs:feat/ai-json
devs:feat/pikaur-parity-arch
devs:fix-pikaur-build
devs:feat/upstream-sync
devs:feat/functest-speedup
devs:fix/cwe-134-format-string-audit
devs:ci/separate-build-step
devs:test/autoping-functional-tests
devs:test/db-functional-tests
devs:fix/arch-build
devs:fix/xep-0030-disco-items-error-handling
devs:fix/xep-0030-empty-disco-items
devs:playground/fix/src_refactoring
devs:tests/disco
devs:fix/test-CI-stability
devs:feat/parallel-tests-clean
devs:feat/parallel-functional-tests
devs:fix/functional_tests_v2
devs:fix/functional_tests
devs:fix/connect_max_args
devs:feat/extended_debug_info
devs:playground/fix/scroll-stuck
devs:build/multicore
devs:build/reenable-fedora
devs:build/autoupdate
No Reviewers
Dismiss Review
Are you sure you want to dismiss this review?
Labels
Clear labels
Compat/Breaking
Breaking change that won't be backward compatible
Kind/Bug
Something is not working
Kind/Documentation
Documentation changes
Kind/Enhancement
Improve existing functionality
Kind/Feature
New functionality
Kind/Security
This is security issue
Kind/Testing
Issue or pull request related to testing
Priority
Critical
1
The priority is critical
Priority
High
2
The priority is high
Priority
Low
4
The priority is low
Priority
Medium
3
The priority is medium
Reviewed
Confirmed
1
Issue has been confirmed
Reviewed
Duplicate
2
This issue or pull request already exists
Reviewed
Invalid
3
Invalid issue
Reviewed
Won't Fix
3
This issue won't be fixed
Status
Abandoned
3
Somebody has started to work on this but abandoned work
Status
Blocked
1
Something is blocking this issue or pull request
Status
Need More Info
2
Feedback is required to reproduce issue or to continue work
No Label
Status
Blocked
1
Milestone
No items
No Milestone
Projects
Clear projects
No project
No Assignees
Notifications
Due Date
No due date set.
Depends on
#87 Add `cons_show_warning()` function
devs/cproof
Reference: devs/cproof#173
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
No description provided.
Delete Branch "fix/e2ee-transport-147"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Implements the four task blocks of #147; the two requirements already satisfied on master are verified and left unchanged.
T04 — security events visible (REQ-LOG-01, REQ-LOG-02, REQ-AUTH-03): SASL auth failure, TLS handshake failure and see-other-host redirects are logged as warnings; the certificate-failure prompt is preceded by a warning with subject and fingerprint;
DISABLE_TLS,TRUST_TLSandLEGACY_AUTHproduce a log warning plus a console notice, so a weakened transport is never silent.T05 — transport policy (REQ-CRY-03, REQ-CFG-01): a session that ends up unencrypted without the user having asked for it triggers a loud warning (an explicit
tls disableis reported at settings time and not repeated); in-band registration is refused on an unencrypted stream, since the account password would otherwise be sent in the clear; a sharedhttp_warn_insecure_transfer()warns on each HTTP transfer performed with certificate verification disabled, covering upload, download and aesgcm transfers.T06 — update check (REQ-VUL-02): the update check is pinned to https with peer/host verification and no redirects, failures are reported; the
sscanfversion parse is replaced with a strict N.N.N parser that rejects signs, trailing garbage and out-of-range components — the fetched version is untrusted network input.T09 — crypto correctness (REQ-CRY-01, REQ-CRY-02, REQ-CRY-07, REQ-MEM-05): a failed MUC OMEMO send no longer writes plaintext to log/history — the message is only recorded when a stanza id was returned; the OTR opportunistic first message is plaintext on the wire and now passes
allow_unencrypted_message()like any other cleartext send;get_random_string()draws from a CSPRNG (gcry_create_nonce, falling back to the OS random device) with rejection sampling to remove modulo bias, and libgcrypt is detected independently of OMEMO; the identity-key length decrement is guarded against unsigned underflow on an empty buffer.Not changed, verified instead: REQ-VUL-03 is already satisfied on master (
PREF_REVEAL_OSdefaults off and the version string is empty sincec5dd0cf9d); REQ-CRY-09 is already correct — trust mode defaults to manual, only blind/firstusage persist trust, both with a visible console notice.Resolve #147
6dd1610e47to214f860d2cGenerally a good update, which requires further polish
@@ -473,1 +476,3 @@curl_easy_perform(handle);curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 1L);curl_easy_setopt(handle, CURLOPT_SSL_VERIFYHOST, 2L);curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 0L);We just overwrite defaults here.
@@ -474,0 +482,4 @@#elsecurl_easy_setopt(handle, CURLOPT_PROTOCOLS, CURLPROTO_HTTPS);curl_easy_setopt(handle, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTPS);#endifCan curl realistically fallback to HTTP? If not, then this code provides no benefit. The string is defined in const variable
urlwhich we do not touch later, so the protocol always remains the same.@@ -484,0 +527,4 @@gint64 value = 0;while (g_ascii_isdigit(*curr)) {value = value * 10 + (*curr - '0');if (value > G_MAXINT) {Can we actually detect this overflow postfactum?
@@ -702,0 +765,4 @@}#endifFILE* urandom = fopen("/dev/urandom", "rb");Why such complicated setup? Earlier setup with
g_rand_new()andg_rand_int_range()utilized/dev/urandomas well. It even had a fallback mechanism.https://gitlab.gnome.org/GNOME/glib/-/blob/main/glib/grand.c#L172
get_random_string()is used only to create stanza ids, download ids, and unique profanity identifier. There is no need for actual strong randomness. But I see the potential of strong random in future applications, such as password generation.@@ -201,3 +201,1 @@groupchat_log_omemo_msg_out(mucwin->roomjid, message);log_database_add_outgoing_muc(id, mucwin->roomjid, message, replace_id, PROF_MSG_ENC_OMEMO);mucwin_outgoing_msg(mucwin, message, id, PROF_MSG_ENC_OMEMO, replace_id);if (id != NULL) { // nothing was sent, so don't persist or echo the plaintextTODO: probably it's a bug with diff, but the only change I see here is adding this condtion. However, for me, the lines below are highlighted as well.
@@ -206,3 +206,3 @@{cons_show_error("Login failed.");log_info("Login failed");log_warning("[SECURITY] Authentication failed for %s", STR_MAYBE_NULL(session_get_account_name()));Do we even need to guard NULL-strings with
STR_MAYBE_NULL? Typically all%sfor us show(null)if they are null.@@ -1434,2 +1434,4 @@unsigned char* identity_public_key_data = signal_buffer_data(identity_public_key);if (identity_public_key_len == 0) {log_error("[OMEMO] cannot fingerprint an empty identity key"); // the decrement below would wrapThe comment is nice, but I feel that it can be placed slightly higher, since inline comment for log message looks less readable.
@@ -331,6 +332,10 @@ otr_on_message_send(ProfChatWin* chatwin, const char* const message, gboolean re// tag and send for policy opportunisticif (policy == PROF_OTRPOLICY_OPPORTUNISTIC) {// the tagged first message is still plaintext on the wireNice catch! I really dislike
message_send_chat_otr, as it's really misleading: unlike othermessage_send_chat_ENCRYPTION_NAMEmethods, the method sends plaintext message and just marks the message as "otr".@@ -54,0 +57,4 @@http_warn_insecure_transfer(ProfWin* window, char* id, const char* const url){log_warning("[SECURITY] TLS certificate verification disabled for transfer: %s", url);http_print_transfer_update(window, id, THEME_ERROR, 0,We need
theme_warning@@ -215,0 +217,4 @@if (flags & XMPP_CONN_FLAG_DISABLE_TLS) {log_warning("[SECURITY] TLS is disabled for this connection: traffic and credentials are sent in the clear");cons_show_error("Security warning: TLS is disabled, this connection is unencrypted.");We need
cons_show_warning@@ -960,0 +985,4 @@// tls.policy=allow negotiates opportunistically, so an unrequested downgrade must not pass silentlyif (!connection_is_secured() && !conn.tls_disabled_by_user) {log_warning("[SECURITY] Logged in over an unencrypted connection to %s: the server offered no usable TLS", conn.domain);cons_show_error("Security warning: this session is NOT encrypted, the server did not provide TLS. Use '/account set <account> tls force' to require it.");Nice actionable warning.
@@ -1126,0 +1157,4 @@g_key_file_set_string(keyfile.keyfile, "identifier", "random_bytes", profanity_instance_id);save_keyfile(&keyfile);} else {log_error("Could not generate an instance identifier: no random source available");Here and below shouldn't happen. We don't need true or strong randomness for simple things like that. Falling back on current time, as GLib does, is perfectly acceptable in these scenarios.
@@ -1091,1 +1091,4 @@assert_false(release_is_new("1.0.0", NULL));// the found version is untrusted network input: nothing but strictly N.N.N may parseassert_false(release_is_new("0.16.0", " 1.0.0")); // leading whitespaceWhat about
...,.,..?Blocked by #87.
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.