Feed aggregator
Telegram Founder Arrest Part of Cybercrime Inquiry, Say Prosecutors
Read more of this story at Slashdot.
A Lot of New In-car Tech is 'Not Necessary,' Survey Finds
Read more of this story at Slashdot.
Australia Grants Workers 'Right To Disconnect' After Hours
Read more of this story at Slashdot.
Amazon and AWS Developers May Not Want To Invite Their CEOs To Java Code Reviews
Read more of this story at Slashdot.
Macron on Telegram CEO's Arrest: French Government Was Not Involved
Read more of this story at Slashdot.
IBM is Latest US Tech Giant To Pull Back From China
Read more of this story at Slashdot.
Telegram Says CEO Durov Has 'Nothing To Hide'
Read more of this story at Slashdot.
Boeing, Lockheed Martin Consider Selling ULA Space Launch Business
Read more of this story at Slashdot.
'Don't Trust Google for Customer Service Numbers. It Might Be a Scam.'
Read more of this story at Slashdot.
CodeSOD: Compile It Yourself
Today's anonymous submitter, who we'll call Sally, works on medical devices. As you can imagine, the development process for such devices is very strict. I mean, it should be, but we know that the industry has problems.
Unfortunately for Sally, one of those problems is the tech lead on a project she is inheriting. Said tech lead is leaving, and Sally is coming on to replace them. The project is in C#, and Sally is the most experience with the language, making her the obvious choice to step in.
Now, the current tech lead had some concerns about the development cycle. You see, the whole process of writing code, compiling code, deploying that code onto hardware, and then running the code just took too darn long. If you wanted to iterate as fast as possible, you needed to skip some of those steps.
internal static Action<InstrumentState> Compile(IEnumerable<Configuration.Rule> rules) { var code = string.Format(@" using System; using SomeCompany.SomeProject.Instrument; using SomeCompany.SomeProject.Instrument.State.Actions; using ConsoleState = StateMachine.Types.State; namespace SomeCompany.SomeProject.Instrument.State.Reducers {{ public class Script {{ private static bool _done; private static void Done() {{ _done = true; }} public static void Execute(InstrumentState state) {{ _done = false; {0} }} {1} }} }} " , string.Join(Environment.NewLine, rules.Select((i, o) => string.Format(@" if (!_done) {{ rule{0}(state); }} ", o))) , string.Join(Environment.NewLine, rules.Select((i, o) => string.Format(@" private static void rule{0}(InstrumentState state) {{ if ({1}) {{ {2} }} }}", o, i.Trigger, string.Join(Environment.NewLine, i.Actions)))) ); var types = new[] { typeof(Console), typeof(InstrumentState), typeof(ErrorEventAction), typeof(ComponentId), typeof(global::StateMachine.Types.State) }; var refs = types.Select(h => MetadataReference.CreateFromFile(h.Assembly.Location) as MetadataReference).ToList(); //some default refeerences refs.Add(MetadataReference.CreateFromFile(Path.Combine(Path.GetDirectoryName(typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly.Location), "System.Runtime.dll"))); refs.Add(MetadataReference.CreateFromFile(typeof(Object).Assembly.Location)); var parse = CSharpSyntaxTree.ParseText(code); var assyName = Guid.NewGuid().ToString(); var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, allowUnsafe: true, optimizationLevel: OptimizationLevel.Release); var compilation = CSharpCompilation.Create(assyName, new List<SyntaxTree> { parse }, refs, options); var state = Expression.Parameter(typeof(InstrumentState), "state"); Action<InstrumentState> y = (_) => { }; using (var stream = new MemoryStream()) { var result = compilation.Emit(stream); if (!result.Success) { var compilationErrors = result.Diagnostics.Where(diagnostic => diagnostic.IsWarningAsError || diagnostic.Severity == DiagnosticSeverity.Error) .ToList(); if (compilationErrors.Any()) { var firstError = compilationErrors.First(); var errorNumber = firstError.Id; var errorDescription = firstError.GetMessage(); var firstErrorMessage = $"{errorNumber}: {errorDescription};"; var exception = new Exception($"Compilation failed, first error is: {firstErrorMessage}"); compilationErrors.ForEach(e => { if (!exception.Data.Contains(e.Id)) exception.Data.Add(e.Id, e.GetMessage()); }); throw exception; } } else { stream.Seek(0, SeekOrigin.Begin); var assy = AssemblyLoadContext.Default.LoadFromStream(stream); var type = assy.GetType("SomeCompany.SomeProject.Instrument.State.Reducers.Script"); y = Expression.Lambda<Action<InstrumentState>>(Expression.Call(type.GetMethod("Execute"), state), state).Compile(); } } return y; }You know when the first line creates a variable code and it holds C# code, you're in for a time.
The first block of code here does a lot. It queries the rules object- a reference to our settings database- to generate a series of rule{0} functions, where the {0} is some name. The body of the function has a condition on i.Trigger (ensuring this rule only applies sometimes) and then has a body defined by i.Actions, which is just C# code living in our data source.
We then populate an Execute function with calls to every rule{0} function we generated. These themselves are further gated by a _done check, meaning it's possible for some rules to abort the processing of further rules.
The rest of the code here is a set of interactions with the C# compiler. We parse and compile the C# code that we just munged together through string concatenation, emit that compiled data into an in-memory stream, and if it succeeds in compilation, we create a C# assembly based off that stream. That is to say, we generate and execute a library without leaving anything on the filesystem for further review. It all exists purely in memory.
We then generate a lambda which calls the Execute function in that newly generate library, and return it, so that other callers can now use it.
There are so many things wrong with this. Setting aside the code generation, the code that gets generated is complicated: a chain of statements where each has its own dedicated trigger condition and may be skipped based on a done flag. Just trying to analyze that for any non-trivial set of rules is hard.
The code generation, however, is the real WTF. First, they were using a set of static analysis tools to try and maximize code safety. None of the code living in the settings database went through that. Second, the settings database was editable by customers. Doctors were expected to edit it. The very idea that you could change the code running on the device by editing the Settings database was a huge "No!" But the bonus of doing this all in memory means that if there were a breach, it'd be trivially easy for an attacker to cover their tracks.
Now, there was no malice on the part of the tech lead. This was all just for personal convenience to speed up iterating on the code. It wasn't an intentional security flaw- it was just clever.
Sally raised this to her boss. He sighed, put his head in his hands, and was silent for a long moment. "We just signed off on doing pen-testing last week. They're going to destroy us."
[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!AI To Go Nuclear? Data Center Deals Say It's Inevitable
Read more of this story at Slashdot.
A Revolutionary Quantum Compass Could Soon Make GPS-Free Navigation a Reality
Read more of this story at Slashdot.
Major Backdoor In Millions of RFID Cards Allows Instant Cloning
Read more of this story at Slashdot.
Hackers Have Found an Entirely New Way To Backdoor Into Microsoft Windows
Read more of this story at Slashdot.
Are OpenAI's ChatGPT Actions Being Abused To Scan For Web Vulnerabilities?
Read more of this story at Slashdot.
US Scientists Identify Cause of Massive Crab Die-Off
Read more of this story at Slashdot.
Sam Bankman-Fried Didn't Have 'Character of a Thief', Argues Author Michael Lewis
Read more of this story at Slashdot.
Can We Fight Climate Change By Bioengineering a Better Cow?
Read more of this story at Slashdot.
ARRL Pays $1 Million Ransom To Decrypt Their Systems After Attack
Read more of this story at Slashdot.
Ford Cancels Electric SUV, Delays EV Pickup
Read more of this story at Slashdot.