<blockquote>
  <p>According to my understanding the receiving node will first check the signature of related the dsha256 of the entire message before verifying the timestamp and not check the remainder of the message if the signature is invalid. So if other fields apart from signature are changed, then the signature will not be valid (as the message has changed) and the node will not process the message further.</p>
</blockquote>

<p>This is the correct understanding. It is stated earlier on in the receiving rules. Although the client implementation must read at least the <code>chain_hash</code> and <code>short_channel_id</code> from the message in order to retrieve the public key associated with that channel from its storage (if it exists), in order to perform the signature check.</p>

<blockquote>
  <blockquote>
    <p>if signature is not a valid signature, using node_id of the double-SHA256 of the entire message following the signature field (including unknown fields following fee_proportional_millionths):</p>
    
    <ul>
    <li><p><strong>MUST NOT process the message further.</strong></p></li>
    <li><p>SHOULD fail the connection.</p></li>
    </ul>
  </blockquote>
</blockquote>

<p>The checks on the timestamp and other field are performed <strong>only if the signature is valid</strong>, and the purpose of the check is to prevent spam from a valid signer. It is assumed that more than one <code>channel_update</code> in the same second is a DoS attempt, and therefore, the node responsible for signing such messages ought to be blacklisted.</p>

CC BY-SA 4.0
2019-06-13T14:00:54.870Z
That's what is confusing me. It is said in the documentation that if: (1) time stamp is unchanged; (2) signature is unchanged; (3) but other fields are changed as compared to prior `channel_update` message then, blacklist the `node_id`. However, if other fields are changed, then the signature can no longer be valid, so the node should not parse the message further and hence will not detect that the what has been changed and what is not. So there is no way the node can be blacklisted.
Ugam Kamat
CC BY-SA 4.0
2019-06-13T14:02:05.603Z
So either that rule in the BOLT #7 is redundant as the node would never reach to validating that rule if signature is invalid otherwise it might lead to DoS attacks as I mentioned
Ugam Kamat
CC BY-SA 4.0
2019-06-13T14:37:52.490Z
The rule is saying that you should not accept multiple `channel_update` with the same timestamp but different information (particularly the fields below `timestamp` in the message definition). It is possible to have the same information, same timestamp, but different signature, and the signatures all be valid, because the signature is generated using some random number `k`. The signer could sign the same details but using a different random number, and this should not result in blacklisting.
Mark H
CC BY-SA 4.0
2019-06-13T15:32:35.823Z
I see what you are trying to say and its fair. But that stage of checking will never reach as signature validation is done first, so why have it?
Ugam Kamat
CC BY-SA 4.0
2019-06-13T15:38:30.313Z
Stated above. If a valid signer signs multiple `channel_update` per second, with different information, then signature validation will pass, but the messages will be classed as spam and the signer will be blacklisted.
Mark H
CC BY-SA 4.0
2019-06-13T15:58:33.977Z
Yes, but if that guys is signing the `channel_update` message with a valid signature then it will be DIFFERENT for every message he sends if he changes the data. So, changing the data cannot have the SAME signature as it is invalid. The condition says, the signature should be same as previous and data should be different. This is not possible without invalidating the signature
Ugam Kamat
CC BY-SA 4.0
2019-06-13T16:18:31.603Z
That is not what it says. The check for the timestamp and equivalent data will not even occur if the signature is invalid. These checks are conditional on the signature being valid. An invalid signature will result in ignoring the message and disconnecting from the peer who sent it.
Mark H
CC BY-SA 4.0
2019-06-13T16:20:59.660Z
Let us [continue this discussion in chat](https://chat.stackexchange.com/rooms/94871/discussion-between-ugam-kamat-and-mark-h).
Ugam Kamat
CC BY-SA 4.0
2019-06-13T13:06:15.283Z
2019-06-13T13:11:19.943Z
2019-06-13T13:11:19.943Z
Mark H
<p>if you look at the format of the <code>channel_update</code> message you will realize there is no field <code>node_id</code> in the message. c.f.: </p>

<pre><code>type: 258 (channel_update)
data:
[64:signature]
[32:chain_hash]
[8:short_channel_id]
[4:timestamp]
[1:message_flags]
[1:channel_flags]
[2:cltv_expiry_delta]
[8:htlc_minimum_msat]
[4:fee_base_msat]
[4:fee_proportional_millionths]
[8:htlc_maximum_msat] (option_channel_htlc_max)
</code></pre>

<p>Thus the way I read the rfc is that the peer might decide to blacklist the <code>node_id</code> of their peer (the one who propagates the forged / wrongful <code>channel_update</code> message) In this way one would not create a DoS attack to some random <code>node_id</code> (the victim) but for oneself which is exactly how it i should work. </p>

CC BY-SA 4.0
2019-06-13T11:44:45.870Z
I think the `channel_update` message works by cross-checking it with `channel_announcement` message in the `short_channel_id` field. Because there is a requirement to discard the `channel_update` message that does not match the `short-channel_id` of the previously received `channel_announcement` message. It is also said that: "The `node_id` for the signature verification is taken from the corresponding `channel_announcement`: node_id_1 if the least-significant bit of flags is 0 or node_id_2 otherwise."
Ugam Kamat
CC BY-SA 4.0
2019-06-13T11:45:28.043Z
So I think in that sense, the `node_id` refers to the one that signs the message rather than the one that broadcasts it
Ugam Kamat
CC BY-SA 4.0
2019-06-13T11:47:01.117Z
ouch. that seems right. If I find the time I will look this up in the code base because then we have certainty how it is meant / understood.
Rene Pickhardt
CC BY-SA 4.0
2019-06-13T11:48:18.843Z
Thanks Rene! I'm still working my way through the BOLTs! will go through the code after that
Ugam Kamat
CC BY-SA 4.0
2019-06-13T11:33:30.220Z
2019-06-13T11:33:30.220Z
Rene Pickhardt
<p>Following requirements have been placed on the receiving nodes related to the <code>channel_update</code> message in <a href="https://github.com/lightningnetwork/lightning-rfc/blob/master/07-routing-gossip.md#requirements-3" rel="nofollow noreferrer">BOLT #7</a>.</p>

<blockquote>
  <ul>
  <li>if timestamp is NOT greater than that of the last-received <code>channel_update</code> for this <code>short_channel_id</code> AND for <code>node_id</code>:
  
  <ul>
  <li>SHOULD ignore the message.</li>
  </ul></li>
  <li>otherwise:
  
  <ul>
  <li>if the timestamp is equal to the last-received <code>channel_update</code> AND the fields (other than signature) differ:
  
  <ul>
  <li>MAY blacklist this <code>node_id</code>.</li>
  <li>MAY forget all channels associated with it.</li>
  </ul></li>
  </ul></li>
  </ul>
</blockquote>

<p>According to my understanding the receiving node will first check the signature of related the <code>dsha256</code> of the entire message before verifying the timestamp and not check the remainder of the message if the signature is invalid. So if <strong>other fields apart from signature</strong> are changed, then the signature will not be valid (as the message has changed) and the node will not process the message further.</p>

<p>Now here's the thing I'm wrestling with: If the node still plans to check the message (as shown in the quoted text above) even though the signature is invalid and then go forward to blacklist the node, it can give rise to DoS attacks. A malicious nodes will just take a <code>channel_update</code> message that it received in the past from a node, change some fields like <code>htlc_minimum_msat</code> and rebroadcast to other nodes. Those receiving nodes will then simply blacklist the <code>node_id</code> without any wrongdoing from its part as (1) the timestamp is equal to the one it received in the past, (2) signature is same AND (3) other fields have changed. </p>

<p>So I feel that this check is simply not needed and if the software goes on to process this message despite checking the signature then it can give rise to attacks from malicious parties. Where am I incorrect in my thought process?</p>

<lightning-network><lightning-rfc>
BOLT #7: Can receiving node requirements in channel_update message give rise to malicious attacks?
Ugam Kamat
# BOLT #7: Can receiving node requirements in channel_update message give rise to malicious attacks?

(Asked by: username_0 on 2019-06-13)

Following requirements have been placed on the receiving nodes related to the `channel_update` message in [BOLT #7](https://github.com/lightningnetwork/lightning-rfc/blob/master/07-routing-gossip.md#requirements-3).

> * if timestamp is NOT greater than that of the last-received `channel_update` for this `short_channel_id` AND for `node_id`:
>   + SHOULD ignore the message.
> * otherwise:
>   + if the timestamp is equal to the last-received `channel_update` AND the fields (other than signature) differ:
>     - MAY blacklist this `node_id`.
>     - MAY forget all channels associated with it.

According to my understanding the receiving node will first check the signature of related the `dsha256` of the entire message before verifying the timestamp and not check the remainder of the message if the signature is invalid. So if **other fields apart from signature** are changed, then the signature will not be valid (as the message has changed) and the node will not process the message further.

Now here's the thing I'm wrestling with: If the node still plans to check the message (as shown in the quoted text above) even though the signature is invalid and then go forward to blacklist the node, it can give rise to DoS attacks. A malicious nodes will just take a `channel_update` message that it received in the past from a node, change some fields like `htlc_minimum_msat` and rebroadcast to other nodes. Those receiving nodes will then simply blacklist the `node_id` without any wrongdoing from its part as (1) the timestamp is equal to the one it received in the past, (2) signature is same AND (3) other fields have changed.

So I feel that this check is simply not needed and if the software goes on to process this message despite checking the signature then it can give rise to attacks from malicious parties. Where am I incorrect in my thought process?

**Tags:** lightning-network, lightning-rfc


---

## 2 answers

### Answer by username_1 on 2019-06-13. Score: 1 | Accepted answer

> According to my understanding the receiving node will first check the signature of related the dsha256 of the entire message before verifying the timestamp and not check the remainder of the message if the signature is invalid. So if other fields apart from signature are changed, then the signature will not be valid (as the message has changed) and the node will not process the message further.

This is the correct understanding. It is stated earlier on in the receiving rules. Although the client implementation must read at least the `chain_hash` and `short_channel_id` from the message in order to retrieve the public key associated with that channel from its storage (if it exists), in order to perform the signature check.

> > if signature is not a valid signature, using node\_id of the double-SHA256 of the entire message following the signature field (including unknown fields following fee\_proportional\_millionths):
> >
> > * **MUST NOT process the message further.**
> > * SHOULD fail the connection.

The checks on the timestamp and other field are performed **only if the signature is valid**, and the purpose of the check is to prevent spam from a valid signer. It is assumed that more than one `channel_update` in the same second is a DoS attempt, and therefore, the node responsible for signing such messages ought to be blacklisted.

> **Comments:**
> **username_0**: That's what is confusing me. It is said in the documentation that if: (1) time stamp is unchanged; (2) signature is unchanged; (3) but other fields are changed as compared to prior `channel_update` message then, blacklist the `node_id`. However, if other fields are changed, then the signature can no longer be valid, so the node should not parse the message further and hence will not detect that the what has been changed and what is not. So there is no way the node can be blacklisted.  
> **username_0**: So either that rule in the BOLT #7 is redundant as the node would never reach to validating that rule if signature is invalid otherwise it might lead to DoS attacks as I mentioned  
> **username_1**: The rule is saying that you should not accept multiple `channel_update` with the same timestamp but different information (particularly the fields below `timestamp` in the message definition). It is possible to have the same information, same timestamp, but different signature, and the signatures all be valid, because the signature is generated using some random number `k`. The signer could sign the same details but using a different random number, and this should not result in blacklisting.  
> **username_0**: I see what you are trying to say and its fair. But that stage of checking will never reach as signature validation is done first, so why have it?  
> **username_1**: Stated above. If a valid signer signs multiple `channel_update` per second, with different information, then signature validation will pass, but the messages will be classed as spam and the signer will be blacklisted.  
> **username_0**: Yes, but if that guys is signing the `channel_update` message with a valid signature then it will be DIFFERENT for every message he sends if he changes the data. So, changing the data cannot have the SAME signature as it is invalid. The condition says, the signature should be same as previous and data should be different. This is not possible without invalidating the signature  
> **username_1**: That is not what it says. The check for the timestamp and equivalent data will not even occur if the signature is invalid. These checks are conditional on the signature being valid. An invalid signature will result in ignoring the message and disconnecting from the peer who sent it.  
> **username_0**: Let us [continue this discussion in chat](https://chat.stackexchange.com/rooms/94871/discussion-between-username_0-and-username_1).  

---

### Answer by username_2 on 2019-06-13. Score: 0

if you look at the format of the `channel_update` message you will realize there is no field `node_id` in the message. c.f.:

```
type: 258 (channel_update)
data:
[64:signature]
[32:chain_hash]
[8:short_channel_id]
[4:timestamp]
[1:message_flags]
[1:channel_flags]
[2:cltv_expiry_delta]
[8:htlc_minimum_msat]
[4:fee_base_msat]
[4:fee_proportional_millionths]
[8:htlc_maximum_msat] (option_channel_htlc_max)

```

Thus the way I read the rfc is that the peer might decide to blacklist the `node_id` of their peer (the one who propagates the forged / wrongful `channel_update` message) In this way one would not create a DoS attack to some random `node_id` (the victim) but for oneself which is exactly how it i should work.

> **Comments:**
> **username_0**: I think the `channel_update` message works by cross-checking it with `channel_announcement` message in the `short_channel_id` field. Because there is a requirement to discard the `channel_update` message that does not match the `short-channel_id` of the previously received `channel_announcement` message. It is also said that: "The `node_id` for the signature verification is taken from the corresponding `channel_announcement`: node_id_1 if the least-significant bit of flags is 0 or node_id_2 otherwise."  
> **username_0**: So I think in that sense, the `node_id` refers to the one that signs the message rather than the one that broadcasts it  
> **username_2**: ouch. that seems right. If I find the time I will look this up in the code base because then we have certainty how it is meant / understood.  
> **username_0**: Thanks username_2! I'm still working my way through the BOLTs! will go through the code after that  

---

