<p>It <em>was</em> possible (see the infamous &quot;<a href="https://bitcoin.stackexchange.com/q/38037/101498"><code>1 RETURN</code> bug</a>&quot;) because the <code>RETURN</code> operand used to stop the execution of the Script. So simply pushing <code>1</code> in the scriptSig and <code>RETURN</code>ing would make the execution of the catenated <code>scriptSig || scriptPubKey</code> successful no matter the content of the scriptPubKey.</p>
<p>Separating both certainly makes it easier to reason about and therefore be certain it's safe from this failure mode.</p>
<hr />
<p>I initially posted this answer with an assertion that once the <code>RETURN</code> operand was fixed it was unclear how you would bypass the scriptPubKey. I didn't think hard enough! Actually you could simply include a <code>PUSHDATA</code>, which would interpret the scriptPubKey as a <a href="https://github.com/bitcoin/bitcoin/blob/6ce5e8f4758e6fccf59b3980af417ec6c75e383e/src/script/interpreter.cpp#L477-L481" rel="noreferrer">data array pushed on the stack</a>, which would then make the execution successful since it <a href="https://github.com/bitcoin/bitcoin/blob/6ce5e8f4758e6fccf59b3980af417ec6c75e383e/src/script/interpreter.cpp#L1824" rel="noreferrer">would be casted to <code>true</code></a> <a href="https://github.com/bitcoin/bitcoin/blob/6ce5e8f4758e6fccf59b3980af417ec6c75e383e/src/script/interpreter.cpp#L35-L48" rel="noreferrer">as long as it's not all <code>0x00</code></a>s.</p>
<p>So it's true that catenating the scriptSig and the scriptPubKey is always unsafe.</p>

CC BY-SA 4.0
2023-08-17T15:42:04.810Z
Thanks! I was under the impression that `RETURN` always implied the execution failed, since it is typically used to burn BTC. Is that what you meant by "fixing the `RETURN` operand"?
Cosmik Debris
CC BY-SA 4.0
2023-08-17T16:02:19.857Z
@CosmikDebris Currently it is the case that `OP_RETURN` immediately marks the transaction invalid, but the the bug under discussion is exactly that its semantics used to  simply be "stop execution" (which only resulted in failure if there was a false on top of the stack at that point). The practice of using `OP_RETURN` for burning funds came only years after this bug was fixed.
Pieter Wuille
CC BY-SA 4.0
2023-08-17T15:13:59.593Z
2023-08-17T15:28:41.247Z
2023-08-17T15:28:41.247Z
Antoine Poinsot
<p>Around the 5:00 timestamp in <a href="https://www.youtube.com/watch?v=np-SCwkqVy4" rel="nofollow noreferrer">this talk</a>, John Newbery states that running the concatenation of scriptPubKey and scriptSig is unsafe, since it can result in someone using a carefully crafted scriptSig in order to spend <em>any</em> output.</p>
<p>What would such a scriptSig look like?</p>

<security><script><input-script><output-script>
Why is concatenating scriptPubKeys and scriptSigs unsafe?
Cosmik Debris
# Why is concatenating scriptPubKeys and scriptSigs unsafe?

(Asked by: username_0 on 2023-08-17)

Around the 5:00 timestamp in [this talk](https://www.youtube.com/watch?v=np-SCwkqVy4), John Newbery states that running the concatenation of scriptPubKey and scriptSig is unsafe, since it can result in someone using a carefully crafted scriptSig in order to spend *any* output.

What would such a scriptSig look like?

**Tags:** security, script, input-script, output-script


---

## 1 answers

### Answer by username_1 on 2023-08-17. Score: 6 | Accepted answer

It *was* possible (see the infamous "[`1 RETURN` bug](https://bitcoin.stackexchange.com/q/38037/101498)") because the `RETURN` operand used to stop the execution of the Script. So simply pushing `1` in the scriptSig and `RETURN`ing would make the execution of the catenated `scriptSig || scriptPubKey` successful no matter the content of the scriptPubKey.

Separating both certainly makes it easier to reason about and therefore be certain it's safe from this failure mode.

---

I initially posted this answer with an assertion that once the `RETURN` operand was fixed it was unclear how you would bypass the scriptPubKey. I didn't think hard enough! Actually you could simply include a `PUSHDATA`, which would interpret the scriptPubKey as a [data array pushed on the stack](https://github.com/bitcoin/bitcoin/blob/6ce5e8f4758e6fccf59b3980af417ec6c75e383e/src/script/interpreter.cpp#L477-L481), which would then make the execution successful since it [would be casted to `true`](https://github.com/bitcoin/bitcoin/blob/6ce5e8f4758e6fccf59b3980af417ec6c75e383e/src/script/interpreter.cpp#L1824) [as long as it's not all `0x00`](https://github.com/bitcoin/bitcoin/blob/6ce5e8f4758e6fccf59b3980af417ec6c75e383e/src/script/interpreter.cpp#L35-L48)s.

So it's true that catenating the scriptSig and the scriptPubKey is always unsafe.

> **Comments:**
> **username_0**: Thanks! I was under the impression that `RETURN` always implied the execution failed, since it is typically used to burn BTC. Is that what you meant by "fixing the `RETURN` operand"?  
> **username_2**: @username_0 Currently it is the case that `OP_RETURN` immediately marks the transaction invalid, but the the bug under discussion is exactly that its semantics used to  simply be "stop execution" (which only resulted in failure if there was a false on top of the stack at that point). The practice of using `OP_RETURN` for burning funds came only years after this bug was fixed.  

---

