Hello everyone,

I decided to get back into some Freenet hacking for a bit. Nobody knows
when I'll disappear again so enjoy it while it lasts ;)

After getting interested in meshnets/darknets again I did some research and
decided that a Freenet like system with forums would be the best bet
against oppressive regimes. I took a look at Freetalk and got it to build
again, but it seems Freetalk is quite dead and WoT progress isn't great
either.

Then I took a look at FMS and I was pleasantly surprised. It works well and
is fast. The only downside seems to be that it is written in C++ and so a
bit harder to include in the main Freenet distribution by default. I think
it would be good for Freenet to have a default and official forum system.
If anything, Freetalk should implement the FMS protocol so it is
inter-operable. No need to reinvent/reprogram the wheel when we have
something that works fine.

After a small discussion on IRC it turned out that a code review would
help. I was quite curious myself how FMS worked so I took a few hours to
browse through the source. I will also post this to the FMS board so please
add some trust to my FMS identity so people can actually see my post:
SSK@cptAO5z0rfUEzlwdyUggtoXdaeQ9XIZzrNBCvBteTDQ
,~-0EZgy~RpU99ThMiyvoiZTpYGgRsY~8GsGJxmZG47U,AQACAAE/

Regards,

Gerard

### Quick code review of the FMS source code by gerard-/gerard_ ###
Downloaded from
CHK@GSJJ7n8
~uBF3dxIqsJVy53g~rJZk8-MlyqN2nGN-Ces,wQIfL5UgA8Uh3ueTvEfIkTMk0dj9-Gcd~5qr97rseXE,AAMC--8/fms-src-0.3.75.zip
$ sha256sum fms-src-0.3.75.zip
1fe5e84aba572143fe95ffb384177e150d5cd4dff2930462b9df24b59c03d85e
 fms-src-0.3.75.zip

What was checked?
* All .cpp files in the directory /src/ and all .h files in the /includes
directory were quickly read through.
* FMS was built from source

What was not checked?
* The /libs directory was not checked. The best way do do this is probably
to find the exact version of the library and diff all files.
* It was NOT checked if the provided binaries correspond with the source
file. To be safe(r) compile from source.

## Summary ##
I spent 4 hours reviewing the FMS code. Disclaimer: I am not familiar with
the FMS code and also not familiar with the Freenet code. I am also not a
professional code auditor.

Verdict: Nice code, could been written a bit more defensively. No
suspicious code was found. The output parts (HTML and Unicode/charset)
should be rewritten to be obviously correct. General architecture seems
well thought out and will be a good foundation for future improvements. The
main improvement would be a reproducible build to verify the binary
corresponds to the source. The licensing situation also needs to be cleared
up.

## Building it ##
Building from source was easy and fast. I could not get the new captcha to
work due to a build error.
After building (with the old captcha, audio captcha enabled)
Filesize 6482312
The produced binary seems to function the same as the one provided in
binary form.

Original (64 bit linux download from Freenet):
Filesize 9773568
Filesize of the original is bigger, which is quite suspicious. This could
be explained by the new captcha or by being built on a different system.

## Code review ##

# general

Bad: FMS does not seem to provide repeatable builds
Bad: Code does not contain assert statements to aid debugging
Bad: FMS does not seem to contain any measures to protect against someone
having access to your own computer. One could argue that those measures
would be ineffective anyways.
Good: The code is of overall high quality
Good: concurrency/threading system is nice, all communication goes through
sqlite
Bad: Most files don't have licensing information, the licensing situation
needs to be investigated for every file

# /src

Good: Code uses modern C++ with STL
Good: Code uses iterators
Good: code uses std::string for string manipulation

Bad: void TranslationPropertyFile::parseLine(std::istream& istr) contains
manual parsing code with loops, this is usually error-prone

Good: code uses prepared statements everywhere
Bad: stringfunctions.cpp is scary, please use a library for string
manipulation. Also looks like some premature optimization has taken place.

Bad: QuoterItemText::GetSanitizedText doesn't operate using a white-list.
There are no comments to see what this function is supposed to do and if it
is correct.
Bad: all functions need a comment next to the implementation that shows
what the function is supposed to do. This makes code reviews and
implementation changes easier and safer

Bad: Option::GetBool(const std::string &option, bool &value) should fail
when it receives an unexpected value instead of considering it "false"
Bad: hardcoded option strings like "UniqueBoardMessageIDs"
Bad: message.cpp:703 - just replacing every instance of \r\n with "" may
have unexpected results
Bad: message.cpp:935 - the code "strips" certain things, a more robust
method would be to parse it and only process it when parsing is successful
- this problem occurs on other places in this file

Main risks:
There is a lot of text parsing going on. If this goes wrong an attacker
could inject javascript into the web interface of possible fake messages.
Any text that is processed should be fully parsed and understood before it
is modified.

Bad: IPAddressACL::Add(const std::string &aclentry) has a weird
m_allowbydefault member, and any element that is added that does not start
with a plus or a minus will be recorded according to that. Consider always
requiring a + or - to remove any ambiguity. This function should be a bit
more strict overall.

Bad: IPAddressACL::MaskAddress just passes through an invalid address (less
than 3 dots)

Bad: hex.cpp doesn't warn then the number of half bytes is uneven

Bad: why does fmsapp.cpp contain a testregex function? Unused or test code
should not be present in the real codebase.

Bad: the database doesn't seem to use foreign keys, data may become
inconsistent leading to crashes and other bugs
Good: there are some range checks in the database

Bad: home-grown Base64 conversion in base64.cpp

## /src/db

Bad: Transaction::Begin uses string operations to build a query. The code
is correct but it would be better to just split up the m_db->Execute call
and move it inside the switch.

Bad: Statement::ResultBool does not warn when the result is unexpected

Bad: DB::HandleError throws an exception but the rest of the code does not
seem to use exceptions

# http/pages

Bad: All pages build html and call SanitizeOutput themselves. Consider
using a library that will build the HTML tags and that will take care of
sanitizing. Functions XMLCreateTextElement and XMLCreateCDATAElement might
be useful.

Bad: ShowInsertedMessagePage::GenerateContent manually builds an SQL query
instead of using a prepared statement variables

Bad: Pages use HTTP GET for trust-list updates

Bad: ForumTemplateMainPage::GenerateContent uses magic strings, replace
those with consts or with defines

# nntp/mime

Bad: Code with quite a bit of pointer arithmetic, from 2000. I think it is
some sort of a library but it should be replaced with something more
modern. A very thorough code review would be needed otherwise.

Bad: uwildmat.cpp contains complicated code that will have to be reviewed
in depth

# unicode

Bad: unicodestring.cpp: the code has empty catch blocks, the string
probably needs to be invalidated when an exception occurs

Bad: what is FMS doing with all this unicode conversion code?
Recommendation: standardize anything on UTF-8 and have the
browser/newsreader handle the display.

# /src/freenet

Bad: All XML parsing code has an empty catch block
Bad: introductionpuzzleinserter.cpp:180 - the code checks for failure,
should check for success
Bad: identityintroductioninserter.cpp:70 - the code checks for failure,
should check for success
_______________________________________________
Devl mailing list
Devl@freenetproject.org
https://emu.freenetproject.org/cgi-bin/mailman/listinfo/devl

Reply via email to