Professional Documents
Culture Documents
60
51.503 - Secure Software Engineering
7. Model Checking
LTL (Linear Temporal Logic) model checking is a formal verification technique used
to ensure that a system meets a given specification expressed in LTL formula. In
LTL, a formula is made up of temporal operators that allow for the expression of
properties that hold over time. In LTL model checking, the function under verification
is modelled as a transition function consisting of a set of states and transitions
between them. The LTL formula is then expressed as a set of properties that must
hold for the function in all possible executions.
The model checker verifies the function against the LTL formula by exhaustively
exploring all possible states and transitions. The model checker checks if the system
satisfies the LTL formula by evaluating it against each possible execution of the
system. If the model checker exhaustively explores all possible executions and the
LTL formula holds for all of them, the system is considered to be verified.
def updateItem(request):
data = json.loads(request.body)
productId = data['productId']
action = data['action']
print('Action:', action)
print('Product:', productId)
customer = request.user.customer
product = Product.objects.get(id=productId)
order, created = Order.objects.get_or_create(customer=customer,
complete=False)
if action == 'add':
orderItem.quantity = (orderItem.quantity + 1)
elif action == 'remove':
orderItem.quantity = (orderItem.quantity - 1)
orderItem.save()
if orderItem.quantity <= 0:
orderItem.delete()
61
51.503 - Secure Software Engineering
init {
run t();
}
The code defines a simple function that has two types of messages - ADD and
REMOVE. It consists of a single process named "t" that executes an infinite loop and
waits for these messages. When it receives an ADD message, it increments the
quantity variable and prints a message that shows the new quantity. Similarly, when
it receives a REMOVE message, it decrements the quantity variable and prints a
62
51.503 - Secure Software Engineering
message showing the new quantity. The ADD and REMOVE statements are atomic,
meaning they cannot be interrupted by other processes. If the value of quantity
becomes negative after decrementing, it is reset to 0. This is similar to the function
updateItem()
The system has three LTL properties that check whether the conditions are satisfied.
1) p1 { [] (run_done -> quantity >= 0) }: Checks that when process "t" has
completed executing (i.e., run_done is true), the quantity variable is always
greater than or equal to 0. This property ensures that the system always
terminates with a non-negative quantity value.
2) p2 { [] ((quantity <= 0) -> ([] (quantity == 0))) }: Checks that if the quantity
variable ever becomes less than or equal to 0, it will eventually become 0.
This property ensures that the system eventually reaches a state where the
quantity is 0, in case the quantity goes negative due to an unexpected event.
3) p3 { [] ((quantity > 0) -> ([] (quantity >= 0))) }: Checks that if the quantity
variable ever becomes greater than 0, it will always remain greater than or
equal to 0. This property ensures that the system never allows the quantity
variable to become negative.
To check the properties, we used the Spin model checker. The model was saved as
proj.pml and we executed the Spin model checker on the model i.e. “spin -a
proj.xml”. This would result in the generation of “pan.c” where we compiled it using
the command “gcc -o proj pan.c” which would create an executable named “proj”, as
shown in Figure 7.2.
63
51.503 - Secure Software Engineering
- ./proj -a -N p3
For each LTL formula, a full state space search to check if the formula is satisfied or
violated by the function described in the Promela code was performed. The output
includes various statistics about the search process, such as the number of states
explored and the amount of memory used.
In all three cases, as shown in Figure 7.2 to 7.4 below, SPIN did not find any errors,
which is indicated by the "errors: 0" line in each section. However, there are some
states in the system that are marked as "unreached", which means that they cannot
be reached during the execution of the system. These states are listed under the
"unreached in" sections. Overall, the output indicates that the Promela code satisfied
all three LTL formulas and does not have any errors.
64
51.503 - Secure Software Engineering
65
51.503 - Secure Software Engineering
66
51.503 - Secure Software Engineering
67
51.503 - Secure Software Engineering
Through the project, we observed the heavy reliance on third-party libraries and
framework i.e. Django in the eCommence application. This may potentially result in
software supply chain issues which are becoming increasingly common. When
developers use third-party code, they are introducing unknown code into their own
applications, which can be a security risk. Dependencies can have vulnerabilities,
backdoors, or other flaws that can be exploited by attackers to gain access to
sensitive information or systems. If a dependency is compromised, it can put the
entire software supply chain at risk.
68
51.503 - Secure Software Engineering
69
51.503 - Secure Software Engineering
9. References
Django Software Foundation. (n.d.). Django. Django Project. Retrieved April
1, 2023, from https://docs.djangoproject.com/en/4.2/
SonarSource. (2023). Python static code analysis: Unique rules to find Bugs,
Vulnerabilities, Security Hotspots, and Code Smells in your PYTHON
code. SonarSource Rules. Retrieved April 1, 2023, from
https://rules.sonarsource.com/python
70